From 8bf356c67dd3db3a5d1dea7624ae62d23e4b2a54 Mon Sep 17 00:00:00 2001 From: Adrian Chiris Date: Wed, 18 Dec 2013 12:01:09 +0200 Subject: [PATCH] MFT-3.5.0 ported to mstflint --- Makefile.am | 2 +- cmdparser/Makefile.am | 42 + cmdparser/cmdparser.cpp | 483 ++ cmdparser/cmdparser.h | 151 + cmdparser/my_getopt.c | 1083 +++++ cmdparser/my_getopt.h | 122 + common/tools_version.h | 5 + configure.ac | 10 +- dev_mgt/tools_dev_types.c | 2 +- flint/Makefile.am | 54 + flint/cmd_line_parser.cpp | 961 ++++ flint/err_msgs.h | 137 + flint/flint.cpp | 251 ++ flint/flint.h | 80 + flint/flint_params.cpp | 83 + flint/flint_params.h | 132 + flint/subcommands.cpp | 3717 ++++++++++++++++ flint/subcommands.h | 497 +++ mflash/Makefile.am | 18 +- mflash/internal_packets.c | 392 ++ mflash/internal_packets.h | 76 + mflash/internal_packets_types.h | 177 + mflash/mflash.c | 583 +-- mflash/mflash.h | 10 +- mflash/mflash_access_layer.c | 180 + mflash/mflash_access_layer.h | 93 + mflash/mflash_common.c | 138 + mflash/mflash_common.h | 182 + mflash/mflash_inband.c | 154 + mflash/mflash_inband.h | 42 + mflash/packets_common.c | 133 + mflash/packets_common.h | 192 + mlxfwops/Makefile.am | 36 + mlxfwops/lib/Makefile.am | 62 + mlxfwops/lib/flint_base.cpp | 281 ++ mlxfwops/lib/flint_base.h | 685 +++ mlxfwops/lib/flint_io.cpp | 796 ++++ mlxfwops/lib/flint_io.h | 325 ++ mlxfwops/lib/fs2_ops.cpp | 1951 ++++++++ mlxfwops/lib/fs2_ops.h | 155 + mlxfwops/lib/fs3_ops.cpp | 1376 ++++++ mlxfwops/lib/fs3_ops.h | 175 + mlxfwops/lib/fw_ops.cpp | 1367 ++++++ mlxfwops/lib/fw_ops.h | 347 ++ mlxfwops/lib/mlxconfig.cpp | 1826 ++++++++ mlxfwops/lib/mlxconfig.h | 185 + mlxfwops/lib/mlxconfig_empty.h | 53 + mlxfwops/lib/mlxfwops.cpp | 141 + mlxfwops/lib/mlxfwops.h | 79 + mlxfwops/lib/mlxfwops_com.h | 209 + mstdump/crd_lib/Makefile.am | 17 +- mstdump/crd_lib/crdump.c | 808 ++-- mstdump/crd_lib/crdump.h | 39 +- mstdump/crd_main/Makefile.am | 12 +- mstdump/crd_main/mstdump.c | 81 +- mstdump/mstdump_dbs/ConnectIB.csv | 899 ++-- mstdump/mstdump_dbs/ConnectX2.csv | 2089 ++++----- mstdump/mstdump_dbs/ConnectX3.csv | 451 +- mstdump/mstdump_dbs/ConnectX3Pro.csv | 600 +-- mstdump/mstdump_dbs/InfiniHost.csv | 494 --- mstdump/mstdump_dbs/InfiniHostIIIEx_MF.csv | 570 --- mstdump/mstdump_dbs/InfiniHostIIILx.csv | 332 -- mstdump/mstdump_dbs/InfiniScaleIII.csv | 844 ---- mstdump/mstdump_dbs/Makefile.am | 6 +- mstdump/mstdump_dbs/SwitchX.csv | 4642 +++++++++++--------- small_utils/Makefile.am | 10 +- small_utils/mcra.c | 357 +- tools_layouts/Makefile.am | 47 + tools_layouts/adb_to_c_utils.c | 273 ++ tools_layouts/adb_to_c_utils.h | 264 ++ tools_layouts/cibfw_layouts.c | 979 +++++ tools_layouts/cibfw_layouts.h | 467 ++ 72 files changed, 27494 insertions(+), 7018 deletions(-) create mode 100644 cmdparser/Makefile.am create mode 100644 cmdparser/cmdparser.cpp create mode 100644 cmdparser/cmdparser.h create mode 100755 cmdparser/my_getopt.c create mode 100755 cmdparser/my_getopt.h create mode 100755 flint/Makefile.am create mode 100644 flint/cmd_line_parser.cpp create mode 100644 flint/err_msgs.h create mode 100644 flint/flint.cpp create mode 100644 flint/flint.h create mode 100644 flint/flint_params.cpp create mode 100644 flint/flint_params.h create mode 100644 flint/subcommands.cpp create mode 100644 flint/subcommands.h create mode 100755 mflash/internal_packets.c create mode 100755 mflash/internal_packets.h create mode 100755 mflash/internal_packets_types.h create mode 100755 mflash/mflash_access_layer.c create mode 100755 mflash/mflash_access_layer.h create mode 100755 mflash/mflash_common.c create mode 100755 mflash/mflash_common.h create mode 100755 mflash/mflash_inband.c create mode 100755 mflash/mflash_inband.h create mode 100755 mflash/packets_common.c create mode 100755 mflash/packets_common.h create mode 100755 mlxfwops/Makefile.am create mode 100755 mlxfwops/lib/Makefile.am create mode 100755 mlxfwops/lib/flint_base.cpp create mode 100755 mlxfwops/lib/flint_base.h create mode 100755 mlxfwops/lib/flint_io.cpp create mode 100755 mlxfwops/lib/flint_io.h create mode 100644 mlxfwops/lib/fs2_ops.cpp create mode 100644 mlxfwops/lib/fs2_ops.h create mode 100644 mlxfwops/lib/fs3_ops.cpp create mode 100644 mlxfwops/lib/fs3_ops.h create mode 100644 mlxfwops/lib/fw_ops.cpp create mode 100644 mlxfwops/lib/fw_ops.h create mode 100644 mlxfwops/lib/mlxconfig.cpp create mode 100755 mlxfwops/lib/mlxconfig.h create mode 100755 mlxfwops/lib/mlxconfig_empty.h create mode 100755 mlxfwops/lib/mlxfwops.cpp create mode 100755 mlxfwops/lib/mlxfwops.h create mode 100644 mlxfwops/lib/mlxfwops_com.h delete mode 100755 mstdump/mstdump_dbs/InfiniHost.csv delete mode 100755 mstdump/mstdump_dbs/InfiniHostIIIEx_MF.csv delete mode 100755 mstdump/mstdump_dbs/InfiniHostIIILx.csv delete mode 100755 mstdump/mstdump_dbs/InfiniScaleIII.csv create mode 100644 tools_layouts/Makefile.am create mode 100644 tools_layouts/adb_to_c_utils.c create mode 100644 tools_layouts/adb_to_c_utils.h create mode 100644 tools_layouts/cibfw_layouts.c create mode 100644 tools_layouts/cibfw_layouts.h diff --git a/Makefile.am b/Makefile.am index 93ab8e8..6da9579 100644 --- a/Makefile.am +++ b/Makefile.am @@ -30,7 +30,7 @@ # SOFTWARE. #-- -SUBDIRS = mtcr_ul dev_mgt mflash flint small_utils mstdump +SUBDIRS = mtcr_ul dev_mgt mflash tools_layouts mlxfwops cmdparser flint small_utils mstdump EXTRA_DIST = \ mstflint.spec \ diff --git a/cmdparser/Makefile.am b/cmdparser/Makefile.am new file mode 100644 index 0000000..cd0ea98 --- /dev/null +++ b/cmdparser/Makefile.am @@ -0,0 +1,42 @@ +#-- +# Copyright (c) 2004-2010 Mellanox Technologies LTD. All rights reserved. +# +# This software is available to you under a choice of one of two +# licenses. You may choose to be licensed under the terms of the GNU +# General Public License (GPL) Version 2, available from the file +# COPYING in the main directory of this source tree, or the +# OpenIB.org BSD license below: +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the following +# conditions are met: +# +# - Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# - Redistributions 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. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +#-- + +# Makefile.am -- Process this file with automake to produce Makefile.in + +INCLUDES = + +AM_CPPFLAGS = -W -g -MP -MD -fPIC + +lib_LTLIBRARIES = libcmdparser.la + +libcmdparser_la_SOURCES = cmdparser.cpp my_getopt.c cmdparser.h my_getopt.h + diff --git a/cmdparser/cmdparser.cpp b/cmdparser/cmdparser.cpp new file mode 100644 index 0000000..d58c3b3 --- /dev/null +++ b/cmdparser/cmdparser.cpp @@ -0,0 +1,483 @@ +/* + * Copyright (c) 2004-2010 Mellanox Technologies LTD. All rights reserved. + * + * This software is available to you under the terms of the + * OpenIB.org BSD license included below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + + +#include +#include +#include +#include +#include +#include +#include "my_getopt.h" +#include "cmdparser.h" + + +/****************************************************/ +typedef vector < bool > vec_bool; + + +/****************************************************/ +/************class CommandLineRequester**************/ +/****************************************************/ +/* private methods */ +string CommandLineRequester::BuildOptStr(option_ifc_t &opt) +{ + string str; + + if (opt.option_short_name != ' ') { + str += "-"; + str += opt.option_short_name; + str += "|"; + } + str += "--"; + str += opt.option_name; + if (opt.option_value != "") { + str += " "; + str += opt.option_value; + } + return str; +} + + +/* public methods */ +#define OPT_STR_LEN 40 +#define OPT_DESC_LEN 40 +#define PREFIX_SPACE " " +#define PREFIX_SHORT_SPACE " " + + +string CommandLineRequester::GetUsageSynopsis(bool hidden_options) +{ + string str = ""; + string curr_str = PREFIX_SPACE; + + for (vec_option_t::iterator it = this->options.begin(); it != this->options.end(); ++it) { + if (hidden_options == false) { //display only not hidden options + if ((*it).hidden == true) { + continue; + } + } else { //display only hidden options + if ((*it).hidden == false) { + continue; + } + } + + curr_str += (*it).is_mandatory ? "<" : "["; + curr_str += this->BuildOptStr(*it); + curr_str += (*it).is_mandatory ? ">" : "]"; + if (curr_str.size() < OPT_STR_LEN) { + curr_str += " "; + } else { + str += curr_str; + str += "\n"; + curr_str = PREFIX_SPACE; + } + } + if (curr_str != PREFIX_SPACE) { + str += curr_str; + str += "\n"; + } + + if (str != "") { + str = PREFIX_SHORT_SPACE + this->name + "\n" + str; + } + + return str; +} + + +string CommandLineRequester::GetUsageDescription() +{ + if (this->description == "") + return ""; + string str = this->description; + + int prev_found = 0; + int found2 = str.find('\n', prev_found); + int found = str.find(" ", prev_found); + while (found != (int)string::npos) { + if ((found2 != (int)string::npos) && (found2 < found)) { + prev_found = found2; + } + if ((found - prev_found) > OPT_DESC_LEN + OPT_STR_LEN) { + prev_found = found + 1; + str.insert(found + 1, "\n"); + } + found2 = str.find('\n', found + 1); + found = str.find(" ", found + 1); + } + + prev_found = 0; + found = str.find('\n', prev_found); + while (found != (int)string::npos) { + str.insert(found + 1, PREFIX_SPACE); + prev_found = found + strlen(PREFIX_SPACE); + found = str.find('\n', prev_found); + } + + str = PREFIX_SPACE + str; + str = PREFIX_SHORT_SPACE + this->name + "\n" + str + "\n"; + + return str; +} + + +string CommandLineRequester::GetUsageOptions(bool hidden_options) +{ + string str = ""; + string opt_str, desc_str; + + for (vec_option_t::iterator it = this->options.begin(); it != this->options.end(); ++it) { + if (hidden_options == false) { //display only not hidden options + if ((*it).hidden == true) { + continue; + } + } else { //display only hidden options + if ((*it).hidden == false) { + continue; + } + } + + opt_str = PREFIX_SPACE; + opt_str += this->BuildOptStr(*it); + while (opt_str.size() < OPT_STR_LEN - 2) + opt_str += " "; + opt_str += ": "; + + desc_str = (*it).description; + int prev_found = 0; + int found2 = desc_str.find('\n', prev_found); + int found = desc_str.find(" ", prev_found); + while (found != (int)string::npos) { + if ((found2 != (int)string::npos) && (found2 < found)) { + prev_found = found2; + } + if ((found - prev_found + 1) > OPT_DESC_LEN) { + prev_found = found + 1; + desc_str.insert(found + 1, "\n"); + } + found2 = desc_str.find('\n', found + 1); + found = desc_str.find(" ", found + 1); + } + + prev_found = 0; + found = desc_str.find('\n', prev_found); + while (found != (int)string::npos) { + for (int i = 0; i < OPT_STR_LEN; ++i) + desc_str.insert(found + 1, " "); + prev_found = found + OPT_STR_LEN; + found = desc_str.find('\n', prev_found); + } + + str += opt_str; + str += desc_str; + str += "\n"; + } + + if (str != "") { + str = PREFIX_SHORT_SPACE + this->name + "\n" + str; + } + + return str; +} + + +/****************************************************/ +/**************class CommandLineParser***************/ +/****************************************************/ +/* private methods */ +void CommandLineParser::SetLastError(const char *fmt, ...) +{ + char buff[1024]; + va_list args; + + memset(buff, 0, sizeof(buff)); + va_start(args, fmt); + vsprintf(buff, fmt, args); + va_end(args); + + this->last_error.assign(buff); + return; +} + + +/* public methods */ +int CommandLineParser::AddRequester(CommandLineRequester *p_req) +{ + for (vec_option_t::iterator it = p_req->GetOptions().begin(); + it != p_req->GetOptions().end(); ++it) { + //long option must be valid + if ((*it).option_name == "") { + this->SetLastError("Requester \"%s\" has long option empty", + p_req->GetName().c_str()); + return 1; + } + + //check if long option already exists + map_str_p_command_line_req::iterator it2 = + this->long_opt_to_req_map.find((*it).option_name); + if (it2 != this->long_opt_to_req_map.end()) { + this->SetLastError("Option \"%s\" from requester \"%s\" " \ + "already exists in requester \"%s\"", + (*it).option_name.c_str(), + p_req->GetName().c_str(), + (*it2).second->GetName().c_str()); + return 1; + } + + //check if short option already exists + if ((*it).option_short_name != ' ') { //if space than no short option + map_char_str::iterator it2 = + this->short_opt_to_long_opt.find((*it).option_short_name); + if (it2 != this->short_opt_to_long_opt.end()) { + this->SetLastError("Option \'%c\' from requester \"%s\" " \ + "already exists in requester \"%s\"", + (*it).option_short_name, + p_req->GetName().c_str(), + this->long_opt_to_req_map[(*it2).second]->GetName().c_str()); + return 1; + } + } + } + + //finally add the requester + for (vec_option_t::iterator it = p_req->GetOptions().begin(); + it != p_req->GetOptions().end(); ++it) { + this->long_opt_to_req_map[(*it).option_name] = p_req; + if ((*it).option_short_name != ' ') //if space than no short option + this->short_opt_to_long_opt[(*it).option_short_name] = (*it).option_name; + } + this->p_requesters_list.push_back(p_req); + return 0; +} + + +string CommandLineParser::GetUsage(bool hidden_options) +{ + string res; + + //name + res = "NAME\n"; + res += PREFIX_SHORT_SPACE; + res += this->name; + res += "\n"; + + //synopsis + res += "SYNOPSIS\n"; + for (list_p_command_line_req::iterator it = this->p_requesters_list.begin(); + it != this->p_requesters_list.end(); ++it) { + res += (*it)->GetUsageSynopsis(hidden_options); + } + + //description + if (hidden_options == false) { + res += "DESCRIPTION\n"; + for (list_p_command_line_req::iterator it = this->p_requesters_list.begin(); + it != this->p_requesters_list.end(); ++it) { + res += (*it)->GetUsageDescription(); + } + } + + //options + res += "OPTIONS\n"; + for (list_p_command_line_req::iterator it = this->p_requesters_list.begin(); + it != this->p_requesters_list.end(); ++it) { + res += (*it)->GetUsageOptions(hidden_options); + } + return res; +} + + +ParseStatus CommandLineParser::ParseOptions(int argc, char **argv, + bool to_ignore_unknown_options, list_p_command_line_req *p_ignored_requesters_list) +{ + char **internal_argv; + struct option *options_arr; + string options_str = ""; + vec_bool returned_option_types_vec; + ParseStatus rc = PARSE_ERROR; + + //allocate internal_argv + internal_argv = new char *[argc]; + if (!internal_argv) { + this->SetLastError("Fail to allocate internal argv for parsing"); + return PARSE_ERROR; + } + for (int i = 0; i < argc; ++i) { + internal_argv[i] = new char[strlen(argv[i]) + 1]; + if (!internal_argv[i]) { + this->SetLastError("Fail to allocate internal argv[%u] for parsing", i); + return PARSE_ERROR; + } + strcpy(internal_argv[i], argv[i]); + } + + //allocate long_options_arr + unsigned num_options = this->long_opt_to_req_map.size(); + options_arr = new struct option[num_options + 1]; + if (!options_arr) { + this->SetLastError("Fail to allocate long_options_arr"); + return PARSE_ERROR; + } + memset(options_arr, 0, sizeof(struct option)*(num_options + 1)); + + /* + * fill options array and options string with + * getopt_long_only() formats + * also create vector of possible options type + * that can be return by getopt_long_only() + */ + unsigned i = 0; + for (list_p_command_line_req::iterator it = this->p_requesters_list.begin(); + it != this->p_requesters_list.end(); ++it) { + for (vec_option_t::iterator it2 = (*it)->GetOptions().begin(); + it2 != (*it)->GetOptions().end(); ++it2) { + options_str += (*it2).option_short_name; + options_arr[i].name = (*it2).option_name.c_str(); + if ((*it2).option_value != "") { + options_arr[i].has_arg = 1; + options_str += ":"; + } else { + options_arr[i].has_arg = 0; + } + options_arr[i].flag = 0; + if ((*it2).option_short_name != ' ') { + options_arr[i].val = (*it2).option_short_name; + } else { + options_arr[i].val = 0; + } + + if (returned_option_types_vec.empty() || (returned_option_types_vec.size() < (unsigned int)options_arr[i].val + 1)) + for (unsigned j = returned_option_types_vec.size(); j < (unsigned int)options_arr[i].val + 1; ++j) + returned_option_types_vec.push_back(false); + returned_option_types_vec[options_arr[i].val] = true; + //printf("%c %d ", options_arr[i].val, options_arr[i].val); + ++i; + } + } + + +/* + for (unsigned int i = 0; i < num_options + 1; ++i) { + printf("name: %s, has_arg:%d, val:%c\n", + options_arr[i].name, options_arr[i].has_arg, options_arr[i].val); + } + printf("%s\n", options_str.c_str()); + for (unsigned i = 0; i < returned_option_types_vec.size(); ++i) { + if (returned_option_types_vec[i] == true) { + if (!i) + printf("%d ", 0); + else + printf("%c ", i); + } + } + printf("\n"); +*/ + + + //finally parse all options + int option_type; + int option_index = 0; + if (to_ignore_unknown_options == true) + tools_opterr = 0; + else + tools_opterr = 1; + tools_optind = 0; + + ParseStatus curr_result; + while ((option_type = tools_getopt_long_only(argc, internal_argv, options_str.c_str(), + options_arr, &option_index)) != -1) { + //printf("option_type=\'%c\'\n", option_type); + + string long_opt_name; + if (option_type == 0) { + long_opt_name = options_arr[option_index].name; + goto do_handle_option; + } else if (option_type == '?') { + if (to_ignore_unknown_options == true) + continue; + this->SetLastError("Bad input parameter"); + goto parse_exit; + } else if (returned_option_types_vec[option_type] == true) { + long_opt_name = this->short_opt_to_long_opt[option_type]; + goto do_handle_option; + } else { + this->SetLastError("getopt_long_only() returned character code 0%o", option_type); + goto parse_exit; + } + +do_handle_option: + CommandLineRequester *p_req = this->long_opt_to_req_map[long_opt_name]; + bool ignore_this_req = false; + if (p_ignored_requesters_list) + for (list_p_command_line_req::iterator it = p_ignored_requesters_list->begin(); + it != p_ignored_requesters_list->end(); ++it) { + if (p_req == (*it)) { + ignore_this_req = true; + break; + } + } + if (ignore_this_req == false) { + curr_result = p_req->HandleOption(long_opt_name, (tools_optarg == NULL) ? "" : tools_optarg); + if (curr_result) { + rc = curr_result; + this->SetLastError("Failed to handle option %s", long_opt_name.c_str()); + goto parse_exit; + } + } + continue; + } + + if (tools_optind < argc) { + while (tools_optind < argc) { + this->last_unknown_options += internal_argv[tools_optind]; + this->last_unknown_options += " "; + ++tools_optind; + } + /*if (this->last_unknown_options != "") //remove last space + this->last_unknown_options.erase(this->last_unknown_options.end() - 1, + this->last_unknown_options.end());*/ + if (to_ignore_unknown_options == false) { + string str = "Found some non-option ARGV-elements "; + str += this->last_unknown_options; + this->SetLastError(str.c_str()); + goto parse_exit; + } + } + + rc = PARSE_OK; +parse_exit: + for (int i = 0; i < argc; ++i) + delete [] internal_argv[i]; + delete [] internal_argv; + delete [] options_arr; + return rc; +} + diff --git a/cmdparser/cmdparser.h b/cmdparser/cmdparser.h new file mode 100644 index 0000000..0144be6 --- /dev/null +++ b/cmdparser/cmdparser.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2004-2010 Mellanox Technologies LTD. All rights reserved. + * + * This software is available to you under the terms of the + * OpenIB.org BSD license included below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + + +#ifndef _OPT_PARSER_H_ +#define _OPT_PARSER_H_ + + +#include +#include +#include +#include +#include +using namespace std; + + +/******************************************************/ +typedef enum +{ + //Returns: 0 - OK / 1 - parsing error / 2 - OK but need to exit / 3 - some other error + PARSE_OK = 0, + PARSE_ERROR = 1, + PARSE_OK_WITH_EXIT = 3, + PARSE_ERROR_SHOW_USAGE = 4 +} ParseStatus; + +typedef struct option_ifc { + string option_name; //must be valid + char option_short_name; //can be used as short option, if space than no short flag + string option_value; //if "" has no argument + string description; //will be display in usage + bool hidden; //if hidden than will not be diaplayed in regular usage + bool is_mandatory; +} option_ifc_t; + +typedef vector < struct option_ifc > vec_option_t; + + +class CommandLineRequester { +protected: + // members + vec_option_t options; + string name; + string description; + + // methods + string BuildOptStr(option_ifc_t &opt); + +public: + // methods + CommandLineRequester(string req_name) : name(req_name) {} + virtual ~CommandLineRequester() {} + + inline void AddOptions(option_ifc_t options[], int arr_size) { + for (int i = 0; i < arr_size; ++i) + this->options.push_back(options[i]); + } + inline void AddOptions(string option_name, + char option_short_name, + string option_value, + string description, + bool hidden = false, + bool is_mandatory = false) { + option_ifc_t opt; + opt.option_name = option_name; + opt.option_short_name = option_short_name; + opt.option_value = option_value; + opt.description = description; + opt.hidden = hidden; + opt.is_mandatory = is_mandatory; + this->options.push_back(opt); + } + inline void AddDescription(string desc) { this->description = desc; } + inline vec_option_t& GetOptions() { return this->options; } + inline string& GetName() { return this->name; } + + string GetUsageSynopsis(bool hidden_options = false); + string GetUsageDescription(); + string GetUsageOptions(bool hidden_options = false); + + virtual ParseStatus HandleOption(string name, string value) = 0; +}; + + +/******************************************************/ +typedef list < CommandLineRequester * > list_p_command_line_req; +typedef map < char, string > map_char_str; +typedef map < string, CommandLineRequester * > map_str_p_command_line_req; + + +class CommandLineParser { +private: + // members + list_p_command_line_req p_requesters_list; + map_char_str short_opt_to_long_opt; + map_str_p_command_line_req long_opt_to_req_map; + + string name; + string last_error; + string last_unknown_options; + + // methods + void SetLastError(const char *fmt, ...); + +public: + // methods + CommandLineParser(string parser_name) : + name(parser_name), last_error(""), last_unknown_options("") {} + ~CommandLineParser() {} + + inline const char * GetErrDesc() { return this->last_error.c_str(); } + inline const char * GetUnknownOptions() { return this->last_unknown_options.c_str(); } + + int AddRequester(CommandLineRequester *p_req); //if multiple option than fail + + ParseStatus ParseOptions(int argc, char **argv, + bool to_ignore_unknown_options = false, + list_p_command_line_req *p_ignored_requesters_list = NULL); + + string GetUsage(bool hidden_options = false); +}; + + +#endif /* not defined _OPT_PARSER_H_ */ diff --git a/cmdparser/my_getopt.c b/cmdparser/my_getopt.c new file mode 100755 index 0000000..6bd7ce8 --- /dev/null +++ b/cmdparser/my_getopt.c @@ -0,0 +1,1083 @@ + /* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97 + Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + + /* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ + #ifndef _NO_PROTO + #define _NO_PROTO + #endif + + #ifdef HAVE_CONFIG_H + #include + #endif + + #if !defined (__STDC__) || !__STDC__ + /* This is a separate conditional since some stdc systems + reject `defined (const)'. */ + #ifndef const + #define const + #endif + #endif + + #include + + /* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + + #define GETOPT_INTERFACE_VERSION 2 + #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2 + #include + #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION + #define ELIDE_CODE + #endif + #endif + + + + /* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ + #ifdef __GNU_LIBRARY__ + /* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ + #include + #include + #endif /* GNU C library. */ + + #ifdef HAVE_STRING_H + # include /* strstr / strdup */ + #else + # ifdef HAVE_STRINGS_H + # include /* strstr / strdup */ + # endif + #endif + + #ifdef VMS + #include + #if HAVE_STRING_H - 0 + #include + #endif + #endif +#include + #ifndef _ + /* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ + #ifdef HAVE_LIBINTL_H + # include + # define _(msgid) gettext (msgid) + #else + # define _(msgid) (msgid) + #endif + #endif + + /* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + + #include "my_getopt.h" + + /* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + + char *tools_optarg = NULL; + + /* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `tools_optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + + /* 1003.2 says this must be 1 before any call. */ + int tools_optind = 1; + + /* Formerly, initialization of getopt depended on tools_optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + + int __getopt_initialized = 0; + + /* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + + static char *nextchar; + + /* Callers store zero here to inhibit the error message + for unrecognized options. */ + + int tools_opterr = 1; + + /* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + + int tools_optopt = '?'; + + /* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `tools_optind' != ARGC. */ + + static enum + { + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER + } ordering; + + /* Value of POSIXLY_CORRECT environment variable. */ + static char *posixly_correct; + + #ifdef __GNU_LIBRARY__ + /* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ + #include + #define my_index strchr + #else + + /* Avoid depending on library functions or files + whose names are inconsistent. */ + + char *getenv (); + + static char * + my_index (str, chr) + const char *str; + int chr; + { + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; + } + + /* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ + #ifdef __GNUC__ + /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ + #if !defined (__STDC__) || !__STDC__ + /* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ + extern int strlen (const char *); + #endif /* not __STDC__ */ + #endif /* __GNUC__ */ + + #endif /* not __GNU_LIBRARY__ */ + + /* Handle permutation of arguments. */ + + /* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + + static int first_nonopt; + static int last_nonopt; + + #ifdef _LIBC + /* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + + /* Defined in getopt_init.c */ + extern char *__getopt_nonoption_flags; + + static int nonoption_flags_max_len; + static int nonoption_flags_len; + + static int original_argc; + static char *const *original_argv; + + /* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ + static void + __attribute__ ((unused)) + store_args_and_env (int argc, char *const *argv) + { + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; + } + # ifdef text_set_element + text_set_element (__libc_subinit, store_args_and_env); + # endif /* text_set_element */ + + # define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } + #else /* !_LIBC */ + # define SWAP_FLAGS(ch1, ch2) + #endif /* _LIBC */ + + /* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,tools_optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + + #if defined (__STDC__) && __STDC__ + static void exchange (char **); + #endif + + static void + exchange (argv) + char **argv; + { + int bottom = first_nonopt; + int middle = last_nonopt; + int top = tools_optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + + #ifdef _LIBC + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } + #endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (tools_optind - last_nonopt); + last_nonopt = tools_optind; + } + + /* Initialize the internal data when the first call is made. */ + + #if defined (__STDC__) && __STDC__ + static const char *_getopt_initialize (int, char *const *, const char *); + #endif + static const char * + _getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; + { + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = tools_optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + + #ifdef _LIBC + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; + #endif + + return optstring; + } + + /* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `tools_optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `tools_optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `tools_opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `tools_optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `tools_optarg', otherwise `tools_optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + + int + _getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; + { + tools_optarg = NULL; + + if (tools_optind == 0 || !__getopt_initialized) + { + if (tools_optind == 0) + tools_optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[tools_optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ + #ifdef _LIBC + #define NONOPTION_P (argv[tools_optind][0] != '-' || argv[tools_optind][1] == '\0' \ + || (tools_optind < nonoption_flags_len \ + && __getopt_nonoption_flags[tools_optind] == '1')) + #else + #define NONOPTION_P (argv[tools_optind][0] != '-' || argv[tools_optind][1] == '\0') + #endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > tools_optind) + last_nonopt = tools_optind; + if (first_nonopt > tools_optind) + first_nonopt = tools_optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != tools_optind) + exchange ((char **) argv); + else if (last_nonopt != tools_optind) + first_nonopt = tools_optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (tools_optind < argc && NONOPTION_P) + tools_optind++; + last_nonopt = tools_optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (tools_optind != argc && !strcmp (argv[tools_optind], "--")) + { + tools_optind++; + + if (first_nonopt != last_nonopt && last_nonopt != tools_optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = tools_optind; + last_nonopt = argc; + + tools_optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (tools_optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + tools_optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + tools_optarg = argv[tools_optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[tools_optind] + 1 + + (longopts != NULL && argv[tools_optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[tools_optind][1] == '-' + || (long_only && (argv[tools_optind][2] || !my_index (optstring, argv[tools_optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (tools_opterr) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[tools_optind]); + nextchar += strlen (nextchar); + tools_optind++; + tools_optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + tools_optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + { + tools_optarg = nameend + 1; + } + else + { + if (tools_opterr) + if (argv[tools_optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[tools_optind - 1][0], pfound->name); + + nextchar += strlen (nextchar); + + tools_optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (tools_optind < argc) + tools_optarg = argv[tools_optind++]; + else + { + if (tools_opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[tools_optind - 1]); + nextchar += strlen (nextchar); + tools_optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[tools_optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (tools_opterr) + { + if (argv[tools_optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[tools_optind][0], nextchar); + } + nextchar = (char *) ""; + tools_optind++; + tools_optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `tools_optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++tools_optind; + + if (temp == NULL || c == ':') + { + if (tools_opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + tools_optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + tools_optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + tools_optind++; + } + else if (tools_optind == argc) + { + if (tools_opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + tools_optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `tools_optind' once; + increment it again when taking next ARGV-elt as argument. */ + tools_optarg = argv[tools_optind++]; + + /* tools_optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = tools_optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (tools_opterr) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[tools_optind]); + nextchar += strlen (nextchar); + tools_optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + tools_optarg = nameend + 1; + else + { + if (tools_opterr) + fprintf (stderr, _("\ + %s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (tools_optind < argc) + tools_optarg = argv[tools_optind++]; + else + { + if (tools_opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[tools_optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + tools_optarg = nextchar; + tools_optind++; + } + else + tools_optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + tools_optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + tools_optind++; + } + else if (tools_optind == argc) + { + if (tools_opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + tools_optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `tools_optind' once; + increment it again when taking next ARGV-elt as argument. */ + tools_optarg = argv[tools_optind++]; + nextchar = NULL; + } + } + return c; + } + } + + int + tools_getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; + { + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); + } + + int + tools_getopt_long (argc, argv, optstring, longopts, longindex) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longindex; + { + return _getopt_internal (argc, argv, optstring, + longopts, + longindex, + 0); + } + + + int + tools_getopt_long_only (argc, argv, optstring, longopts, longindex) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longindex; + { + return _getopt_internal (argc, argv, optstring, + longopts, + longindex, + 1); + } + + + #ifdef TEST + + /* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + + int + main (argc, argv) + int argc; + char **argv; + { + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = tools_optind ? tools_optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", tools_optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (tools_optind < argc) + { + printf ("non-option ARGV-elements: "); + while (tools_optind < argc) + printf ("%s ", argv[tools_optind++]); + printf ("\n"); + } + + exit (0); + } + + #endif /* TEST */ + +int hello() +{ + return 1; +} diff --git a/cmdparser/my_getopt.h b/cmdparser/my_getopt.h new file mode 100755 index 0000000..96def52 --- /dev/null +++ b/cmdparser/my_getopt.h @@ -0,0 +1,122 @@ + /* Declarations for getopt. + Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + + #ifndef _TOOLS_GETOPT_H + #define _TOOLS_GETOPT_H + + #ifdef __cplusplus + extern "C" { + #endif + + /* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + + extern char *tools_optarg; + + /* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + + extern int tools_optind; + + /* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + + extern int tools_opterr; + + /* Set to an option character which was unrecognized. */ + + extern int tools_optopt; + + /* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + + struct option + { + #if defined (__STDC__) && __STDC__ + const char *name; + #else + char *name; + #endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; + }; + + /* Names for the values of the `has_arg' field of `struct option'. */ + + #define tools_no_argument 0 + #define tools_required_argument 1 + #define tools_optional_argument 2 + +int tools_getopt ( + int argc, + char *const *argv, + const char *shortopts); + +int tools_getopt_long ( + int argc, + char *const *argv, + const char *shortopts, + const struct option *longopts, + int *longind); + +int tools_getopt_long_only ( + int argc, + char *const *argv, + const char *shortopts, + const struct option *longopts, + int *longind); + + #ifdef __cplusplus + } + #endif + + #endif /* _TOOLS_GETOPT_H */ diff --git a/common/tools_version.h b/common/tools_version.h index 8f07c80..a3c526b 100644 --- a/common/tools_version.h +++ b/common/tools_version.h @@ -35,6 +35,8 @@ // Generic version for all tools // +#ifndef __TOOLS_VERSION_H__ +#define __TOOLS_VERSION_H__ #include #include @@ -78,3 +80,6 @@ void print_version_string(const char* exe_name, const char* tool_version) { get_version_string(buf, sizeof(buf), exe_name, tool_version); printf("%s\n", buf); } + +#endif + diff --git a/configure.ac b/configure.ac index 7c87b78..a5441e3 100644 --- a/configure.ac +++ b/configure.ac @@ -1,16 +1,16 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(mstflint, 3.0, orenk@mellanox.co.il) +AC_INIT(mstflint, 3.5.0, orenk@mellanox.co.il) AC_DEFINE_UNQUOTED([PROJECT], ["mstflint"], [Define the project name.]) AC_SUBST([PROJECT]) -AC_DEFINE_UNQUOTED([VERSION], ["3.0"], [Define the project version.]) +AC_DEFINE_UNQUOTED([VERSION], ["3.5.0"], [Define the project version.]) AC_SUBST([VERSION]) AC_CONFIG_AUX_DIR(config) AC_CONFIG_SRCDIR([README]) -AM_INIT_AUTOMAKE(mstflint, 3.0) +AM_INIT_AUTOMAKE(mstflint, 3.5.0) dnl Checks for programs AC_PROG_CC @@ -36,5 +36,5 @@ AC_SUBST(mstflint_CXXFLAGS) AC_CONFIG_FILES( mstflint.spec ) -AC_OUTPUT( Makefile mtcr_ul/Makefile dev_mgt/Makefile mflash/Makefile flint/Makefile small_utils/Makefile \ - mstdump/Makefile mstdump/crd_lib/Makefile mstdump/crd_main/Makefile mstdump/mstdump_dbs/Makefile ) +AC_OUTPUT( Makefile mtcr_ul/Makefile dev_mgt/Makefile mflash/Makefile tools_layouts/Makefile mlxfwops/Makefile mlxfwops/lib/Makefile cmdparser/Makefile flint/Makefile \ + small_utils/Makefile mstdump/Makefile mstdump/crd_lib/Makefile mstdump/crd_main/Makefile mstdump/mstdump_dbs/Makefile ) diff --git a/dev_mgt/tools_dev_types.c b/dev_mgt/tools_dev_types.c index a25cb17..beaabd1 100644 --- a/dev_mgt/tools_dev_types.c +++ b/dev_mgt/tools_dev_types.c @@ -215,7 +215,7 @@ int dm_get_device_id(mfile* mf, #if 1 for (i = 0; i < DeviceEndMarker; i++) { if (g_devs_info[i].dm_id != i) { - printf("-F- in get_device_type: Wron index of the g_devs_info array. idx %d dev %s\n", + printf("-F- in get_device_type: Wrong index of the g_devs_info array. idx %d dev %s\n", i, g_devs_info[i].name); exit(1); } diff --git a/flint/Makefile.am b/flint/Makefile.am new file mode 100755 index 0000000..00a60ad --- /dev/null +++ b/flint/Makefile.am @@ -0,0 +1,54 @@ +#-- +# Copyright (c) 2004-2010 Mellanox Technologies LTD. All rights reserved. +# +# This software is available to you under a choice of one of two +# licenses. You may choose to be licensed under the terms of the GNU +# General Public License (GPL) Version 2, available from the file +# COPYING in the main directory of this source tree, or the +# OpenIB.org BSD license below: +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the following +# conditions are met: +# +# - Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# - Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or othint2_oem.er materials +# provided with the distribution. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +#-- + +# Makefile.am -- Process this file with automake to produce Makefile.in +USER_DIR = .. +MTCR_DIR = $(USER_DIR)/mtcr_ul +COMMON_DIR = $(USER_DIR)/common +LAYOUTS_DIR = $(USER_DIR)/tools_layouts +LAYOUTS_LIB = $(LAYOUTS_DIR)/libtools_layouts.la + + + +INCLUDES = -I. -I.. -I$(MTCR_DIR) -I../mflash -I$(COMMON_DIR) \ + -I $(LAYOUTS_DIR) $(ZLIB_INC) -I$(MFT_EXT_LIBS_INC_DIR)/zlib + +AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe +bin_PROGRAMS = mstflint + +mstflint_SOURCES = flint.cpp flint.h subcommands.cpp subcommands.h\ + flint_params.cpp flint_params.h cmd_line_parser.cpp err_msgs.h + +mstflint_LDADD = ../mlxfwops/lib/libmlxfwops.la ../cmdparser/libcmdparser.la ../mflash/libmflash.la $(MTCR_DIR)/libmtcr_ul.a $(ZLIB_LIB) $(LAYOUTS_LIB) $(LIBSTD_CPP) -ldl + +mstflintinclude_HEADERS = $(top_srcdir)/include/mtcr_ul/mtcr.h +mstflintincludedir = @includedir@/mtcr_ul diff --git a/flint/cmd_line_parser.cpp b/flint/cmd_line_parser.cpp new file mode 100644 index 0000000..0ca632e --- /dev/null +++ b/flint/cmd_line_parser.cpp @@ -0,0 +1,961 @@ +/* + * + * cmd_line_parser.cpp - FLash INTerface + * + * Copyright (c) 2013 Mellanox Technologies Ltd. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Version: $Id$ + * + */ + +#include +#include +// Flint includes +#include "flint.h" +#include +#include + +#ifndef FLINT_NAME + #ifdef __GNUC__ + #define FLINT_NAME "flint" + #else + #define FLINT_NAME "flint" + #endif +#endif + +using namespace std; + +/****************************** + * Data structures containing + * Meta data about subcommands + * and flags + ******************************/ +class SubCmdMetaData { +private: + class SubCmd { + public: + SubCmd(string s, string l, sub_cmd_t n): shortf(s), longf(l), cmdNum(n) {} + ~SubCmd(){} + string shortf; + string longf; + sub_cmd_t cmdNum; + }; + vector _sCmds; +public: + SubCmdMetaData(); + ~SubCmdMetaData(); + sub_cmd_t getCmdNum(string flag); +}; + +SubCmdMetaData::SubCmdMetaData() { + _sCmds.push_back(new SubCmd("b", "burn", SC_Burn)); + _sCmds.push_back(new SubCmd("q", "query", SC_Query)); + _sCmds.push_back(new SubCmd("v", "verify", SC_Verify)); + _sCmds.push_back(new SubCmd("", "swreset", SC_Swreset)); + _sCmds.push_back(new SubCmd("", "brom", SC_Brom)); + _sCmds.push_back(new SubCmd("", "drom", SC_Drom)); + _sCmds.push_back(new SubCmd("", "rrom", SC_Rrom)); + _sCmds.push_back(new SubCmd("", "qrom", SC_Qrom)); + _sCmds.push_back(new SubCmd("", "bb", SC_Bb)); + _sCmds.push_back(new SubCmd("", "sg", SC_Sg)); +#ifndef EXTERNAL + _sCmds.push_back(new SubCmd("", "smg", SC_Smg)); + _sCmds.push_back(new SubCmd("", "set_vpd", SC_Set_Vpd)); +#endif + _sCmds.push_back(new SubCmd("", "sv", SC_Sv)); + _sCmds.push_back(new SubCmd("", "ri", SC_Ri)); + _sCmds.push_back(new SubCmd("", "dc", SC_Dc)); + _sCmds.push_back(new SubCmd("", "dh", SC_Dh)); + _sCmds.push_back(new SubCmd("", "set_key", SC_Set_Key)); + _sCmds.push_back(new SubCmd("", "hw_access", SC_Hw_Access)); + _sCmds.push_back(new SubCmd("", "hw", SC_Hw)); + _sCmds.push_back(new SubCmd("e", "erase", SC_Erase)); + _sCmds.push_back(new SubCmd("", "rw", SC_Rw)); + _sCmds.push_back(new SubCmd("", "ww", SC_Ww)); + _sCmds.push_back(new SubCmd("", "wwne", SC_Wwne)); + _sCmds.push_back(new SubCmd("", "wbne", SC_Wbne)); + _sCmds.push_back(new SubCmd("", "wb", SC_Wb)); + _sCmds.push_back(new SubCmd("", "rb", SC_Rb)); + _sCmds.push_back(new SubCmd("", "clear_semaphore", SC_Clear_Sem)); +} + +SubCmdMetaData::~SubCmdMetaData() { + for (vector::iterator it= _sCmds.begin(); it != _sCmds.end(); ++it ) + { + delete *it; + } +} + +sub_cmd_t SubCmdMetaData::getCmdNum(string flag) +{ + for (vector::iterator it= _sCmds.begin(); it != _sCmds.end(); ++it ) + { + if (((*it)->shortf == flag) || ((*it)->longf == flag)) { + return (*it)->cmdNum; + } + } + return SC_No_Cmd; +} + + +class FlagMetaData { +private: + class Flag { + public: + Flag(string s, string l, int n): shortf(s), longf(l), argNum(n) {} + ~Flag(){} + string shortf; + string longf; + int argNum; + }; + vector _flags; +public: + FlagMetaData(); + ~FlagMetaData(); + int getNumOfArgs(string flag); +}; + +FlagMetaData::FlagMetaData() { + _flags.push_back(new Flag("d", "device", 1)); + _flags.push_back(new Flag("", "guid", 1)); + _flags.push_back(new Flag("", "guids", GUIDS)); + _flags.push_back(new Flag("", "mac", 1)); + _flags.push_back(new Flag("", "macs", MACS)); + _flags.push_back(new Flag("", "uid", 1)); + _flags.push_back(new Flag("", "uids", 29)); //TODO: update this with the correct constatnt from mlxfwops + _flags.push_back(new Flag("", "blank_guids", 0)); + _flags.push_back(new Flag("", "clear_semaphore", 0)); + _flags.push_back(new Flag("h", "help", 0)); + _flags.push_back(new Flag("", "hh", 0)); + _flags.push_back(new Flag("i", "image", 1)); + _flags.push_back(new Flag("", "qq", 0)); + _flags.push_back(new Flag("", "nofs", 0)); + _flags.push_back(new Flag("", "allow_psid_change", 0)); + _flags.push_back(new Flag("", "allow_rom_change", 0)); + _flags.push_back(new Flag("", "override_cache_replacement", 0)); + _flags.push_back(new Flag("", "ocr", 0)); + _flags.push_back(new Flag("", "no_flash_verify", 0)); + _flags.push_back(new Flag("s", "silent", 0)); + _flags.push_back(new Flag("y", "yes", 0)); + _flags.push_back(new Flag("", "no", 0)); + _flags.push_back(new Flag("", "vsd", 1)); + _flags.push_back(new Flag("", "use_image_ps", 0)); + _flags.push_back(new Flag("", "use_image_guids", 0)); + _flags.push_back(new Flag("", "use_image_rom", 0)); + _flags.push_back(new Flag("", "dual_image", 0)); + _flags.push_back(new Flag("", "striped_image", 0)); + _flags.push_back(new Flag("", "banks", 1)); + _flags.push_back(new Flag("", "log", 1)); + _flags.push_back(new Flag("", "flash_params", 1)); //its actually 3 but separated by comma so we refer to them as one + _flags.push_back(new Flag("v", "version", 0)); + _flags.push_back(new Flag("", "no_devid_check", 0)); +} + +FlagMetaData::~FlagMetaData() { + for (vector::iterator it= _flags.begin(); it != _flags.end(); ++it ) + { + delete *it; + } +} + +int FlagMetaData::getNumOfArgs(string flag) +{ + for (vector::iterator it= _flags.begin(); it != _flags.end(); ++it ) + { + if (((*it)->shortf == flag) || ((*it)->longf == flag)) { + return (*it)->argNum; + } + } + return -1; +} + +/******************** + * Helper Functions: + *******************/ + +// NOTE : number of parameters extracted in the container should be checked. +static void splitByDelimiters(std::vector& container, string str, const char* delimiters ) +{ + if (str.size() == 0 ) { + return; + } + char* cStr = strcpy(new char[str.size()+1], str.c_str()); + char* ptr; + ptr = strtok(cStr, delimiters); + + while (ptr != NULL) { + container.push_back(ptr); + ptr = strtok(NULL, delimiters); + } + delete[] cStr; + return; +} + +char* stripFlag(char* flag) { + char* strippedFlagStart = NULL; + if (flag[0] != '-') { // not a flag + return flag; + }; + if ((flag[0] == '-') && (flag[1] == '-')) + strippedFlagStart = &flag[2]; + else { + strippedFlagStart = &flag[1]; + } + return strippedFlagStart; +} + +int countArgs(string args) { + if (args.size() == 0) + return 0; + int count = 1; + for (string::iterator it = args.begin(); it < args.end(); ++it) { + if (*it == ',') + count++; + } + return count; +} + +bool verifyNumOfArgs(string name, string value) { + //HACK : we don't check device numOfArgs because image device format might contain "," + if ((name == "device") || (name == "d") ) { + return true; + } + if ((name == "image") || (name == "i") ) { + return true; + } + // Hack : VSD can be empty or contain "," so we shouldnt count its args + if (name == "vsd") { + return true; + } + + int expected = FlagMetaData().getNumOfArgs(name); + if (expected < 0) { + printf(FLINT_INVALID_FLAG_ERROR, name.c_str()); + return false; + } + //HACK : flash_params is 3 argument but given with comma separated instead of spaces like the rest + // so flag_arg_num gives a wrong value + + if (name == "flash_params") + expected = 3; + int actual = countArgs(value); + if (actual < expected) { + printf(FLINT_TOO_FEW_ARGS_ERROR,expected, actual); + return false; + } else if (actual > expected) { + printf(FLINT_TOO_MANY_ARGS_ERROR, expected, actual); + return false; + } + return true; +} + +bool strToNum(string str, u_int64_t& num, int base=0) +{ + char *endp; + char* numStr = strcpy(new char[str.size()],str.c_str()); + num = strtoul(numStr, &endp, base); + if (*endp) { + delete[] numStr; + return false; + } + delete[] numStr; + return true; +} + +//this function is used in extracting both guids and macs from user +bool getGUIDFromStr(string str, guid_t& guid, string prefixErr="") +{ + char* endp; + u_int64_t g; + g = strtoull(str.c_str(), &endp, 16); + if (*endp || (g == 0xffffffffffffffffULL && errno == ERANGE)) { + if (prefixErr.size() == 0) { + printf("-E- Invalid GUID syntax (%s) %s \n", str.c_str(), errno ? strerror(errno) : "" ); + } else { + printf("%s\n", prefixErr.c_str()); + } + return false; + } + guid.h = (u_int32_t)(g >> 32); + guid.l = (u_int32_t)(g & 0xffffffff); + return true; +} + +guid_t incrGuid(guid_t baseGuid, unsigned int incrVal) +{ + u_int64_t g = baseGuid.h; + g = (g << 32) | baseGuid.l; + g += incrVal; + guid_t userGuid; + userGuid.h = (u_int32_t)(g >> 32); + userGuid.l = (u_int32_t)g; + return userGuid; +} + +guid_t GetBaseMac(guid_t baseGuid) +{ + guid_t baseMac; + baseMac.l = (baseGuid.l & 0x00ffffff) | ((baseGuid.h & 0xff00) << 16); + baseMac.h = baseGuid.h >> 16; + return baseMac; +} + +bool InitBxGuids(std::vector& user_guids, guid_t base_guid1) { + + int base_index = 0; + guid_t base_mac, base_guid; + user_guids.resize(MAX_GUIDS); + + for (int i = 0; i < BX_SLICES_NUM; i++) { + base_index = i * BX_SLICE_GUIDS; + base_guid = incrGuid(base_guid1, i * 8); + // Init Guids + int base_guids_index = base_index + BI_GUIDS; + for (int j = 0; j < BX_NP_GUIDS; j++) { + if (j == 0) { + // The node guid should be the same one on the two slices. + user_guids[base_guids_index + j] = incrGuid(base_guid1, j); + } else { + user_guids[base_guids_index + j] = incrGuid(base_guid, j); + } + + } + // Init Macs + base_mac = GetBaseMac(base_guid); + int base_macs_index = base_index + BI_IMACS; + for (int j = 0; j < BX_MACS; j++) { + user_guids[base_macs_index + j] = incrGuid(base_mac, j); + } + // Init WWPNSs + int base_wwpn_index = base_index + BI_WWPNS; + int base_emac_index = base_index + BI_EMACS; + + for (int j = 0; j < BX_WWPNS; j++) { + user_guids[base_wwpn_index + j].l = user_guids[base_emac_index + j].l; + user_guids[base_wwpn_index + j].h = (user_guids[base_emac_index + j].h | (0x2000 << 16)); + } + + // Init WWNNS + int base_wwnn_index = base_index + BI_WWNNS; + base_emac_index = base_index + BI_EMACS; + + user_guids[base_wwnn_index].l = user_guids[base_emac_index].l; + user_guids[base_wwnn_index].h = (user_guids[base_emac_index].h | (0x2001 << 16)); + } + + // Init SysGuid + user_guids[BI_SYS_GUID] = incrGuid(base_guid1, 7); + return true; +} + +bool parseFlashParams(string params, flash_params_t& fp) +{ + // Step 1 split by "," + std::vector paramVec; + splitByDelimiters(paramVec, params, ","); + if (paramVec.size() != 3) { + return false; + } + // Step 2 extract params + fp.type_name = strcpy(new char[paramVec[0].length()+1], paramVec[0].c_str()); + if (!fp.type_name) { + return false; + } + u_int64_t tmp; + if (!strToNum(paramVec[1], tmp)) { + delete[] fp.type_name; + return false; + } + fp.log2size = (int)tmp; + if (!strToNum(paramVec[2], tmp)) { + delete[] fp.type_name; + return false; + } + fp.num_of_flashes = (int)tmp; + return true; +} + +/************************************ + *Implementation of the Command line + *Parsing part of the Flint class + ************************************/ + + + +void Flint::initCmdParser() { + AddDescription("flint is a FW (firmware) burning and flash memory operations tool for\n" + "Mellanox Infiniband HCAs, Ethernet NIC cards, and switch devices."); + + AddOptions("device", + 'd', + "", + "Device flash is connected to.\n" + "Commands affected: all"); + + AddOptions("guid", + ' ', + "", + "GUID base value. 4 GUIDs\n" + "are automatically assigned to the following values:\n\n" + "guid -> node GUID\n" + "guid+1 -> port1\n" + "guid+2 -> port2\n" + "guid+3 -> system image GUID.\n\n" + "Note: port2 guid will be assigned even for a\n" + "single port HCA - The HCA ignores this value.\n\n" + "Commands affected: burn, sg"); + + AddOptions("guids", + ' ', + "", + "4 GUIDs must be specified here.\n" + "The specified GUIDs are assigned\n" + "to the following fields, repectively:\n" + "node, port1, port2 and system image GUID.\n\n" + "Note: port2 guid must be specified even for a\n" + "single port HCA - The HCA ignores this value.\n" + "It can be set to 0x0.\n\n" + "Commands affected: burn, sg"); + + AddOptions("mac", + ' ', + "", + "MAC address base value. 2 MACs\n" + "are automatically assigned to the\n" + "following values:\n\n" + "mac -> port1\n" + "mac+1 -> port2\n\n" + "Commands affected: burn, sg"); + + AddOptions("macs", + ' ', + "", + "2 MACs must be specified here.\n" + "The specified MACs are assigned\n" + "to port1, port2, repectively.\n" + "Commands affected: burn, sg\n\n" + "Note: -mac/-macs flags are applicable only for Mellanox\n" + "\tTechnologies ethernet products."); + + AddOptions("uid", + ' ', + "", + "BridgeX only. Derive and set the device UIDs (GUIDs, MACs, WWNs).\n" + "UIDs are derived from the given base UID according to Mellanox Methodology\n" + "Commands affected: burn, sg"); + + AddOptions("uids", + ' ', + "", + "BridgeX only. 29 space separated UIDs must be specified here.\n" + "The specified UIDs are assigned to the following fields, repectively:\n" + "G0-MAC-PI0 G0-MAC-PI1 G0-MAC-PI2\n" + "G0-MAC-PE0 G0-MAC-PE1 G0-MAC-PE2 G0-MAC-PE3\n" + "G0-FC-WWPN-P0 G0-FC-WWPN-P1 G0-FC-WWPN-P2 G0-FC-WWPN-P3\n" + "G0-IB-NODE-GUID G0-IB-PORT-GUID G0-FC-WWNN\n" + "G1-MAC-PI0 G1-MAC-PI1 G1-MAC-PI2\n" + "G1-MAC-PE0 G1-MAC-PE1 G1-MAC-PE2 G1-MAC-PE3\n" + "G1-FC-WWPN-P0 G1-FC-WWPN-P1 G1-FC-WWPN-P2 G1-FC-WWPN-P3\n" + "G1-IB-NODE-GUID G1-IB-PORT-GUID G1-FC-WWNN\n" + "IB-SYSTEM-GUID\n" + "Commands affected: burn, sg"); + + AddOptions("blank_guids", + ' ', + "", + "Burn the image with blank GUIDs and MACs (where\n" + "applicable). These values can be set later using\n" + "the \"sg\" command (see details below).\n\n" + "Commands affected: burn"); + + AddOptions("clear_semaphore", + ' ', + "", + "Force clear the flash semaphore on the device.\n" + "No command is allowed when this flag is used.\n" + "NOTE: May result in system instability or flash\n" + "\tcorruption if the device or another\n" + "\tapplication is currently using the flash.\n" + "\tExercise caution.\n"); + + AddOptions("help", + 'h', + "", + "Prints this message and exits"); + + AddOptions("hh", + ' ', + "", + "Prints extended command help"); + + AddOptions("image", + 'i', + "", + "Binary image file.\n" + "Commands affected: burn, verify"); + + AddOptions("qq", + ' ', + "", + "Run a quick query. When specified, flint will not perform full\n" + "image integrity checks during the query operation. This may shorten\n" + "execution time when running over slow interfaces (e.g., I2C, MTUSB-1).\n" + "Commands affected: burn, query"); + + AddOptions("nofs", + ' ', + "", + "Burn image in a non failsafe manner."); + + AddOptions("allow_psid_change", + ' ', + "", + "Allow burning a FW image with a different PSID (Parameter Set ID)than the\n" + "one currently on flash. Note that changing a PSID may cause the device to\n" + "malfunction. Use only if you know what you are doing"); + + AddOptions("allow_rom_change", + ' ', + "", + "Allow burning/removing a ROM to/from FW image when product version is present.\n" + "Use only if you know what you are doing"); + + AddOptions("override_cache_replacement", + ' ', + "", + "On SwitchX/ConnectIB devices:\n" + "Allow accessing the flash even if the cache replacement mode is enabled.\n" + "NOTE: This flag is intended for advanced users only.\n" + "\tRunning in this mode may cause the firmware to hang.\n"); + + AddOptions("no_flash_verify", + ' ', + "", + "Do not verify each write on the flash."); + + AddOptions("silent", + 's', + "", + "Do not print burn progress flyer.\n" + "Commands affected: burn"); + + AddOptions("yes", + 'y', + "", + "Non interactive mode - assume answer\n" + "\"yes\" to all questions.\n" + "Commands affected: all"); + + AddOptions("no", + ' ', + "", + "Non interactive mode - assume answer\n" + "\"no\" to all questions.\n" + "Commands affected: all"); + + AddOptions("vsd", + ' ', + "", + "Write this string, of up to 208 characters, to VSD when burn."); + + AddOptions("use_image_ps", + ' ', + "", + "Burn vsd as appears in the given image - do not keep existing VSD on flash.\n" + "Commands affected: burn"); + + AddOptions("use_image_guids", + ' ', + "", + "Burn (guids/uids/macs) as appears in the given image.\n" + "Commands affected: burn"); + + AddOptions("use_image_rom", + ' ', + "", + "Do not save the ROM which exists in the device.\n" + "Commands affected: burn"); + + AddOptions("dual_image", + ' ', + "", + "Make the burn process burn two images on flash (previously default algorithm). Current" + "default failsafe burn process burns a single image (in alternating locations).\n" + "Commands affected: burn"); + + AddOptions("striped_image", + ' ', + "", + "Use this flag to indicate that the given image file is in a \"striped image\" format.\n" + "Commands affected: query verify"); + + AddOptions("banks", + ' ', + "", + "Set the number of attached flash devices (banks)"); + + AddOptions("log", + ' ', + "", + "Print the burning status to the specified log file"); + + AddOptions("flash_params", + ' ', + "", + "Use the given parameters to access the flash instead of reading them from the flash.\n" + "Supported parameters:\n" + "Type: The type of the flash, such as: M25PXxx, M25Pxx, N25Q0XX, SST25VFxx, W25QxxBV, W25Xxx, AT25DFxxx, S25FLXXXP.\n" + "log2size: The log2 of the flash size." + "num_of_flashes: the number of the flashes connected to the device."); + + AddOptions("version", + 'v', + "", + "Version info."); + + AddOptions("no_devid_check", + ' ', + "", + "ignore device_id checks", true); + + AddOptions("ocr", + ' ', + "", + "another flag for override cache replacement", true); + + + _cmdParser.AddRequester(this); +} + +ParseStatus Flint::HandleOption(string name, string value) +{ + //TODO: consider verifying num of args inside each if statements that needs its arg num verified + // thus we will be able to get rid of the hacks inside the function in the expense of a longer code. + if (!(verifyNumOfArgs(name, value))) + return PARSE_ERROR; + + if (name == "device" || name == "d" ) + { + _flintParams.device_specified = true; + _flintParams.device = value; + } + else if (name == "help" || name == "h") + { + cout<< _cmdParser.GetUsage()<second->getFlagL()+((it->second->getFlagS() == "") ? (" ") : ("|"))+it->second->getFlagS()\ + +" "+it->second->getParam(); + string str2 = ": " + it->second->getDesc()+"\n"; + printf("%-40s %s", str1.c_str(), str2.c_str()); + } + cout<second->getFlagL()+((it->second->getFlagS() == "") ? (" ") : ("|"))+it->second->getFlagS()\ + +" "+it->second->getParam(); + string str2 = ": " + it->second->getDesc()+"\n"; + printf("%-40s %s", str1.c_str(), str2.c_str()); + } + cout<second->getName()<second->getExtDesc()<second->getFlagL()<<\ + ((it->second->getFlagS() == "") ? (" ") : ("|"))+it->second->getFlagS()\ + <<" "<second->getParam()<second->getParamExp()<second->getExample()<::iterator it=_flintParams.user_guids.begin();it != _flintParams.user_guids.end(); it++){ + // printf("%8.8x%8.8x\n",it->h,it->l); + // } + } else if (name == "guids") { + _flintParams.guids_specified = true; + std::vector strs; + splitByDelimiters(strs, value,","); + if (strs.size() != GUIDS) { + return PARSE_ERROR; + } + for (int i=0; i strs; + splitByDelimiters(strs, value,","); + if (strs.size() != MACS) { + return PARSE_ERROR; + } + for (int i=0; i strs; + splitByDelimiters(strs, value,","); + if (strs.size() < BX_ALL_GUIDS) { + return PARSE_ERROR; + } + for (int i = 0; i < BX_ALL_GUIDS; i++) { + guid_t u; + if (!getGUIDFromStr(strs[i], u)){ + return PARSE_ERROR; + }else{ + _flintParams.user_uids.push_back(u); + } + } + } else if (name == "blank_guids") { + _flintParams.blank_guids = true; + } else if (name == "clear_semaphore") { + _flintParams.clear_semaphore = true; + } else if (name == "image" || name == "i") { + _flintParams.image_specified = true; + _flintParams.image = value; + } else if (name == "qq") { + _flintParams.quick_query = true; + } else if (name == "nofs") { + _flintParams.nofs = true; + } else if (name == "allow_psid_change") { + _flintParams.allow_psid_change = true; + } else if (name == "allow_rom_change") { + _flintParams.allow_rom_change = true; + } else if (name == "override_cache_replacement" || name == "ocr") { + _flintParams.override_cache_replacement = true; + } else if (name == "no_flash_verify") { + _flintParams.no_flash_verify = true; + } else if (name == "silent" || name == "s") { + _flintParams.silent = true; + } else if (name == "yes" || name == "y") { + _flintParams.yes = true; + } else if (name == "no") { + _flintParams.no = true; + } else if (name == "vsd") { + _flintParams.vsd_specified = true; + _flintParams.vsd = value; + } else if (name == "use_image_ps") { + _flintParams.use_image_ps = true; + } else if (name == "use_image_guids") { + _flintParams.use_image_guids = true; + } else if (name == "use_image_rom") { + _flintParams.use_image_rom = true; + } else if (name == "dual_image") { + _flintParams.dual_image = true; + } else if (name == "striped_image") { + _flintParams.striped_image = true; + } else if (name == "banks") { + _flintParams.banks_specified = true; + u_int64_t banksNum; + if (!strToNum(value, banksNum)) { + return PARSE_ERROR; + } + _flintParams.banks = (int)banksNum; + } else if (name == "log") { + _flintParams.log_specified = true; + _flintParams.log = value; + } else if (name == "flash_params") { + _flintParams.flash_params_specified = true; + if (!parseFlashParams(value, _flintParams.flash_params)) { + return PARSE_ERROR; + } + //printf("-D- flashType=%s , log2size = %d , numOfBanks = %d\n", _flintParams.flash_params.type_name, _flintParams.flash_params.log2size, _flintParams.flash_params.num_of_flashes); + } else { + cout << "Unknown Flag: " << name; + return PARSE_ERROR; + } + return PARSE_OK; +} + +ParseStatus Flint::parseCmdLine(int argc, char* argv[]) { + //Step1 separate between option section and cmd section + SubCmdMetaData subCmds; + FlagMetaData flags; + char **argvCmd = NULL; + char **argvOpt = NULL; + int argcCmd = 0, argcOpt = 0; + for (int i = (argc - 1); i > 0; i--) { + if ((subCmds.getCmdNum(argv[i])) != SC_No_Cmd) { // i.e we found a subcommand + argcOpt = i; + argvOpt = argv; + argcCmd = argc - i; + argvCmd = &argv[i]; + } + } + if (argcCmd == 0) { + //no subcommand found + argcOpt = argc; + argvOpt = argv; + } + //printf("-D- argcOpt:%d argvOpt:%s argcCmd:%d argvCmd:%s\n", argcOpt, argvOpt[0], argcCmd, argvCmd[0]); + //_cmdparser should deal with the case of no arguments in argv except the program. + //Step2 unite with comma multiple args in the options section + char* newArgv[argcOpt]; + int newArgc = 0; + int i = 1, j = 1, argStart = 1, argEnd = 1; + //first arg is the flint command we can copy as is + newArgv[0] = strcpy(new char[strlen(argvOpt[0]) + 1], argvOpt[0]); + while (i < argcOpt) { + if (argvOpt[i][0] == '-') //its a flag so we copy to new_argv as is + { + newArgv[j] = strcpy(new char[strlen(argvOpt[i]) + 1], + argvOpt[i]); + i++; + j++; + } else //its an argument + { + //find next flag if exsists + argStart = i; + argEnd = i; + int argsSize = 0; + while (argEnd < argcOpt && argvOpt[argEnd][0] != '-') { + argsSize += strlen(argvOpt[argEnd]) + 1; //for the comma + argEnd++; + } + i = argEnd; + //concatenate all the args with comma between them to a single string + newArgv[j] = new char[argsSize + 1]; + newArgv[j][0] = '\0'; + while (argStart < argEnd) { + if (argStart == argEnd - 1) { + //no need to add comma to the last arg + strcat(newArgv[j], argvOpt[argStart]); + } else { + strcat(newArgv[j], argvOpt[argStart]); + strcat(newArgv[j], ","); + } + argStart++; + } + j++; + } + } + newArgc = j; + + //Step3 set the command and its args in the FlintParams struct if present + ParseStatus rc; + if (argcCmd > 0) { + this->_flintParams.cmd = subCmds.getCmdNum(argvCmd[0]); + for (int i = 1; i < argcCmd; ++i) { + this->_flintParams.cmd_params.push_back(string(argvCmd[i])); + } + } else //no command found deal with either missing/invalid command + { + //find last flag + int lastFlagPos; + char* strippedFlag; + for (lastFlagPos = argc - 1; lastFlagPos > 0; lastFlagPos--) { + if (argv[lastFlagPos][0] == '-') + break; + } + if (lastFlagPos == 0) { + cout << FLINT_NO_OPTIONS_FOUND_ERROR << endl; + rc = PARSE_ERROR; + goto clean_up; + } + strippedFlag = stripFlag(argv[lastFlagPos]); + //check how many args it needs + int numOfArgs = flags.getNumOfArgs(strippedFlag); + //if too many args return arg in pos num_of_args+1 as the invalid command. + if ((argc - 1 - lastFlagPos) > numOfArgs) { + printf(FLINT_INVALID_COMMAD_ERROR, argv[argc - 1]); + rc = PARSE_ERROR; + goto clean_up; + } + } + //Step5 parse option section using _cmdParser + rc = this->_cmdParser.ParseOptions(newArgc, newArgv); + // Step 6 Delete allocated memory + clean_up: for (int i = 0; i < newArgc; i++) { + delete[] newArgv[i]; + } + return rc; +} diff --git a/flint/err_msgs.h b/flint/err_msgs.h new file mode 100644 index 0000000..6d2cb61 --- /dev/null +++ b/flint/err_msgs.h @@ -0,0 +1,137 @@ +/* + * + * err_msgs.h - FLash INTerface + * + * Copyright (c) 2013 Mellanox Technologies Ltd. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Version: $Id$ + * + */ + + +#ifndef __ERR_MSGS__ +#define __ERR_MSGS__ + +/********************** + * Flint Status Code + *********************/ + +typedef enum { + FLINT_SUCCESS = 0, + FLINT_FAILED = 1, + FLINT_BURN_ABORTED = 7 +}FlintStatus; + +/*********************** + * Flint Error Messages + **********************/ + +#define FLINT_CLEAR_SEM_CMD_ERROR "No command is allowed when -clear_semaphore flag is given.\n" +#define FLINT_COMMAND_FLAGS_ERROR "For %s command, Please specify %s.\n" +#define FLINT_PARSE_MEM_ERROR "Failed to allocate memory for parsing.\n " +#define FLINT_NO_OPTIONS_FOUND_ERROR "No options found. " +#define FLINT_INVALID_COMMAD_ERROR "Invalid command: %s\n" +#define FLINT_TOO_MANY_ARGS_ERROR "Too many arguments. Expected: %d , Recieved: %d\n" +#define FLINT_TOO_FEW_ARGS_ERROR "Too few arguments. Expected: %d , Recieved: %d\n" +#define FLINT_NO_COMMAND_ERROR "No command found." +#define FLINT_OPEN_FWOPS_DEVICE_ERROR "Cannot open Device: %s. %s\n" +#define FLINT_OPEN_FWOPS_IMAGE_ERROR "Cannot open Image: %s. %s\n" +#define FLINT_DEVICE_AND_IMAGE_ERROR "Please specify either Device or Image.\n" +#define FLINT_NO_DEVICE_ERROR "Please specify Device.\n" +#define FLINT_NO_IMAGE_ERROR "Please specify Image file.\n" +#define FLINT_MISSED_ARG_ERROR "Missed %s parameter after \"%s\" command.\n" +#define FLINT_CMD_ARGS_ERROR "Command \"%s\" requires %d arguments, but %d arguments were given\n" +#define FLINT_CMD_ARGS_ERROR2 "Command \"%s\" requires at most %d arguments, but %d arguments were given\n" +#define FLINT_CMD_ARGS_ERROR3 "Command \"%s\" requires at least %d arguments, but %d arguments were given\n" +#define FLINT_INVALID_OPTION_ERROR "Unknown option \"%s\" for the \"%s\" command. you can use %s.\n" +#define FLINT_INVALID_FLAG_ERROR "Invalid switch \"%s\" is specified.\n" +#define FLINT_INVALID_UID_NUM_BX_ERROR "Number of UIDs on BridgeX should be %d\n" +#define FLINT_BX_BAD_MAC_FORMAT_ERROR "Bad mac ( %4.4x%8.8x ) %s. Please re-burn with a valid MACs value.\n" +#define FLINT_INVALID_FLAG_WITH_FLAG_ERROR "Cannot specify \"%s\" flag with \"%s\" flag.\n" +#define FLINT_INVALID_FLAG_WITH_CMD_ERROR "Cannot specify flag: %s with Command: %s\n" +#define FLINT_CMD_VERIFY_ERROR "FW image verification failed: %s. AN HCA DEVICE CAN NOT BOOT FROM THIS IMAG.\n" +#define FLINT_FAILED_QUERY_ERROR "Failed to query %s: %s.%s\n" +#define FLINT_COMMAND_DEVICE_IMAGE_ERROR "Command \"%s\" requires both image and device to be specified.\n" +#define FLINT_COMMAND_DEVICE_ERROR "Command \"%s\" requires device, but an image file was given.\n" +#define FLINT_COMMAND_IMAGE_ERROR "Command \"%s\" requires an image file, but device was given.\n" +#define FLINT_COMMAND_DEVICE_ERROR2 "Command \"%s\" requires device, but both an image file and a device are given.\n" +#define FLINT_COMMAND_IMAGE_ERROR2 "Command \"%s\" requires an image, but both an image file and a device are given.\n" +#define FLINT_HW_SET_ARGS_ERROR "bad argument of hw set command : %s, it should be in the format PARAM_NAME=VALUE\n" +#define FLINT_HW_COMMAND_ERROR "HW %s failed. %s\n" +#define FLINT_SWRESET_ERROR "Software reset failed. %s\n" +#define FLINT_ERASE_SEC_ERROR "Erase sector failed. %s\n" +#define FLINT_INVALID_ADDR_ERROR "Invalid address \"%s\"\n" +#define FLINT_FLASH_READ_ERROR "Flash read failed. %s\n" +#define FLINT_FLASH_WRITE_ERROR "Flash write failed. %s\n" +#define FLINT_INVALID_DATA_ERROR "Invalid data \"%s\"\n" +#define FLINT_INVALID_SIZE_ERROR "Invalid size \"%s\", Length should be 4-bytes aligned.\n" +#define FLINT_OPEN_FILE_ERROR "Cannot open %s: %s\n" +#define FLINT_WRITE_FILE_ERROR "Failed to write to %s: %s\n" +#define FLINT_IO_OPEN_ERROR "Failed to open %s: %s\n" +#define FLINT_IMAGE_READ_ERROR "Failed to read image. %s\n" +#define FLINT_READ_ERROR "Failed to read from %s. %s\n" +#define FLINT_WIN_NOT_SUPP_ERROR "Command \"%s\" is not supported in windows.\n" +#define FLINT_GEN_COMMAND_ERROR "Failed to execute command %s. %s\n" +#define FLINT_FS3_BB_ERROR "bb command is not supported anymore in FS3 image, please use b for burning FS3 image.\n" +#define FLINT_FS3_BURN_ERROR "Burning FS3 image failed: %s\n" +#define FLINT_FS2_BURN_ERROR "Burning FS2 image failed: %s\n" +#define FLINT_PSID_ERROR "PSID mismatch. The PSID on flash (%s) differs from the PSID in the given image (%s).\n" +#define FLINT_FS2_STRIPED_ERROR "The -striped_image cannot be used with the burn command\n" +#define FLINT_IMG_DEV_COMPAT_ERROR "The given device requires an %s image type, but the given image file does not contain an %s FW image\n" +#define FLINT_UNKNOWN_FW_TYPE_ERROR "Unknown Firmware Type.\n" +#define FLINT_READ_ROM_ERROR "Read ROM failed. %s\n" +#define FLINT_SG_GUID_ERROR "Cannot set GUIDs: %s\n" +#define FLINT_SG_UID_ERROR "Failed to set UID: %s\n" +#define FLINT_MFG_ERROR "Failed to set manufacture guids: %s\n" +#define FLINT_VSD_ERROR "Failed to set the VSD: %s\n" +#define FLINT_VPD_ERROR "Failed to set VPD: %s\n" +#define FLINT_SET_KEY_ERROR "Failed to set the HW access key: %s\n" +#define FLINT_DROM_ERROR "Remove ROM failed: %s\n" +#define FLINT_BROM_ERROR "Burn ROM failed: %s\n" +#define FLINT_DUMP_ERROR "Failed dumping %s : %s\n" +#define FLINT_ROM_QUERY_ERROR "Image file rom (%s) query failed. %s\n" +#define FLINT_WB_FILE_ERROR "failed to open file: %s. %s\n" +#define FLINT_WB_ERROR "write Block Failed. %s\n" + +/************************** + * Flint Warning Messages + *************************/ +#define FLINT_QQ_WARRNING "-W- Running quick query - Skipping full image integrity checks.\n" +#define FLINT_NOT_MLNX_FW_WARNING "-W- Not a Mellanox FW image (vendor_id = 0x%04x). VSD and PSID are not displayed.\n" +#define FLINT_BLANK_GUIDS_WARNING "-W- GUIDs/MACs values and their CRC are not set.\n" +#define FLINT_MULTI_BIT_WARNING "Multicast bit (bit 40) is set." +#define FLINT_MORE_48_BITS_WARNING "More than 48 bits are used." +#define FLINT_BAD_MAC_ADRESS_WARNING "\n-W- Bad mac address ( %4.4x%8.8x ): %s\n" +#define FLINT_MAC_ENTRIES_WARNING "-W- Cannot get MAC address: Expecting %d entries in guid section, got %d. Probably an old FW image. Please update.\n" +#define FLINT_INTERRUPT_WARRNING "\n-W- An internal error occurred. This program cannot be interrupted.\n" +#define FLINT_SET_GUIDS_WARRNING "-W- GUIDs are already set, re-burning image with the new GUIDs ...\n" +#define FLINT_OCR_WARRNING "\n-W- Firmware flash cache access is enabled. Running in this mode may cause the firmware to hang.\n" +#endif diff --git a/flint/flint.cpp b/flint/flint.cpp new file mode 100644 index 0000000..5705a0c --- /dev/null +++ b/flint/flint.cpp @@ -0,0 +1,251 @@ +/* + * + * flint.cpp - FLash INTerface + * + * Copyright (c) 2013 Mellanox Technologies Ltd. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Version: $Id$ + * + */ + + +#include "flint.h" +#include + +//Globals: +Flint* gFlint = NULL; +extern FILE* flint_log_fh; +//signal handler section + +#define BURN_INTERRUPTED 0x1234 + +#ifdef _WIN32 +#include +HANDLE mainThread; + +#define GET_MAIN_THREAD() {\ + int rc = DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(),\ + &mainThread, 0, FALSE, DUPLICATE_SAME_ACCESS);\ + if (rc == 0) {\ + mainThread = NULL;\ + }\ +} + +#define CHECK_WIN_SIGNAL() {\ + if (mainThread == NULL) {\ + printf(FLINT_INTERRUPT_WARRNING);\ + signal(signum, TerminationHandler);\ + return;\ + }\ +} + +#define SUSPEND_MAIN_THREAD() {\ + SuspendThread(mainThread);\ +} + +#else + +#define GET_MAIN_THREAD() +#define WIN_TERM_THREAD() +#define CHECK_WIN_SIGNAL() +#define SUSPEND_MAIN_THREAD() +#endif + + +void TerminationHandler(int signum) +{ + static volatile sig_atomic_t fatal_error_in_progress = 0; + + CHECK_WIN_SIGNAL(); + if (fatal_error_in_progress) { + raise (signum); + } + fatal_error_in_progress = 1; + + signal (signum, SIG_DFL); + write_result_to_log(BURN_INTERRUPTED, ""); + close_log(); + if (gFlint != NULL) { + printf("\n Received signal %d. Cleaning up ...", signum); + fflush(stdout); + SUSPEND_MAIN_THREAD(); + sleep(1); // Legacy from the Old Flint + delete gFlint; + gFlint = NULL; + printf(" Done.\n"); + } + raise(signum); +} + + +void initHandler() +{ +#ifdef __WIN__ +#define SIGNAL_NUM 3 + int signalList[SIGNAL_NUM] = {SIGINT, SIGTERM, SIGABRT}; +#else +#define SIGNAL_NUM 4 + int signalList[SIGNAL_NUM] = {SIGINT, SIGTERM, SIGPIPE, SIGHUP}; +#endif + //set the signal handler + for (int i=0; i < SIGNAL_NUM ; i++) { + void (*prevFunc)(int); + prevFunc = signal(signalList[i],TerminationHandler); + if (prevFunc == SIG_ERR) { + printf("-E- failed to set signal Handler."); + exit(FLINT_FAILED); + } + } + GET_MAIN_THREAD(); +} + +//End of signal handler section. + + +map_sub_cmd_t_to_subcommand Flint::initSubcommandMap() +{ + map_sub_cmd_t_to_subcommand cmdMap; + cmdMap[SC_Burn] = new BurnSubCommand(); + cmdMap[SC_Query] = new QuerySubCommand(); + cmdMap[SC_Verify] = new VerifySubCommand(); + cmdMap[SC_Swreset] = new SwResetSubCommand(); + cmdMap[SC_Brom] = new BromSubCommand(); + cmdMap[SC_Drom] = new DromSubCommand(); + cmdMap[SC_Rrom] = new RromSubCommand(); + cmdMap[SC_Qrom] = new RomQuerySubCommand(); + cmdMap[SC_Bb] = new BbSubCommand(); + cmdMap[SC_Sg] = new SgSubCommand(); + cmdMap[SC_Smg] = new SmgSubCommand(); + cmdMap[SC_Set_Vpd] = new SetVpdSubCommand(); + cmdMap[SC_Sv] = new SvSubCommand(); + cmdMap[SC_Ri] = new RiSubCommand(); + cmdMap[SC_Dc] = new DcSubCommand(); + cmdMap[SC_Dh] = new DhSubCommand(); + cmdMap[SC_Set_Key] = new SetKeySubCommand(); + cmdMap[SC_Hw_Access] = new HwAccessSubCommand(); + cmdMap[SC_Hw] = new HwSubCommand(); + cmdMap[SC_Erase] = new EraseSubCommand(); + cmdMap[SC_Rw] = new RwSubCommand(); + cmdMap[SC_Ww] = new WwSubCommand(); + cmdMap[SC_Wwne] = new WwneSubCommand(); + cmdMap[SC_Wbne] = new WbneSubCommand(); + cmdMap[SC_Wb] = new WbSubCommand(); + cmdMap[SC_Rb] = new RbSubCommand(); + return cmdMap; +} + +void Flint::deInitSubcommandMap(map_sub_cmd_t_to_subcommand cmdMap) +{ + for (map_sub_cmd_t_to_subcommand::iterator it = cmdMap.begin(); it != cmdMap.end(); ++it) + delete it->second; +} + + +Flint::Flint(): + CommandLineRequester(FLINT_DISPLAY_NAME" [OPTIONS] [Parameters]"), + _flintParams(), + _cmdParser(FLINT_DISPLAY_NAME" - Flash Interface"), + _subcommands(initSubcommandMap()) +{ + initCmdParser(); +} + +Flint::~Flint() +{ + deInitSubcommandMap(_subcommands); + if (_flintParams.flash_params.type_name) { + delete[] _flintParams.flash_params.type_name; + } +} + +FlintStatus Flint::run(int argc, char* argv[]) +{ + //Step1 parse input + //There are some memory allocations parseCmdLine + ParseStatus status; + try { + status = this->parseCmdLine(argc, argv);; + } catch (exception& e) { + cout << "-E- " << e.what() << endl; + return FLINT_FAILED; + } + if (status == PARSE_OK_WITH_EXIT) { + return FLINT_SUCCESS; + } else if (status == PARSE_ERROR || status == PARSE_ERROR_SHOW_USAGE) { + if (string(_cmdParser.GetErrDesc()).length() > 0) { + cout << "-E- " << this->_cmdParser.GetErrDesc() << endl; + } + return FLINT_FAILED; + } + + if (_flintParams.cmd == SC_No_Cmd && !_flintParams.clear_semaphore) + { + cout << FLINT_NO_COMMAND_ERROR << endl; + return FLINT_FAILED; + } + if (_flintParams.clear_semaphore) { + if (_flintParams.cmd != SC_No_Cmd) { + printf(FLINT_CLEAR_SEM_CMD_ERROR); + return FLINT_FAILED; + } + _subcommands[SC_Clear_Sem] = new ClearSemSubCommand(); + _flintParams.cmd = SC_Clear_Sem; + } + // Step 2 save argv as a single cmd string in flint params for the log functionallity + for(int i=0; isetParams(_flintParams); + return _subcommands[_flintParams.cmd]->executeCommand(); +} + + +int main(int argc, char* argv[]) +{ + initHandler(); + try + { + gFlint = new Flint(); + FlintStatus rc = gFlint->run(argc, argv); + if (gFlint) { + delete gFlint; + gFlint = NULL; + } + return rc; + } + catch (std::exception& e) + { + cout<<"-E- "< +#include "flint_params.h" +#include "subcommands.h" +#include +#include "err_msgs.h" + +using namespace std; + +typedef map map_sub_cmd_t_to_subcommand; +typedef map map_string_to_string; +typedef map map_string_to_int; + +map_string_to_string initShortToLongFlagMap(); +map_string_to_int initLongFlagToNumOfArgsMap(); +void deInitSubcommandMap(map_sub_cmd_t_to_subcommand cmdMap); +map_sub_cmd_t_to_subcommand initSubcommandMap(); + +class Flint : public CommandLineRequester +{ +private: + FlintParams _flintParams; + CommandLineParser _cmdParser; + map_sub_cmd_t_to_subcommand _subcommands; + + //methods + map_sub_cmd_t_to_subcommand initSubcommandMap(); + void deInitSubcommandMap(map_sub_cmd_t_to_subcommand cmdMap); + +public: + Flint(); + ~Flint(); + void initCmdParser(); + virtual ParseStatus HandleOption(string name, string value); + ParseStatus parseCmdLine(int argc, char* argv[]); + FlintStatus run(int argc, char* argv[]); +}; +#endif diff --git a/flint/flint_params.cpp b/flint/flint_params.cpp new file mode 100644 index 0000000..abaf152 --- /dev/null +++ b/flint/flint_params.cpp @@ -0,0 +1,83 @@ +/* + * + * flint_params.cpp - FLash INTerface + * + * Copyright (c) 2013 Mellanox Technologies Ltd. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Version: $Id$ + * + */ + +#include "flint_params.h" + +FlintParams::FlintParams() +{ + help = false; + version = false; + extended_help = false; + guids_specified = false; + guid_specified = false; + mac_specified = false; + macs_specified = false; + uid_specified = false; + uids_specified = false; + device_specified = false; + blank_guids = false; + clear_semaphore = false; + quick_query = true; //should now be true by default + image_specified = false; + nofs = false; + allow_psid_change = false; + allow_rom_change = false; + override_cache_replacement = false; + no_flash_verify = false; + silent = false; + yes = false; + no = false; + vsd_specified = false; + use_image_ps = false; + use_image_guids = false; + use_image_rom = false; + dual_image = false; + striped_image = false; + banks_specified = false; + banks = 4; + log_specified = false; + flash_params_specified = false; + flash_params.type_name = (char*)NULL; + no_devid_check = false; + cmd = SC_No_Cmd; +} + +FlintParams::~FlintParams() +{ + +} diff --git a/flint/flint_params.h b/flint/flint_params.h new file mode 100644 index 0000000..0cffc50 --- /dev/null +++ b/flint/flint_params.h @@ -0,0 +1,132 @@ +/* + * + * flint_params.h - FLash INTerface + * + * Copyright (c) 2013 Mellanox Technologies Ltd. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Version: $Id$ + * + */ + +#ifndef __FLINTPARAMS__ +#define __FLINTPARAMS__ + +#include +#include +#include "mlxfwops/lib/mlxfwops_com.h" +#include "mflash/mflash.h" + +using namespace std; + +typedef enum { + SC_No_Cmd = 0, + SC_Burn, + SC_Query, + SC_Verify, + SC_Swreset, + SC_Brom, + SC_Drom, + SC_Rrom, + SC_Bb, + SC_Sg, + SC_Smg, + SC_Set_Vpd, + SC_Sv, + SC_Ri, + SC_Dc, + SC_Dh, + SC_Set_Key, + SC_Hw_Access, + SC_Hw, + SC_Erase, + SC_Rw, + SC_Ww, + SC_Wwne, + SC_Wbne, + SC_Wb, + SC_Rb, + SC_Clear_Sem, + SC_Qrom +} sub_cmd_t; + +class FlintParams { +public: + //add more params + FlintParams(); + ~FlintParams(); + bool device_specified; + string device; + bool guids_specified; + bool guid_specified; + std::vector user_guids; + bool mac_specified; + bool macs_specified; + std::vector user_macs; + bool uid_specified; + bool uids_specified; + guid_t baseUid; + std::vector user_uids; + bool help; + bool version; + bool extended_help; + bool blank_guids; + bool clear_semaphore; + bool quick_query; + bool image_specified; + string image; + bool nofs; + bool allow_psid_change; + bool allow_rom_change; + bool override_cache_replacement; + bool no_flash_verify; + bool silent; + bool yes; + bool no; + bool vsd_specified; + string vsd; + bool use_image_ps; + bool use_image_guids; + bool use_image_rom; + bool dual_image; + bool striped_image; + bool banks_specified; + int banks; + bool log_specified; + string log; + bool flash_params_specified; + flash_params_t flash_params; + bool no_devid_check; + sub_cmd_t cmd; + vector cmd_params; + string fullCmd; +}; + +#endif diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp new file mode 100644 index 0000000..12f092d --- /dev/null +++ b/flint/subcommands.cpp @@ -0,0 +1,3717 @@ +/* + * + * subcommands.cpp - FLash INTerface + * + * Copyright (c) 2013 Mellanox Technologies Ltd. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met:FwVerify + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Version: $Id$ + * + */ + +#include "subcommands.h" +#include +#include + +using namespace std; + +#define INDENT "\t\t\t\t\t " +#define INDENTEX "\t" + +// The Log file writing implementation + +//global log file header +FILE* flint_log_fh = NULL; + +#define BURN_INTERRUPTED 0x1234 + +void close_log() +{ + if (flint_log_fh != NULL) { + fclose(flint_log_fh); + flint_log_fh = NULL; + } + return; +} + +#define ARR_SIZE(arr) sizeof(arr)/sizeof(arr[0]) + +const char* month_2monstr (int month) { + static const char* month_2monstr_arr[] = { + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", + }; + int arr_size = (int)ARR_SIZE(month_2monstr_arr); + return month < arr_size ? month_2monstr_arr[month] : "???"; +} + +void print_time_to_log() +{ + time_t rawtime; + struct tm * timeinfo; + + if (flint_log_fh == NULL) { + return; + } + time ( &rawtime ); + timeinfo = localtime ( &rawtime ); + + fprintf(flint_log_fh, "%-3s %2d %02d:%02d:%02d ", month_2monstr(timeinfo->tm_mon), timeinfo->tm_mday, + timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); + return; +} + +int print_line_to_log(const char* format, ...) +{ + va_list args; + if (flint_log_fh == NULL) { + return 0; + } + print_time_to_log(); + va_start(args, format); + vfprintf(flint_log_fh, format, args); + va_end(args); + return 0; +} + +int write_cmd_to_log(string fullCmd , sub_cmd_t cmd, bool write) +{ + if (!write) { + return 0; + } + char pre_str[50]; + if (flint_log_fh == NULL) { + return 0; + } + if (cmd == SC_Brom) { + sprintf(pre_str, "ROM"); + } else { + sprintf(pre_str, "FW"); + } + print_time_to_log(); + fprintf(flint_log_fh, "Start %s burning: ", pre_str); + fprintf(flint_log_fh, "%s ", fullCmd.c_str()); + fprintf(flint_log_fh, "\n"); + return 0; +} + +int write_result_to_log(int is_failed, const char* err_msg, bool write) +{ + if (!write) { + return 0; + } + char msg[MAX_ERR_STR_LEN]; + strcpy(msg, err_msg); + if (is_failed == 0) { + print_line_to_log("Burn completed successfully\n"); + } else if (is_failed == BURN_INTERRUPTED) { + print_line_to_log("Burn interrupted by user\n"); + } else { + int msg_len = strlen(msg); + // cleanup the msg + for (int i = 0; i < msg_len; i++) { + if (msg[i] == '\n') { + if (i == msg_len - 1) { + msg[i] = '\0'; + } else { + msg[i] = ' '; + } + } + } + print_line_to_log("Burn failed: %s\n", msg); + } + return 0; +} +/******************* + * Class: Subcommand + ******************/ + + +#define MAX_ERR_STR_LEN 1024 +#define PRE_ERR_MSG "-E-" + +bool SubCommand::isCmdSupportLog() { + // a subcommand supports Logging if: A & B where: + // A. it is either Burn, Burn Block or Burn ROM. + // B. log flag was given in the cmd line. + + switch (_cmdType) { + case SC_Burn: + case SC_Bb: + case SC_Brom: + return _flintParams.log_specified; + default: + return false; + } + return false; +} + +void SubCommand::reportErr(bool shouldPrint, const char *format, ...) +{ + va_list args; + + va_start(args, format); + + if (vsnprintf(_errBuff, FLINT_ERR_LEN, format, args) >= FLINT_ERR_LEN) { + strcpy(&_errBuff[FLINT_ERR_LEN - 5], "...\n"); + } + //print to the user and to the log if needed + if (shouldPrint) { + fprintf(stdout,PRE_ERR_MSG" %s",_errBuff); + } + write_result_to_log(FLINT_FAILED,_errBuff, isCmdSupportLog()); + va_end(args); + + return; +} + +bool SubCommand::writeToFile(string filePath, const std::vector& buff) { + FILE* fh; + if ((fh = fopen(filePath.c_str(), "wb")) == NULL) { + reportErr(true, FLINT_OPEN_FILE_ERROR, filePath.c_str(), strerror(errno)); + return false; + } + // Write + if (fwrite(&buff[0], 1, buff.size(), fh) != buff.size()) { + fclose(fh); + reportErr(true, FLINT_WRITE_FILE_ERROR, filePath.c_str(), strerror(errno)); + return false; + } + fclose(fh); + return true; +} + +void SubCommand::openLog() +{ + if (isCmdSupportLog()) { + flint_log_fh = fopen(_flintParams.log.c_str(), "a+"); + if (flint_log_fh == NULL) { + printf("-W- Failed to open log file \"%s\": %s. No logs will be saved\n", _flintParams.log.c_str() + , strerror(errno)); + } + write_cmd_to_log(_flintParams.fullCmd, _flintParams.cmd, _flintParams.log_specified); + } +} + +int SubCommand::verifyCbFunc(char* str) +{ + printf("%s", str); + return 0; +} + +int SubCommand::CbCommon(int completion, char*preStr, char* endStr) +{ + if (completion < 100) { + printf("\r%s%%%03d", preStr, completion); + }else if (completion == 100) { + printf("\r%sOK \n", preStr); + } else {// printing endStr + if (endStr){ + printf("\r%s\n", endStr); + } + } + fflush(stdout); + return 0; +} + +// HACK: the endStr is printed when we reach 101% this is for backward compat with the original flint +// output. thus in subcommands that use these callbacks you will see we manually call them at the end with the 101 arg + +int SubCommand::burnCbFs3Func(int completion) +{ + char* message = "Burning FS3 FW image without signatures - "; + char* endStr = "Restoring signature - OK"; + return CbCommon(completion, message, endStr); +} + +int SubCommand::burnCbFs2Func(int completion) +{ + char* message = "Burning FS2 FW image without signatures - "; + char* endStr = "Restoring signature - OK"; + return CbCommon(completion, message, endStr); +} + +int SubCommand::bromCbFunc(int completion) +{ + char* message = "Burning ROM image - "; + char* endStr = "Restoring signature - OK"; + return CbCommon(completion, message, endStr); +} + +int SubCommand::dromCbFunc(int completion) +{ + char* message = "Removing ROM image - "; + char* endStr = "Restoring signature - OK"; + return CbCommon(completion, message, endStr); +} + +int SubCommand::burnBCbFunc(int completion) +{ + return CbCommon(completion,""); +} + +int SubCommand::vsdCbFunc(int completion) +{ + char* message = "Setting the VSD - "; + char* endStr = "Restoring signature - OK"; + return CbCommon(completion, message, endStr); +} + +int SubCommand::setKeyCbFunc(int completion) +{ + char* message = "Setting the HW Key - "; + char* endStr = "Restoring signature - OK"; + return CbCommon(completion, message, endStr); +} + +int SubCommand::wbCbFunc(int completion) +{ + char* message = "Writing Block: - "; + return CbCommon(completion, message, NULL); +} + +#define ERR_BUFF_SIZE 1024 +FlintStatus SubCommand:: openOps() +{ + char errBuff[ERR_BUFF_SIZE]; + errBuff[0] = '\0'; + if (_flintParams.device_specified) { + // fillup the fw_ops_params_t struct + FwOperations::fw_ops_params_t fwParams; + fwParams.errBuff = errBuff; + fwParams.errBuffSize = ERR_BUFF_SIZE; + fwParams.flashParams =_flintParams.flash_params_specified ? &_flintParams.flash_params : NULL; + fwParams.forceLock = _flintParams.clear_semaphore; + fwParams.hndlType = FHT_MST_DEV; + fwParams.ignoreCacheRep = _flintParams.override_cache_replacement ? 1 : 0; + fwParams.mstHndl = strcpy(new char[_flintParams.device.length()+1],_flintParams.device.c_str()); + fwParams.numOfBanks = _flintParams.banks; + fwParams.readOnly = false; + fwParams.noFlashVerify = _flintParams.no_flash_verify; + _fwOps = FwOperations::FwOperationsCreate(fwParams); + delete[] fwParams.mstHndl; + } + if (_flintParams.image_specified) { + _imgOps = FwOperations::FwOperationsCreate((void*)_flintParams.image.c_str(), NULL, NULL,\ + FHT_FW_FILE, errBuff, 1024); + } + if (_flintParams.device_specified && _fwOps == NULL) + { + reportErr(true, FLINT_OPEN_FWOPS_DEVICE_ERROR, _flintParams.device.c_str(), strlen(errBuff) != 0 ? errBuff : ""); + return FLINT_FAILED; + } + if (_flintParams.image_specified && _imgOps == NULL) + { + reportErr(true, FLINT_OPEN_FWOPS_IMAGE_ERROR, _flintParams.image.c_str(), strlen(errBuff) != 0 ? errBuff : ""); + return FLINT_FAILED; + } + return FLINT_SUCCESS; +} + + + +FlintStatus SubCommand:: openIo() +{ + //TODO: consider adding a parameter for when image/device will be opened as "readOnly" in the open routine. + if (_flintParams.device_specified && _flintParams.image_specified) { + //should not arrive here as we verify params at each subcommand. + reportErr(true, FLINT_DEVICE_AND_IMAGE_ERROR); + return FLINT_FAILED; + } + if (_flintParams.device_specified) { + _io = new Flash; + if (!((Flash*)_io)->open(_flintParams.device.c_str(), _flintParams.clear_semaphore, false, _flintParams.banks, \ + NULL, _flintParams.override_cache_replacement)) { + // if we have Hw_Access command we dont fail straght away + if (_flintParams.cmd == SC_Hw_Access && ((Flash*)_io)->get_cr_space_locked()) { + return FLINT_SUCCESS; + } + reportErr(true, FLINT_IO_OPEN_ERROR, "Device", (_io)->err()); + delete _io; + _io = NULL; + return FLINT_FAILED; + } + // we have successfully opened a Flash Obj + // set no_flash_verify if needed + ((Flash*)_io)->set_no_flash_verify(_flintParams.no_flash_verify); + } else if (_flintParams.image_specified) { + _io = new FImage; + if (!((FImage*)_io)->open(_flintParams.image.c_str())) { + reportErr(true, FLINT_IO_OPEN_ERROR, "Image", (_io)->err()); + delete _io; + _io = NULL; + return FLINT_FAILED; + } + } + return FLINT_SUCCESS; +} + +bool SubCommand::basicVerifyParams() +{ + if (!_flintParams.log_specified) { + char* logFile; + logFile = getenv(FLINT_LOG_ENV); + if (logFile) { + _flintParams.log = logFile; + _flintParams.log_specified = true; + } + } + //open log if needed + openLog(); + switch (_v) { + case Wtv_Img: + if ( _flintParams.device_specified == true) { + _flintParams.image_specified ? reportErr(true, FLINT_COMMAND_IMAGE_ERROR2,_name.c_str()) : + reportErr(true, FLINT_COMMAND_IMAGE_ERROR, _name.c_str()); + return false; + } + if ( _flintParams.image_specified == false ) { + reportErr(true, FLINT_NO_IMAGE_ERROR); + return false; + } + break; + case Wtv_Dev: + if ( _flintParams.image_specified == true) { + _flintParams.device_specified ? reportErr(true, FLINT_COMMAND_DEVICE_ERROR2,_name.c_str()) : + reportErr(true, FLINT_COMMAND_DEVICE_ERROR, _name.c_str()); + return false; + } + if ( _flintParams.device_specified == false ) { + reportErr(true, FLINT_NO_DEVICE_ERROR); + return false; + } + break; + case Wtv_Dev_And_Img: + if (( _flintParams.image_specified == false) || ( _flintParams.device_specified == false)) { + reportErr(true, FLINT_COMMAND_DEVICE_IMAGE_ERROR, _name.c_str()); + return false; + } + break; + case Wtv_Dev_Or_Img: + if ( _flintParams.image_specified == true && _flintParams.device_specified == true) { + reportErr(true, FLINT_DEVICE_AND_IMAGE_ERROR); + return false; + } + if ( _flintParams.device_specified == false && _flintParams.image_specified == false ) { + reportErr(true, FLINT_DEVICE_AND_IMAGE_ERROR); + return false; + } + break; + default: + reportErr(true, "Failed to verify parms(internal error)."); + return false; + } + + if (_flintParams.device_specified && _flintParams.striped_image) { + reportErr(true, FLINT_INVALID_FLAG_WITH_FLAG_ERROR, "-device", "-striped_image"); + return false; + } + + if (_flintParams.override_cache_replacement) { + printf(FLINT_OCR_WARRNING); + } + return true; +} + +FlintStatus SubCommand::preFwOps() +{ + if (!basicVerifyParams()) { + return FLINT_FAILED; + } + if (!verifyParams()) { + return FLINT_FAILED; + } + return openOps(); +} + +FlintStatus SubCommand::preFwAccess() +{ + if (!basicVerifyParams()) { + return FLINT_FAILED; + } + if (!verifyParams()) { + return FLINT_FAILED; + } + return openIo(); +} + +SubCommand::~SubCommand() +{ + if (_fwOps != NULL) { + _fwOps->FwCleanUp(); + delete _fwOps; + } + if (_imgOps != NULL) { + _imgOps->FwCleanUp(); + delete _imgOps; + } + if (_io != NULL) { + _io->close(); + delete _io; + } + + +} + +bool SubCommand::getRomsInfo(FBase* io, roms_info_t& romsInfo) +{ + std::vector romSector; + romSector.clear(); + romSector.resize(io->get_size()); + if (!io->read(0, &romSector[0], io->get_size())) { + reportErr(true, FLINT_READ_ERROR,_flintParams.image.c_str(), io->err()); + return false; + } + FwOperations::RomInfo info(romSector, false); + info.ParseInfo(); + info.initRomsInfo(&romsInfo); + return true; +} + +bool SubCommand::getGUIDFromStr(string str, guid_t& guid, string prefixErr) +{ + char* endp; + u_int64_t g; + g = strtoull(str.c_str(), &endp, 16); + if (*endp || (g == 0xffffffffffffffffULL && errno == ERANGE)) { + if (prefixErr.size() == 0) { + reportErr(true, "Invalid GUID syntax (%s) %s \n", str.c_str(), errno ? strerror(errno) : "" ); + } else { + reportErr(true, "%s\n", prefixErr.c_str()); + } + return false; + } + guid.h = (u_int32_t)(g >> 32); + guid.l = (u_int32_t)(g & 0xffffffff); + return true; +} + + +#if !defined(__WIN__) && !defined(__DJGPP__) +static int mygetch(void) +{ + struct termios oldt, + newt; + int ch; + tcgetattr( STDIN_FILENO, &oldt ); + newt = oldt; + newt.c_lflag &= ~( ICANON | ECHO ); + tcsetattr( STDIN_FILENO, TCSANOW, &newt ); + ch = getchar(); + tcsetattr( STDIN_FILENO, TCSANOW, &oldt ); + return ch; +} + +bool SubCommand::getPasswordFromUser(char *preStr, char buffer[MAX_PASSWORD_LEN]) +{ + char c; + int pos = 0; + + printf("%s: ", preStr); + do { + c = mygetch(); + + if( ((pos < MAX_PASSWORD_LEN - 1)) && isprint(c) ) { + buffer[ pos++ ] = c; + printf("%c", '*'); + } else if( (c == 8 || c == 127) && pos ) { + buffer[ pos-- ] = '\0'; + printf("%s", "\b \b"); + } + + + } while( c != '\n' ); + printf("\n"); + buffer[pos] = '\0'; + return true; +} + +#else +bool SubCommand::getPasswordFromUser(char *preStr, char buffer[MAX_PASSWORD_LEN]) +{ + //TODO: Buffer Overflow danger use loop with gets() or istream + printf("%s: ", preStr); + scanf("%s", buffer); + return true; +} + +#endif + +// +// Asks user a yes/no question. +// Returns true if user chose Y, false if user chose N. +// + +bool SubCommand::askUser(const char *question, bool printAbrtMsg) { + if (question == NULL) { + printf("\n Do you want to continue ? (y/n) [n] : "); + } else { + printf("\n %s ? (y/n) [n] : ", question); + + } + + if (_flintParams.yes) + printf("y\n"); + else { + char ansbuff[32]; + ansbuff[0] = '\0'; + if (_flintParams.no) { + printf("n\n"); + reportErr(false, "-no flag is set\n"); + return false; + } + /*for future tracer dev + * + if (_ignore_tty == false) { + if (!isatty(0)) { + sprintf(_err_msg, "Not on tty - Can not interact. assuming \"no\"\n"); + return false; + } + } + */ + fflush(stdout); + fgets(ansbuff, 30, stdin); + + if ( strcmp(ansbuff, "y\n") && + strcmp(ansbuff, "Y\n") && + strcmp(ansbuff, "yes\n") && + strcmp(ansbuff, "Yes\n") && + strcmp(ansbuff, "YES\n")) { + + if (printAbrtMsg) { + reportErr(true, "Aborted by user\n"); + } + return false; + } + + } + return true; +} + +void SubCommand::displayOneExpRomInfo(const rom_info_t& info) { + + if (info.exp_rom_product_id == 0xf) {// version id in this case is the freeStr that was moved to exp_rom_ver[0] in mlxfwops + printf("devid=%d version_id=%d", info.exp_rom_dev_id,info.exp_rom_ver[0]); + } else { + printf("type="); + switch (info.exp_rom_product_id) { + case 1: + printf("CLP1 "); + break; + case 2: + printf("CLP2 "); + break; + case 3: + printf("CLP3 "); + break; + case 4: + printf("CLP4 "); + break; + case 0x10: + printf("PXE "); + break; + case 0x11: + printf("UEFI "); + break; + case 0x21: + printf("FCODE "); + break; + + default: + printf("0x%x - Unknown ROM product ID\n", info.exp_rom_product_id); + return; + } + + printf("version=%d", info.exp_rom_ver[0]); + if (info.exp_rom_product_id >= 0x10) { + printf(".%d.%d", info.exp_rom_ver[1], info.exp_rom_ver[2]); + + if (info.exp_rom_dev_id != EXP_ROM_GEN_DEVID) { + // Do not display if 0 - ROM is the same for all device IDs + printf(" devid=%d", info.exp_rom_dev_id); + } + if (info.exp_rom_port) { + // Do not display if 0 - port independent + printf(" port=%d", info.exp_rom_port); + } + + printf(" proto="); + switch (info.exp_rom_proto) { + case ER_IB: + printf("IB"); + break; + case ER_ETH: + printf("ETH"); + break; + case ER_VPI: + printf("VPI"); + break; + default: + printf("0x%x", info.exp_rom_proto); + } + } + } + return; +} + + +void SubCommand::displayExpRomInfo(const roms_info_t& romsInfo, char *preStr) +{ + int i; + int strLen = strlen(preStr); + + if (romsInfo.num_of_exp_rom > 0) { + for (i = 0; i < romsInfo.num_of_exp_rom; i++) { + // Print the pre string or spaces + if (i == 0) { + printf("%s", preStr); + } else { + int j; + for ( j = 0; j < strLen; j++) { + printf("%s", " "); + } + } + // Display a ROM info + displayOneExpRomInfo(romsInfo.rom_info[i]); + if (i != romsInfo.num_of_exp_rom - 1) { // Don't print new line after the info of the last ROM + printf("\n"); + } + } + if (romsInfo.exp_rom_warning) { + printf(" (-W- %s)", romsInfo.exp_rom_warning_msg); + } + printf("\n"); + } else { + printf("%s", preStr); + printf("N/A"); + if (romsInfo.exp_rom_err_msg_valid) { + printf(" (-E- %s)", romsInfo.exp_rom_err_msg); + } + printf("\n"); + } + return; +} + +/*TODO: this function was ported to mlxfwops needs to be removed. + * +void SubCommand::setDevFlags(const fw_info_t& info, bool& ib_dev, bool& eth_dev) { + + if (info.fw_info.chip_type == CT_IS4) { + ib_dev = true; + eth_dev = false; + } else if (info.fw_info.chip_type == CT_SWITCHX) { + ib_dev = true; + eth_dev = true; + } else { + ib_dev = (info.fw_type == FIT_FS3) || !_fwOps->CntxEthOnly(info.fw_info.dev_type); + eth_dev = (info.fw_type == FIT_FS2) && info.fw_info.chip_type == CT_CONNECTX; + } + + if ((!ib_dev && !eth_dev) || info.fw_info.chip_type == CT_UNKNOWN) { + // Unknown device id - for forward compat - assume that ConnectX is MP and + // prev HCAs are IB only (these flags are for printing only - no real harm can be done). + // TODO: FS2 does not mean ConnectX now. + ib_dev = true; + if (info.fw_type == FIT_FS2) { + eth_dev = true; + } else { + eth_dev = false; + } + } +} +*/ + +bool SubCommand::printGuidLine(guid_t* new_guids, guid_t* old_guids, int guid_index) +{ + printf(GUID_FORMAT GUID_SPACES, new_guids[guid_index].h, new_guids[guid_index].l); + if (old_guids != NULL) { + printf(GUID_FORMAT, old_guids[guid_index].h, old_guids[guid_index].l); + }else { + printf(" N/A"); + } + printf("\n"); + return true; +} + +bool SubCommand::printBxGuids(guid_t* new_guids, guid_t* old_guids, int index, int num_of_guids, const char* pre_str) +{ + int guid_index = index; + int _is_wwpn = ((guid_index - BI_WWPNS) % BX_SLICE_GUIDS); + + for (int i = 0; i < num_of_guids; i++) { + printf(" G%d", (index >= BX_SLICE_GUIDS)); + if (i == 0 && _is_wwpn) { + printf(" Node %s: ", pre_str); + } else { + int j = _is_wwpn ? i : i + 1; + printf(" Port%d %s: ", j, pre_str); + } + printGuidLine(new_guids, old_guids, guid_index); + guid_index++; + } + return true; +} + +bool SubCommand::printMacLine(guid_t* new_guids, guid_t* old_guids, int mac_index) +{ + printf(" "MAC_FORMAT MAC_SPACES, new_guids[mac_index].h, new_guids[mac_index].l); + if (old_guids != NULL) { + printf(MAC_FORMAT, old_guids[mac_index].h, old_guids[mac_index].l); + } else { + printf(" N/A"); + } + printf("\n"); + return true; +} + +bool SubCommand::printBxMacs(guid_t* new_guids, guid_t* old_guids, int index, int num_of_guids, const char* pre_str) +{ + int guid_index = index; + + for (int i = 0; i < num_of_guids; i++) { + printf(" G%d", (index >= BX_SLICE_GUIDS)); + printf(" Port%d %s: ", i + 1, pre_str); + printMacLine(new_guids, old_guids, guid_index); + guid_index++; + } + return true; +} + +bool SubCommand::printUidsFunc(guid_t* new_guids, guid_t* old_guids) +{ + int base_index = 0, guid_index; + + for (int i = 0; i < BX_SLICES_NUM; i++) { + base_index = i * BX_SLICE_GUIDS; + // Init Guids + printBxGuids(new_guids, old_guids, base_index + BI_GUIDS, BX_NP_GUIDS, "Guid"); + printBxMacs (new_guids, old_guids, base_index + BI_IMACS, BX_IMACS, "IMAC"); + printBxMacs (new_guids, old_guids, base_index + BI_EMACS, BX_EMACS, "EMAC"); + printBxGuids(new_guids, old_guids, base_index + BI_WWNNS, BX_WWNNS, "WWNN"); + printBxGuids(new_guids, old_guids, base_index + BI_WWPNS, BX_WWPNS, "WWPN"); + } + + // Init SysGuid + //INCR_GUID(base_guid1, user_guids[Operations::BI_SYS_GUID], 7); + guid_index = BI_SYS_GUID; + printf(" System GUID: "); + printGuidLine(new_guids, old_guids, guid_index); + return true; +} + +bool SubCommand::printGUIDsFunc(guid_t guids[GUIDS],guid_t macs[MACS], guid_t old_guids[GUIDS],\ + guid_t old_macs[MACS], bool print_guids, bool print_macs, int portNum, bool old_guid_fmt) { + + if (print_guids) { + printf(" Node GUID: "); + printGuidLine(guids,old_guids, 0); + if (portNum > 0) { + printf(" Port1 GUID: "); + printGuidLine(guids,old_guids, 1); + } + if (portNum > 1) { + printf(" Port2 GUID: "); + printGuidLine(guids,old_guids, 2); + } + if (!old_guid_fmt) { + printf(" Sys.Image GUID: "); + printGuidLine(guids,old_guids, 3); + } + } + + if (print_macs) { + printf(" Port1 MAC: "); + printMacLine(macs, old_macs, 0); + printf(" Port2 MAC: "); + printMacLine(macs, old_macs, 1); + } + return true; +} + +bool SubCommand::reportGuidChanges(guid_t* new_guids, guid_t* new_macs,\ + guid_t* old_guids, guid_t* old_macs, bool printGuids,\ + bool printMacs, bool printUids, int guidNum) +{ + //should be used ONLY on FS2 in current implementation + + printf(" You are about to change the Guids/Macs/Uids on the device:\n\n"); + printf(" New Values " GUID_SPACES "Current Values\n"); + if (printUids) { + printUidsFunc(new_guids, old_guids ); + } else { + printGUIDsFunc(new_guids, new_macs, + old_guids, old_macs, + printGuids, + printMacs, + guidNum, + guidNum < GUIDS); + } + if (!askUser()) + return false; + + return true; +} + +bool SubCommand::fwVerLessThan(const u_int16_t r1[3], const u_int16_t r2[3]) +{ + for (int i = 0; i < 3 ; i++) { + if (r1[i] < r2[i]) { + return true; + } + else if (r1[i] > r2[i]) { + return false; + } + } + return false; // equal versions +} + +//used for dc and dh subcommands + +bool SubCommand::unzipDataFile (std::vector data, std::vector &newData, const char *sectionName) +{ +#ifndef NO_ZLIB + int rc; + if (data.empty()) { + reportErr(true, "%s section not found in the given image.", sectionName); + return false; + } + // restore endianess. + TOCPUn(&(data[0]), data.size()/4); + + // uncompress: + uLongf destLen = data.size(); + destLen *= 40; // Assuming this is the best compression ratio + vector dest(destLen); + + for (int i = 0; i < 32; i++) { + rc = uncompress((Bytef *)&(dest[0]), &destLen, + (const Bytef *)&(data[0]), data.size()); + if (rc != Z_BUF_ERROR) { + break; + } + destLen *= 2; + dest.resize(destLen); + } + + if (rc != Z_OK) { + reportErr(true, "Failed uncompressing FW configuration section. uncompress returns %d", rc); + return false; + } + // printf("%s", (char*)&(dest[0])); + + newData = dest; + newData[destLen] = 0; // Terminating NULL + newData.resize(destLen + 1); + return true; +#else + reportErr(true, "Executable was compiled with \"dump files\" option disabled."); + return false; +#endif +} + +bool SubCommand::dumpFile(const char* confFile, std::vector& data, const char *sectionName) { + FILE* out; + vector dest; + + if (confFile == NULL) { + out = stdout; + } else { + out = fopen(confFile, "w"); + + if (out == NULL) { + reportErr(true, "Can not open file %s for write: %s.", confFile, strerror(errno)); + return false; + } + } + if (unzipDataFile(data, dest, sectionName) == false) { + return false; + } + fprintf(out, "%s", (char*)&(dest[0])); + + if (confFile != NULL) { + fclose(out); + } + return true; +} + +bool SubCommand::checkGuidsFlags (chip_type_t ct, u_int16_t devType, u_int8_t fwType, + bool guidsSpecified, bool macsSpecified, bool uidsSpecified) { + + if (guidsSpecified || macsSpecified || uidsSpecified) { + if (ct == CT_BRIDGEX) { + if (macsSpecified || guidsSpecified) { + reportErr(true, "-mac(s)/-guid(s) flags is not applicable for MT%d.\n",devType); + return false; + } + } else { + if (uidsSpecified) { + reportErr(true, "-uid(s) flag is applicable only for BridgeX and FS3 FW.\n"); + return false; + } else if (fwType != FIT_FS2 && macsSpecified ) { + reportErr(true, "-mac(s) flag is not applicable for IB MT%d device.\n", devType); + return false; + }// else if (!_fwOps->CntxEthOnly() && guids_specified) { + // return errmsg("-guid(s) flag is not applicable for IB MT%d device.\n", + // devType); + //} + } + } + return true; +} + +void SubCommand::printMissingGuidErr(bool ibDev, bool ethDev, bool bxDev) +{ + const char* missingInfo; + const char* missingFlags; + + if (bxDev) { + missingInfo = "UIDs (GUIDs / MACs / WWNs)"; + missingFlags = "-uid(s)"; + } else { + if (ibDev && ethDev) { + missingInfo = "GUIDs / MACs"; + missingFlags = "-guid(s) / -mac(s)"; + } else if (ibDev) { + missingInfo = "GUIDs"; + missingFlags = "-guid(s)"; + } else { + missingInfo = "MACs"; + missingFlags = "-mac(s)"; + } + + } + printf("Please specify %s (using command line flags %s ).\n", missingInfo, missingFlags); + return; +} + +/*********************** + *Class: BurnSubCommand + **********************/ + +BurnSubCommand:: BurnSubCommand() +{ + _name = "burn"; + _desc = "Burn flash"; + _extendedDesc = "Burn flash \n" + INDENTEX"Performs failsafe FW update from a raw binary image."; + _flagLong = "burn"; + _flagShort = "b"; + _param = ""; + _paramExp = "None"; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" -i image1.bin burn\n" + INDENTEX FLINT_NAME" -d "MST_DEV_EXAMPLE2" -guid 0x2c9000100d050 -i image1.bin b"; + _v = Wtv_Dev_And_Img; + _cmdType = SC_Burn; +} + +BurnSubCommand:: ~BurnSubCommand() +{ + closeLog(); + if (_burnParams.userVsd != NULL) { + delete[] _burnParams.userVsd; + } +} + +bool BurnSubCommand::verifyParams() +{ + if ((_flintParams.guid_specified || _flintParams.guid_specified) && (_flintParams.uid_specified || _flintParams.uids_specified)) { + reportErr(true, FLINT_COMMAND_FLAGS_ERROR, _name.c_str(), "either GUIDs / UIDs (using command line flags -guid(s) / -uid(s) )"); + return false; + } + if ((_flintParams.mac_specified || _flintParams.macs_specified) && (_flintParams.uid_specified || _flintParams.uids_specified)) { + reportErr(true, FLINT_COMMAND_FLAGS_ERROR, _name.c_str(), "either MACs / UIDs (using command line flags -mac(s) / -uid(s) )"); + return false; + } + bool GuidsFromUser = _flintParams.guid_specified || _flintParams.guid_specified ||\ + _flintParams.uid_specified || _flintParams.uids_specified|| \ + _flintParams.mac_specified || _flintParams.macs_specified; + if (GuidsFromUser && _flintParams.use_image_guids) { + reportErr(true, FLINT_INVALID_FLAG_WITH_FLAG_ERROR,"GUIDs/UIDs/MACs", "-use_image_guids"); + return false; + } + if ((GuidsFromUser || _flintParams.use_image_guids) && _flintParams.blank_guids) { + reportErr(true, FLINT_INVALID_FLAG_WITH_FLAG_ERROR, _flintParams.use_image_guids ? \ + "-use_image_guids" : "GUIDs/UIDs/MACs", "-blank_guids"); + return false; + } + if (_flintParams.guid_specified && _flintParams.guids_specified) { + reportErr(true, FLINT_INVALID_FLAG_WITH_FLAG_ERROR, "-guids", "-guid" ); + return false; + } + if (_flintParams.mac_specified && _flintParams.macs_specified) { + reportErr(true, FLINT_INVALID_FLAG_WITH_FLAG_ERROR, "-macs", "-mac" ); + return false; + } + if (_flintParams.uid_specified && _flintParams.uids_specified) { + reportErr(true, FLINT_INVALID_FLAG_WITH_FLAG_ERROR, "-uids", "-uid" ); + return false; + } + if (_flintParams.use_image_ps && _flintParams.vsd_specified) { + reportErr(true, FLINT_INVALID_FLAG_WITH_FLAG_ERROR, "-use_image_ps", "-vsd"); + return false; + } + return true; +} + +void BurnSubCommand::updateBurnParams() +{ + _burnParams.progressFunc = _flintParams.silent == true ? (ProgressCallBack)NULL :\ + _devInfo.fw_type == FIT_FS2? &burnCbFs2Func : &burnCbFs3Func; + _burnParams.userGuidsSpecified = _flintParams.guids_specified || _flintParams.guid_specified; + _burnParams.userMacsSpecified = _flintParams.macs_specified || _flintParams.mac_specified; + _burnParams.userUidsSpecified = _flintParams.uids_specified || _flintParams.uid_specified; + _burnParams.vsdSpecified = _flintParams.vsd_specified; + _burnParams.blankGuids = _flintParams.blank_guids; + _burnParams.burnFailsafe = !_flintParams.nofs; + _burnParams.allowPsidChange = _flintParams.allow_psid_change; + _burnParams.useImagePs = _flintParams.use_image_ps; + _burnParams.burnRomOptions = _flintParams.use_image_rom ? FwOperations::ExtBurnParams::BRO_ONLY_FROM_IMG \ + : FwOperations::ExtBurnParams::BRO_DEFAULT ; + _burnParams.useImageGuids = _flintParams.use_image_guids; + _burnParams.singleImageBurn = !_flintParams.dual_image; + _burnParams.noDevidCheck = _flintParams.no_devid_check; + if (_burnParams.userGuidsSpecified) { + _burnParams.userUids = _flintParams.user_guids; + } + if (_burnParams.userUidsSpecified) { + _burnParams.userUids = _flintParams.user_uids; + } + if (_burnParams.userMacsSpecified) { + if (!_burnParams.userGuidsSpecified) { + //we dont care about the first 4 values + _burnParams.userUids.resize(GUIDS); + } + _burnParams.userUids.push_back(_flintParams.user_macs[0]); + _burnParams.userUids.push_back(_flintParams.user_macs[1]); + } + if (_burnParams.vsdSpecified) { + _burnParams.userVsd = strcpy(new char[_flintParams.vsd.size()+1], _flintParams.vsd.c_str()); + } + //make sure its of max size and fill the rest with 0xffff + _burnParams.userUids.resize(MAX_GUIDS, (guid_t){0xffffffff,0xffffffff}); +} + +bool BurnSubCommand::checkFwVersion() +{ + char curr_ver[124], new_ver[124]; + printf("\n"); + printf(" Current FW version on flash: "); + if (_devInfo.fw_info.fw_ver[0] != 0) { // i.e if we have a fw_version we assume this is != 0 + sprintf(curr_ver, "%d.%d.%d", _devInfo.fw_info.fw_ver[0], _devInfo.fw_info.fw_ver[1], _devInfo.fw_info.fw_ver[2]); + } else { + sprintf(curr_ver, "N/A"); + } + printf(curr_ver); printf("\n"); + + printf(" New FW version: "); + if (_imgInfo.fw_info.fw_ver[0] != 0) { + sprintf(new_ver, "%d.%d.%d", _imgInfo.fw_info.fw_ver[0], _imgInfo.fw_info.fw_ver[1], _imgInfo.fw_info.fw_ver[2]); + } else { + sprintf(new_ver, "N/A"); + } + printf(new_ver); printf("\n"); + + if (_flintParams.log_specified) { + print_line_to_log("Current FW version on flash: %s, New FW version: %s\n", curr_ver, new_ver); + } + bool updateRequired = true; + + if (_devInfo.fw_info.fw_ver[0] != 0 && + _imgInfo.fw_info.fw_ver[0] != 0) { + updateRequired = fwVerLessThan(_devInfo.fw_info.fw_ver,_imgInfo.fw_info.fw_ver); + } + + if (!updateRequired) { + printf("\n Note: The new FW version is not newer than the current FW version on flash.\n"); + if (!askUser()) { + return false; + } + } + printf("\n"); + _burnParams.ignoreVersionCheck = true; + return true; + +} + +bool BurnSubCommand::checkPSIDAndIbEth() +{ + //bool ib_dev; + //bool eth_dev; + //setDevFlags(_devInfo, ib_dev, eth_dev); + //all FW now support both ETH and IB so the OLD IB/ETH FW check is not needed anymore (see old implementation of flint) + + if (strlen(_imgInfo.fw_info.psid) != 0 && strlen(_devInfo.fw_info.psid) != 0 && + strncmp( _imgInfo.fw_info.psid, _devInfo.fw_info.psid, PSID_LEN)) { + if (_flintParams.allow_psid_change) { + printf("\n You are about to replace current PSID on flash - \"%s\" with a different PSID - \"%s\".\n" + " Note: It is highly recommended not to change the PSID.\n", + _devInfo.fw_info.psid, _imgInfo.fw_info.psid); + if (! askUser()) { + return false; + } + } else { + printf("\n"); + reportErr(true, FLINT_PSID_ERROR, _devInfo.fw_info.psid, _imgInfo.fw_info.psid); + return false; + } + } + return true; +} + +FlintStatus BurnSubCommand::burnFs3() +{ + // Here we want to burn FS3 device so we check if the image is indeed FS3 image + if (_imgInfo.fw_type != FIT_FS3) { + reportErr(true, FLINT_IMG_DEV_COMPAT_ERROR, "FS3", "FS3"); + return FLINT_FAILED; + } + // on FS3 burn we require query to pass + if (!_devQueryRes) { + reportErr(true, FLINT_FS3_BURN_ERROR, _fwOps->err()); + return FLINT_FAILED; + } + + //check FwVersion + if ( !checkFwVersion()) { + return FLINT_BURN_ABORTED; + } + // check Psid + if (!checkPSIDAndIbEth()) { + return FLINT_FAILED; + } + // deal with rom + + dealWithExpRom(); + bool getRomFromDev = ( _burnParams.burnRomOptions == FwOperations::ExtBurnParams::BRO_FROM_DEV_IF_EXIST); + if (!getRomFromDev && !checkMatchingExpRomDevId(_imgInfo)) { + printf("Image file ROM: FW is for device %d, but Exp-ROM is for device %d\n", _imgInfo.fw_info.dev_type,\ + _imgInfo.fw_info.roms_info.exp_rom_com_devid); + if (!askUser()) { + return FLINT_FAILED; + } + } + + if (!_fwOps->FwBurnAdvanced(_imgOps, _burnParams)) { + reportErr(true, FLINT_FS3_BURN_ERROR, _fwOps->err()); + return FLINT_FAILED; + } + _burnParams.progressFunc(101); + write_result_to_log(FLINT_SUCCESS, "", _flintParams.log_specified); + return FLINT_SUCCESS; +} + +FlintStatus BurnSubCommand::burnFs2() +{ + + if (_flintParams.striped_image) { + reportErr(true, FLINT_FS2_STRIPED_ERROR); + return FLINT_FAILED; + } + if (_imgInfo.fw_type != FIT_FS2) { + reportErr(true, FLINT_IMG_DEV_COMPAT_ERROR, "FS2", "FS2"); + return FLINT_FAILED; + } + + //CheckMatchingHwDevId is done in mlxfwops burn routine. + //CheckMatchingDevId is done in mlxfwops burn routine. + + dealWithExpRom(); + bool getRomFromDev = _burnParams.burnRomOptions == FwOperations::ExtBurnParams::BRO_FROM_DEV_IF_EXIST; + if (!getRomFromDev && !checkMatchingExpRomDevId(_imgInfo)) { + printf("Image file ROM: FW is for device %d, but Exp-ROM is for device %d\n", _imgInfo.fw_info.dev_type,\ + _imgInfo.fw_info.roms_info.exp_rom_com_devid); + if (!askUser()) { + return FLINT_FAILED; + } + } + + //deal with guids + if (!dealWithGuids()) { + return FLINT_FAILED; + } + + //deal with failsifity should be made in fwops as we dont know if image/device fw is failsafe + if (_burnParams.burnFailsafe & (!_imgInfo.fw_info.is_failsafe || !_devInfo.fw_info.is_failsafe)) { + + if ((!_imgInfo.fw_info.is_failsafe && !_devInfo.fw_info.is_failsafe)) { + // When both image and flash are non-failsafe, flint will burn in a non-failsafe mode + _burnParams.burnFailsafe = false; + } else { + // when only one of image and flash is non-failsafe, flint will fail with appropriate message + reportErr(true, "Failsafe burn failed: FW image in the %s is non failsafe.\n" + " you cannot burn a%s failsafe image over a%s failsafe image in a failsafe mode.\n" + " If you want to burn in non failsafe mode, use the \"-nofs\" switch.\n", + _imgInfo.fw_info.is_failsafe ? "flash" : "given file", _imgInfo.fw_info.is_failsafe? "" : " non",\ + _devInfo.fw_info.is_failsafe ? "" : " non"); + return FLINT_FAILED; + } + } + + //deal with vsd + if (!dealWithVSD()) { + return FLINT_FAILED; + } + + //check versions + if (!checkFwVersion()) { + return FLINT_BURN_ABORTED; + } + //check Psid + if (_devQueryRes && !checkPSIDAndIbEth()) { + return FLINT_FAILED; + } + + // Warn if a fw which does not support config is burnt over fw that does support config + // The other way (new fw with config, old fw w/o config) is a normal update flow. + // Update: all fw should now support config sectors, so we just check any missmatch in the config pads + + + // Verify config offset. Should never be different between image and flash (unless changing PSID). + if (_imgInfo.fs2_info.config_pad != _devInfo.fs2_info.config_pad) { + printf("\n"); + printf("-W- Configuration section offset on flash (%u sectors) differs from the" + " Configuration section offset in the given image (%u sectors)." + " Current device configuration (if exists) will be deleted.\n", + _devInfo.fs2_info.config_pad, + _imgInfo.fs2_info.config_pad); + if (_burnParams.allowPsidChange) { + if (!askUser()) { + return FLINT_FAILED; + } + } else { + reportErr(true, "Use the '-allow_psid_change' flag to force this change.\n"); + return FLINT_FAILED; + } + } + + if (!_burnParams.burnFailsafe) { + printf("Burn process will not be failsafe. No checks will be performed.\n"); + printf("ALL flash, including the Invariant Sector will be overwritten.\n"); + printf("If this process fails, computer may remain in an inoperable state.\n"); + if (!askUser()) { + return FLINT_FAILED; + } + } + + //Finally we can burn + if (!_fwOps->FwBurnAdvanced(_imgOps, _burnParams)) + { + reportErr(true, FLINT_FS2_BURN_ERROR, _fwOps->err()); + return FLINT_FAILED; + } + _burnParams.progressFunc(101); + write_result_to_log(FLINT_SUCCESS, "", _flintParams.log_specified); + return FLINT_SUCCESS; +} + +bool BurnSubCommand::dealWithVSD() +{ + if (!(_burnParams.vsdSpecified || _burnParams.useImagePs) && !((strlen(_devInfo.fw_info.psid) != 0 \ + && _devInfo.fw_info.vsd_sect_found))) { + printf("\n"); + if (_burnParams.burnFailsafe) { + reportErr(true, "Can not extract VSD/PSID info from flash.\n" + " Can not burn in a failsafe mode. Please use \"-nofs\" flag to burn in a non failsafe mode.\n"); + return false; + } else { + printf("-W- Can not extract VSD/PSID info from flash.\n\n" + " To use a specific VSD, abort and re-burn specifying the\n" + " needed info (using command line flags -vsd / -use_image_ps).\n" + " You can also continue burn using blank VSD.\n"); + if (!askUser()) { + return false; + } + } + } + return true; +} + +bool BurnSubCommand::dealWithGuids() +{ + bool read_guids = true; + bool ib_dev; + bool eth_dev; + bool bx_dev; + // Get the FW types + bx_dev = _imgInfo.fw_info.chip_type == CT_BRIDGEX; + FwOperations::SetDevFlags(_imgInfo.fw_info.chip_type, _imgInfo.fw_info.dev_type, (fw_img_type)_imgInfo.fw_type, ib_dev, eth_dev); + //setDevFlags(_imgInfo, ib_dev, eth_dev); + + // Check if there is a need to read guids + if (_burnParams.useImageGuids || _burnParams.blankGuids + || (_burnParams.userGuidsSpecified && ib_dev) + || (_burnParams.userMacsSpecified) + || (_burnParams.userUidsSpecified && bx_dev)) { + read_guids = false; + } + // Check if the burnt FW is ok and readable in order to get the GUIDs later + if (read_guids && !_devQueryRes) { + //printMissingGuidErr(ib_dev, eth_dev, bx_dev); + if (_burnParams.burnFailsafe) { + reportErr(true, + "Can not extract GUIDs/MACs info from flash, %s\n" + " Can not burn in a failsafe mode.\n" + " If you want to burn in non failsafe mode, use the \"-nofs\" switch.\n", _fwOps->err()); + } else { + reportErr(true, "Can not extract GUIDs/MACs info from flash, %s", _fwOps->err()); + printMissingGuidErr(ib_dev, eth_dev, bx_dev); + } + return false; + } + // Check guids flag to ensure correct patching of guids in mlxfwops + bool is_guids_specified = _burnParams.userGuidsSpecified + || _burnParams.userMacsSpecified + || _burnParams.userUidsSpecified; + if (is_guids_specified) { + if (!checkGuidsFlags((chip_type_t)_imgInfo.fw_info.chip_type, _imgInfo.fw_info.dev_type, _devInfo.fw_type,\ + _burnParams.userGuidsSpecified, _burnParams.userMacsSpecified, _burnParams.userUidsSpecified)) { + return false; + } + } + //report guid changes if needed. and update the user_guids vector in _burnParams + if (is_guids_specified || _flintParams.use_image_guids) { + guid_t* new_guids = ( _burnParams.userGuidsSpecified || _burnParams.userUidsSpecified )?\ + &_burnParams.userUids[0] : _devInfo.fs2_info.guids; + guid_t* new_macs = _burnParams.userMacsSpecified != 0 ? &_burnParams.userUids[GUIDS] : &_devInfo.fs2_info.guids[GUIDS]; + guid_t* old_guids = !_devQueryRes ? NULL : _devInfo.fs2_info.guids; + guid_t* old_macs = old_guids != NULL ? &old_guids[GUIDS] : NULL; + if (!is_guids_specified && _flintParams.use_image_guids) { + new_guids = _imgInfo.fs2_info.guids; + new_macs = &_imgInfo.fs2_info.guids[GUIDS]; + } + //printf("-D- l=%d, h=%d\n", new_macs->l, new_macs->h); + if (!reportGuidChanges(new_guids, new_macs, old_guids, old_macs, ib_dev,\ + eth_dev, bx_dev, _imgInfo.fs2_info.guid_num)) { + return false; + } + + } + return true; +} + +void BurnSubCommand::dealWithExpRom() +{ + bool getRomFromDev = false; + // Check exp rom: + bool fs2Cond = _devInfo.fw_type == FIT_FS2? (_devQueryRes && _devInfo.fw_info.chip_type == CT_CONNECTX && \ + (FwOperations::IsFwSupportingRomModify(_devInfo.fw_info.fw_ver) || (_imgInfo.fw_info.roms_info.num_of_exp_rom > 0))\ + && !_flintParams.use_image_rom && !strcmp(_devInfo.fw_info.product_ver,"") && !strcmp(_imgInfo.fw_info.product_ver, "")) : false; + + bool fs3Cond = _devInfo.fw_type == FIT_FS3 ? (_devQueryRes && _devInfo.fw_info.chip_type == CT_CONNECT_IB && \ + (FwOperations::IsFwSupportingRomModify(_devInfo.fw_info.fw_ver) || (_imgInfo.fw_info.roms_info.num_of_exp_rom > 0))\ + && !_flintParams.use_image_rom) : false; //&& !strcmp(_devInfo.fw_info.product_ver,"") && !strcmp(_imgInfo.fw_info.product_ver, "") : false; + + bool cond = _devInfo.fw_type == FIT_FS2 ? fs2Cond : fs3Cond; + + if (cond) { + // Enter here when: + // The fw on the flash is OK (passed query, and it should pass verify in mlxfwops) && + // ( The device is hermon || golan )&& + // The image fw supports modifying ROM OR it contains ROM &&. + // The user didn't ask to burn the image rom. && + // The fw on the flash doesn't contain product version (on golan we dont check this last cond) + + if (_imgInfo.fw_info.roms_info.num_of_exp_rom > 0 && _devInfo.fw_info.roms_info.num_of_exp_rom > 0) { + printf("\n Note: Both the image file and the flash contain a ROM image.\n" + " Select \"yes\" to use the ROM from the given image file.\n" + " Select \"no\" to keep the existing ROM in the flash\n"); + + displayExpRomInfo(_devInfo.fw_info.roms_info, " Current ROM info on flash: "); + displayExpRomInfo(_imgInfo.fw_info.roms_info, " ROM info from image file : "); + if (!askUser("Use the ROM from the image file", false)) { + getRomFromDev = true; + } else { + getRomFromDev = false; + } + } else if (!(_imgInfo.fw_info.roms_info.num_of_exp_rom > 0) && _devInfo.fw_info.roms_info.num_of_exp_rom > 0) { + getRomFromDev = true; + } + } + if (getRomFromDev) { + _burnParams.burnRomOptions = FwOperations::ExtBurnParams::BRO_FROM_DEV_IF_EXIST; + } + return; +} + +bool BurnSubCommand::checkMatchingExpRomDevId(const fw_info_t& info) +{ + if ((info.fw_info.roms_info.num_of_exp_rom > 0) && (info.fw_info.dev_type) + && (info.fw_info.roms_info.exp_rom_com_devid != EXP_ROM_GEN_DEVID) \ + && (info.fw_info.roms_info.exp_rom_com_devid != MISS_MATCH_DEV_ID) + && (info.fw_info.dev_type != info.fw_info.roms_info.exp_rom_com_devid)) { + return false; + } + return true; +} + +FlintStatus BurnSubCommand::executeCommand() +{ + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + // query both image and device (deviceQuery can fail but we save rc) + _devQueryRes = _fwOps->FwQuery(&_devInfo); + if (!_imgOps->FwQuery(&_imgInfo)) + { + reportErr(true, FLINT_FAILED_QUERY_ERROR, "image", _flintParams.image.c_str(), _imgOps->err()); + return FLINT_FAILED; + } + //updateBurnParams with input given by user + updateBurnParams(); + if (_devInfo.fw_type == FIT_FS3) { + return burnFs3(); + } else if (_devInfo.fw_type == FIT_FS2) { + return burnFs2(); + } + // unknown fw type + reportErr(true, FLINT_UNKNOWN_FW_TYPE_ERROR); + return FLINT_FAILED; +} + +/*********************** + *Class: QuerySubCommand + **********************/ + +bool QuerySubCommand::verifyParams() +{ + if (_flintParams.cmd_params.size() > 1) + { + reportErr(true, FLINT_CMD_ARGS_ERROR,_name.c_str(), 1, (int)_flintParams.cmd_params.size()); + return false; + } + if ((_flintParams.cmd_params.size() == 1) && _flintParams.cmd_params[0] != "full") + { + reportErr(true, FLINT_INVALID_OPTION_ERROR, _flintParams.cmd_params[0].c_str(), _name.c_str(), "full"); + return false; + } + return true; +} + +bool QuerySubCommand::checkMac(u_int64_t mac, string& warrStr) { + if ((mac >> 40) & 0x1) { + + warrStr = FLINT_MULTI_BIT_WARNING; + return false; + } + + if (mac >> 48) { + warrStr = FLINT_MORE_48_BITS_WARNING; + return false; + } + + return true; +} + +bool QuerySubCommand::reportBxGuidsQuery(const guid_t* guids, int base1, int guids_num, int index, const char* pre_str) +{ + int i, first_index, base, wwnns_index; + + printf("G%d %-14s", index, pre_str); + first_index = index * BX_SLICE_GUIDS; + if (base1 == BI_WWPNS) { + wwnns_index = first_index + (BX_SLICE_GUIDS - 1); + printf(GUID_FORMAT " ", guids[wwnns_index].h, guids[wwnns_index].l); + } + base = first_index + base1; + for (i = base; i < base + guids_num; i++) { + int j = i; + // HACK + if (i == BI_GUIDS + BX_SLICE_GUIDS) { + // We display the same node guid on the two slices. + j = BI_GUIDS; + } + printf(GUID_FORMAT " ", guids[j].h, guids[j].l); + } + printf("\n"); + return true; +} + + +bool QuerySubCommand::reportBxMacsQuery(const guid_t* guids, int base1, int guids_num, int index, const char* pre_str) +{ + int i, base; + + base = index * BX_SLICE_GUIDS + base1; + printf("G%d %-30s", index, pre_str); + for (i = base; i < base + guids_num; i++) { + printf(" " MAC_FORMAT , guids[i].h, guids[i].l); + } + printf("\n"); + return true; +} + +bool QuerySubCommand::reportBxMacsWarnings(const guid_t* guids, int index, int warning, int user_uids) +{ + int i, base; + int is_first = 1; + base = index * BX_SLICE_GUIDS + BI_IMACS; + for (i = base; i < base + BX_MACS; i++) { + u_int64_t mac = (((u_int64_t)guids[i].h) << 32) | guids[i].l; + string warrStr; + if (!checkMac(mac, warrStr)) { + if (warning) { + if (is_first) { + printf("\n\n"); + is_first = 0; + } + printf(FLINT_BAD_MAC_ADRESS_WARNING, guids[i].h, guids[i].l, warrStr.c_str()); + } else { + printf(FLINT_BX_BAD_MAC_FORMAT_ERROR, + guids[i].h, + guids[i].l, + user_uids ? "given" : "found on flash"); + return false; + } + } + } + return true; +} + + +bool QuerySubCommand::displayFs2Uids(const fw_info_t& fwInfo) +{ + const char* mac_indent = ""; + bool ibDev; + bool ethDev; + FwOperations::SetDevFlags(fwInfo.fw_info.chip_type, fwInfo.fw_info.dev_type, (fw_img_type)fwInfo.fw_type, ibDev, ethDev); + //setDevFlags(fwInfo, ibDev, ethDev); + int numPorts = 2; + if ((fwInfo.fw_info.chip_type == CT_IS4) || (fwInfo.fw_info.chip_type == CT_SWITCHX)) { + numPorts = 0; + } + //we do not support cards with one port anymore. + + // GUIDS: + + if (fwInfo.fw_info.chip_type == CT_BRIDGEX) { + int i, base; + if (fwInfo.fs2_info.guid_num != BX_ALL_GUIDS) { + reportErr(true, FLINT_INVALID_UID_NUM_BX_ERROR, BX_ALL_GUIDS); + return false; + } + printf("Description: Node Port1 Port2 Port3 Port4\n"); + for (i = 0; i < BX_SLICES_NUM; i++) { + base = i * BX_SLICE_GUIDS; + reportBxGuidsQuery(fwInfo.fs2_info.guids, BI_GUIDS, BX_NP_GUIDS, i, "GUIDs:"); + reportBxMacsQuery(fwInfo.fs2_info.guids, BI_IMACS, BX_IMACS, i, "IMACs:"); + reportBxMacsQuery(fwInfo.fs2_info.guids, BI_EMACS, BX_EMACS, i, "EMACs:"); + reportBxGuidsQuery(fwInfo.fs2_info.guids, BI_WWPNS, BX_WWPNS, i, "WWNs: "); + } + printf("SYS GUID: " GUID_FORMAT " ",\ + fwInfo.fs2_info.guids[fwInfo.fs2_info.guid_num - 1].h,\ + fwInfo.fs2_info.guids[fwInfo.fs2_info.guid_num - 1].l); + if (!fwInfo.fs2_info.blank_guids) { + for (i = 0; i < BX_SLICES_NUM; i++) { + reportBxMacsWarnings(fwInfo.fs2_info.guids, i, 1, 0); + } + } + } else { + if (ibDev) { + //report("GUID Des: Node Port1 "); + printf("Description: Node "); + if (numPorts > 0) + printf("Port1 "); + if (numPorts > 1) + printf("Port2 "); + printf( "Sys image\n"); + + printf("GUIDs: "); + for (u_int32_t i=0; i < GUIDS; i++) { + if ((i == 1 && numPorts < 1) || + (i == 2 && numPorts < 2)) { + continue; + } + printf(GUID_FORMAT " ", fwInfo.fs2_info.guids[i].h, fwInfo.fs2_info.guids[i].l); + } + if (numPorts > 0) { + mac_indent = " "; + } + } + // MACS: + if (ethDev) { + if (fwInfo.fs2_info.guid_num == 6) { + if (!ibDev) { + printf("Description:%s Port1 Port2\n", mac_indent); + } else if (fwInfo.fw_info.chip_type == CT_SWITCHX) { + printf("\nDescription: Base Switch\n"); + } else { + printf("\n"); + } + printf("MACs: %s ", mac_indent); + for (u_int32_t i=GUIDS; i < 6; i++) { + printf(" " MAC_FORMAT , fwInfo.fs2_info.guids[i].h, fwInfo.fs2_info.guids[i].l); + } + + for (u_int32_t i=GUIDS; i < 6; i++) { + u_int64_t mac = (((u_int64_t)fwInfo.fs2_info.guids[i].h) << 32) | fwInfo.fs2_info.guids[i].l; + string warrStr; + if (!fwInfo.fs2_info.blank_guids && !checkMac(mac, warrStr)) { + if (i==GUIDS) printf("\n\n"); + printf(FLINT_BAD_MAC_ADRESS_WARNING, fwInfo.fs2_info.guids[i].h, fwInfo.fs2_info.guids[i].l, warrStr.c_str()); + } + } + } else { + printf(FLINT_MAC_ENTRIES_WARNING, 6, fwInfo.fs2_info.guid_num); + } + } + } + printf("\n"); + return true; +} + +#define BASE_STR "Base" +#define PRINT_FS3_UID(uid1, str) printf("%-16s %016lx %d %d\n", str, uid1.uid, uid1.num_allocated, uid1.step); +#define PRINT_FS3_UIDS(uid1, uid2, str) {\ + PRINT_FS3_UID(uid1, BASE_STR" "str":");\ + if (uid1.uid != uid2.uid || uid1.num_allocated != uid2.num_allocated || uid1.step != uid2.step) {\ + PRINT_FS3_UID(uid2, "Orig " BASE_STR " "str":");\ + } \ +} + +bool QuerySubCommand::displayFs3Uids(const fw_info_t& fwInfo) +{ + printf("Description: UID GuidsNumber Step\n"); + PRINT_FS3_UIDS(fwInfo.fs3_info.fs3_uids_info.guids[0], fwInfo.fs3_info.orig_fs3_uids_info.guids[0], "GUID1"); + PRINT_FS3_UIDS(fwInfo.fs3_info.fs3_uids_info.guids[1], fwInfo.fs3_info.orig_fs3_uids_info.guids[1], "GUID2"); + PRINT_FS3_UIDS(fwInfo.fs3_info.fs3_uids_info.macs[0], fwInfo.fs3_info.orig_fs3_uids_info.macs[0], "MAC1"); + PRINT_FS3_UIDS(fwInfo.fs3_info.fs3_uids_info.macs[1], fwInfo.fs3_info.orig_fs3_uids_info.macs[1], "MAC2"); + return true; +} + + + +FlintStatus QuerySubCommand::printInfo(const fw_info_t& fwInfo, bool fullQuery) +{ + bool isFs2 = (fwInfo.fw_type == FIT_FS2) ? true : false; + printf("Image type: %s\n",(isFs2)? "FS2" : "FS3"); + + if (fwInfo.fw_info.fw_ver[0] || fwInfo.fw_info.fw_ver[1] || fwInfo.fw_info.fw_ver[2]) { + printf("FW Version: %d.%d.%d\n", fwInfo.fw_info.fw_ver[0], fwInfo.fw_info.fw_ver[1],\ + fwInfo.fw_info.fw_ver[2]); + } + + + if (fullQuery) { + if (fwInfo.fw_info.min_fit_ver[0] || fwInfo.fw_info.min_fit_ver[1]\ + || fwInfo.fw_info.min_fit_ver[2]||fwInfo.fw_info.min_fit_ver[3]) { + printf("Min FIT Version: %d.%d.%d.%d\n", fwInfo.fw_info.min_fit_ver[0],\ + fwInfo.fw_info.min_fit_ver[1], fwInfo.fw_info.min_fit_ver[2], fwInfo.fw_info.min_fit_ver[3]); + } + if ((fwInfo.fw_info.mic_ver[0] || fwInfo.fw_info.mic_ver[1] || fwInfo.fw_info.mic_ver[2])) { + printf("MIC Version: %d.%d.%d\n", fwInfo.fw_info.mic_ver[0],\ + fwInfo.fw_info.mic_ver[1], fwInfo.fw_info.mic_ver[2]); + } + if (isFs2) + { if (fwInfo.fs2_info.config_sectors) + printf("Config Sectors: %d\n", fwInfo.fs2_info.config_sectors); + if (fwInfo.fs2_info.config_pad) { + printf("Config Pad: %d\n", fwInfo.fs2_info.config_pad); + } + + } + } + + if (strlen(fwInfo.fw_info.product_ver)) { + printf("Product Version: %s\n", fwInfo.fw_info.product_ver); + } + + if (fwInfo.fw_info.roms_info.exp_rom_found) { + displayExpRomInfo(fwInfo.fw_info.roms_info, "Rom Info: "); + } + + if (isFs2) + { + printf("Device ID: %d\n", fwInfo.fw_info.dev_type); + } + + if (isFs2 && fwInfo.fs2_info.access_key_exists) { + printf("HW Access Key: "); + if (fwInfo.fs2_info.access_key_value.l || fwInfo.fs2_info.access_key_value.h) { + printf("Enabled\n"); + } else { + printf("Disabled\n"); + } + } + + if (!isFs2)/*i.e its fs3*/{ + if (!displayFs3Uids(fwInfo)) { + return FLINT_FAILED; + } + } else { + if (!displayFs2Uids(fwInfo)) { + return FLINT_FAILED; + } + } + + // VSD, PSID + if (!fwInfo.fw_info.vsd_vendor_id || fwInfo.fw_info.vsd_vendor_id == MELLANOX_VENDOR_ID) { + if (!isFs2) { + printf("Image VSD: %s\n", fwInfo.fs3_info.image_vsd); + printf("Device VSD: %s\n", fwInfo.fw_info.vsd); + printf("PSID: %s\n", fwInfo.fw_info.psid); + if (strncmp(fwInfo.fw_info.psid, fwInfo.fs3_info.orig_psid, 13) != 0) { + printf("Orig PSID: %s\n", fwInfo.fs3_info.orig_psid); + } + } else { + printf("VSD: %s\n", fwInfo.fw_info.vsd); + printf("PSID: %s\n", fwInfo.fw_info.psid); + } + } else { + printf(FLINT_NOT_MLNX_FW_WARNING, fwInfo.fw_info.vsd_vendor_id); + } + + if (isFs2 && fwInfo.fs2_info.blank_guids) { //blankGuids only exsists in FS2 image type in mlxfwops why? + printf(FLINT_BLANK_GUIDS_WARNING); + } + return FLINT_SUCCESS; +} + +QuerySubCommand:: QuerySubCommand() +{ + _name = "query"; + _desc = "Query misc. flash/firmware characteristics, use \"full\"\n" + INDENT"to get more information."; + _extendedDesc = "Query miscellaneous FW and flash parameters \n" + INDENTEX"Display FW Version, GUIDs, PSID, and other info"; + _flagLong = "query"; + _flagShort = "q"; + _param = "[full]"; + _paramExp = "None"; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" query"; + _v = Wtv_Dev_Or_Img; + _cmdType = SC_Query; +} + +QuerySubCommand:: ~QuerySubCommand() +{ + +} + +FlintStatus QuerySubCommand::executeCommand() +{ + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + fw_info_t fwInfo; + FwOperations* ops; + bool fullQuery = false; + //check on what we are wroking + ops = (_flintParams.device_specified) ? _fwOps : _imgOps; + if (!ops->FwQuery(&fwInfo, true, _flintParams.striped_image)) + { + reportErr(true, FLINT_FAILED_QUERY_ERROR,_flintParams.device_specified? "Device" : "image", + _flintParams.device_specified? _flintParams.device.c_str() : _flintParams.image.c_str(), ops->err()); + return FLINT_FAILED; + } + //print fw_info nicely to the user + if (_flintParams.quick_query) {// we actually dont use "regular" query , just quick + printf("\n"FLINT_QQ_WARRNING"\n"); + } + if (_flintParams.cmd_params.size() == 1) { + fullQuery=true; + } + return printInfo(fwInfo, fullQuery); +} + +/*********************** + *Class: VerifySubCommand + ***********************/ +VerifySubCommand:: VerifySubCommand() +{ + _name = "verify"; + _desc = "Verify entire flash, use \"showitoc\" to see ITOC headers\n" + INDENT"in FS3 image only."; + _extendedDesc = "Verify entire flash."; + _flagLong = "verify"; + _flagShort = "v"; + _param = "[showitoc]"; + _paramExp = "None"; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" v"; + _v = Wtv_Dev_Or_Img; + _cmdType = SC_Verify; +} + +VerifySubCommand:: ~VerifySubCommand() +{ + +} + +bool VerifySubCommand::verifyParams() +{ + + if (_flintParams.cmd_params.size() > 1) + { + reportErr(true, FLINT_CMD_ARGS_ERROR,_name.c_str(), 0, (int)_flintParams.cmd_params.size()); + return false; + } + if ((_flintParams.cmd_params.size() == 1) && _flintParams.cmd_params[0] != "showitoc") + { + reportErr(true, FLINT_INVALID_OPTION_ERROR, _flintParams.cmd_params[0].c_str(), _name.c_str(), "swhoitoc"); + return false; + } + + return true; +} + + + + +FlintStatus VerifySubCommand::executeCommand() +{ + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + FwOperations* ops; + bool showItoc = (_flintParams.cmd_params.size() == 1) ? true : false; + //check on what we are wroking + ops = (_flintParams.device_specified) ? _fwOps : _imgOps; + if (!ops->FwVerify(&verifyCbFunc, _flintParams.striped_image, showItoc)) { + printf("\n\n"); + reportErr(true, FLINT_CMD_VERIFY_ERROR, ops->err()); + + return FLINT_FAILED; + } + //get status of blank guids in fs2 only can either bring from FwVerify as another parameter. ask mohammad + if (ops->FwType() == FIT_FS2) { + fw_info_t fwInfo; + if (!ops->FwQuery(&fwInfo, true, _flintParams.striped_image)) { + printf("\n\n"); + reportErr(true, "Failed to get Guids status. %s\n", ops->err()); + return FLINT_FAILED; + } + if (fwInfo.fs2_info.blank_guids) { + printf("\n\n"); + reportErr(true, FLINT_CMD_VERIFY_ERROR, "BLANK GUIDS"); + return FLINT_FAILED; + } + } + printf("\n-I- FW image verification succeeded. Image is bootable.\n\n"); + return FLINT_SUCCESS; +} + +/*********************** + *Class: SwResetSubCommand + **********************/ +SwResetSubCommand:: SwResetSubCommand() { + _name = "swreset"; + _desc = "SW reset the target un-managed switch device. This command\n" + INDENT"is supported only in the In-Band access method."; + _extendedDesc = "SW reset the target un-managed switch device. This command\n" + INDENTEX"is supported only in the In-Band access method."; + _flagLong = "swreset"; + _flagShort = ""; + _param = ""; + _paramExp = "None"; + _example = "None"; + _v = Wtv_Dev; + _cmdType = SC_Swreset; +} + +SwResetSubCommand:: ~SwResetSubCommand() { + +} + + +bool SwResetSubCommand::verifyParams() { + if (_flintParams.cmd_params.size() != 0) { + reportErr(true, FLINT_CMD_ARGS_ERROR,_name.c_str() , 0, (int)_flintParams.cmd_params.size()); + return false; + } + return true; +} + +FlintStatus SwResetSubCommand::executeCommand() +{ + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + printf("-I- Resetting device %s ...\n", _flintParams.device.c_str()); + if (!_fwOps->FwSwReset()) { + reportErr(true, FLINT_SWRESET_ERROR, _fwOps->err()); + return FLINT_FAILED; + } + return FLINT_SUCCESS; +} + +/*********************** + *Class: BromSubCommand + **********************/ +BromSubCommand:: BromSubCommand() +{ + _name = "brom"; + _desc = "Burn the specified ROM file on the flash."; + _extendedDesc = "Burn the specified exp-ROM on the flash."; + _flagLong = "brom"; + _flagShort = ""; + _param = ""; + _paramExp = "file: The exp-ROM file."; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" brom exp-rom.rom"; + _v = Wtv_Dev_Or_Img; + _cmdType = SC_Brom; +} + +BromSubCommand:: ~BromSubCommand() +{ + closeLog(); + _fRom.close(); +} + +bool BromSubCommand::verifyParams() { + if (_flintParams.cmd_params.size() != 1) { + reportErr(true, FLINT_CMD_ARGS_ERROR,_name.c_str() , 1, (int)_flintParams.cmd_params.size()); + return false; + } + return true; +} + + +bool BromSubCommand::getExpRomStrVer(roms_info_t& roms_info, char* version) { + if (roms_info.rom_info[0].exp_rom_product_id >= 0x10) { + sprintf(version, "%d.%d.%d", roms_info.rom_info[0].exp_rom_ver[0], roms_info.rom_info[0].exp_rom_ver[1], + roms_info.rom_info[0].exp_rom_ver[2]); + } else { + sprintf(version, "%d", roms_info.rom_info[0].exp_rom_ver[0]); + } + return true; +} + + +FlintStatus BromSubCommand::executeCommand() +{ + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + + FwOperations *ops = _flintParams.device_specified ? _fwOps : _imgOps; + // query device + if (!ops->FwQuery(&_info)) { + reportErr(true, FLINT_FAILED_QUERY_ERROR, "Device", _flintParams.device.c_str(), + ops->err()); + return FLINT_FAILED; + } + // get roms info + if (!_fRom.open(_flintParams.cmd_params[0].c_str())) { + reportErr(true, FLINT_BROM_ERROR, _fRom.err()); + return FLINT_FAILED; + } + if (!getRomsInfo(&_fRom, _romsInfo)) { + return FLINT_FAILED; + } + //check devids + if ((_romsInfo.num_of_exp_rom > 0) && (_info.fw_info.dev_type) + && (_romsInfo.exp_rom_com_devid != EXP_ROM_GEN_DEVID) \ + && (_romsInfo.exp_rom_com_devid != MISS_MATCH_DEV_ID) + && (_info.fw_info.dev_type != _romsInfo.exp_rom_com_devid)) { + printf("-W- Image file ROM: FW is for device %d, but Exp-ROM is for device %d\n",\ + _info.fw_info.dev_type, _romsInfo.exp_rom_com_devid); + if (!askUser()) { + return FLINT_FAILED; + } + } + char romVer1[50], romVer2[50]; + printf("\n"); + char *infoStr = " Current ROM info on flash: "; + char *infoStr2 = " New ROM info: "; + if (_info.fw_info.roms_info.num_of_exp_rom > 0) { + displayExpRomInfo(_info.fw_info.roms_info, infoStr); + getExpRomStrVer(_info.fw_info.roms_info, romVer1); + } else { + printf("%s", infoStr); + sprintf(romVer1, "N/A"); + printf("%s\n", romVer1); + } + displayExpRomInfo(_romsInfo, infoStr2); + getExpRomStrVer(_romsInfo, romVer2); + //add new line to space up before showing burn precentage + printf("\n"); + //print correct msg to log + if (_info.fw_info.roms_info.num_of_exp_rom != 0) { + print_line_to_log("Current ROM version on flash (1st ROM of %d): %s, New ROM version (1st ROM of %d): %s\n",\ + _info.fw_info.roms_info.num_of_exp_rom, romVer1, _romsInfo.num_of_exp_rom, romVer2); + } else { + print_line_to_log("Current ROM version on flash: %s, New ROM version(1st ROM of %d): %s\n",romVer1, _romsInfo.num_of_exp_rom, romVer2); + } + // burn the rom + printf("-I- Preparing to burn ROM ...\n"); + if (!ops->FwBurnRom(&_fRom, _flintParams.allow_rom_change, true, bromCbFunc)) { + reportErr(true, FLINT_BROM_ERROR, ops->err()); + return FLINT_FAILED; + } + bromCbFunc(101); + printf("\n"); + write_result_to_log(FLINT_SUCCESS, "", _flintParams.log_specified); + return FLINT_SUCCESS; +} + +/*********************** + *Class: Delete ROM + **********************/ +DromSubCommand:: DromSubCommand() +{ + _name = "drom"; + _desc = "Remove the ROM section from the flash."; + _extendedDesc = "Remove the exp-ROM from the flash if it is existing."; + _flagLong = "drom"; + _flagShort = ""; + _param = ""; + _paramExp = "None"; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" drom"; + _v = Wtv_Dev_Or_Img; + _cmdType = SC_Drom; +} + +DromSubCommand:: ~DromSubCommand() +{ + +} + +bool DromSubCommand::verifyParams() +{ + if (_flintParams.cmd_params.size() != 0) { + reportErr(true, FLINT_CMD_ARGS_ERROR,_name.c_str() , 0, (int)_flintParams.cmd_params.size()); + return false; + } + return true; +} + +FlintStatus DromSubCommand::executeCommand() +{ + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + // leave an empty line before printing from callback + FwOperations *ops = _flintParams.device_specified ? _fwOps : _imgOps; + + printf("\n"); + printf("-I- Preparing to remove ROM ...\n"); + if(!ops->FwDeleteRom(_flintParams.allow_rom_change, dromCbFunc)) { + reportErr(true, FLINT_DROM_ERROR, ops->err()); + return FLINT_FAILED; + } + dromCbFunc(101); + return FLINT_SUCCESS; +} +/*********************** + *Class: Read ROM + **********************/ +RromSubCommand:: RromSubCommand() +{ + _name = "rrom"; + _desc = "Read the ROM section from the flash."; + _extendedDesc = "Read the exp-ROM from the flash if it is existing."; + _flagLong = "rrom"; + _flagShort = ""; + _param = ""; + _paramExp = "file: filename to write the exp-ROM to."; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" rrom exp-rom.rom"; + _v = Wtv_Dev_Or_Img; + _cmdType = SC_Rrom; +} + +RromSubCommand:: ~RromSubCommand() +{ + +} + +bool RromSubCommand::verifyParams() +{ + if (_flintParams.cmd_params.size() != 1) { + reportErr(true, FLINT_CMD_ARGS_ERROR,_name.c_str() , 1, (int)_flintParams.cmd_params.size()); + return false; + } + FILE * file; + if ((file = fopen(_flintParams.cmd_params[0].c_str(), "r")) != NULL) { + fclose(file); + printf( + "\n-W- The given ROM file is existing, you are going to overwrite it.\n"); + if (!askUser()) { + return false; + } + } + return true; +} + +FlintStatus RromSubCommand::executeCommand() +{ + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + //get the rom sector if present. + std::vector romSect; + FwOperations* ops = _flintParams.device_specified ? _fwOps : _imgOps; + if (!ops->FwReadRom(romSect)) { + reportErr(true, FLINT_READ_ROM_ERROR, ops->err()); + return FLINT_FAILED; + } + //TOCPUn(&(romSect[0]), romSect.size()/4); + if (!writeToFile(_flintParams.cmd_params[0], romSect)) { + return FLINT_FAILED; + } + return FLINT_SUCCESS; +} + + + +/*********************** + *Class: + **********************/ +BbSubCommand:: BbSubCommand() +{ + _name = "bb"; + _desc = "Burn Block - Burns the given image as is. No checks are done."; + _extendedDesc = "Burns entire flash verbatim from raw binary image. No checks are done on the flash or\n" + INDENTEX"on the given image file. No fields (such as VSD or Guids) are read from flash."; + _flagLong = "bb"; + _flagShort = ""; + _param = ""; + _paramExp = "None"; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" -i image1.bin bb"; + _v = Wtv_Dev_And_Img; + _cmdType = SC_Bb; +} + +BbSubCommand:: ~BbSubCommand() +{ + closeLog(); +} + +bool BbSubCommand:: verifyParams() +{ + if (_flintParams.cmd_params.size() != 0) { + reportErr(true, FLINT_CMD_ARGS_ERROR, _name.c_str(), 0, (int)(_flintParams.cmd_params.size())); + return false; + } + return true; +} + +FlintStatus BbSubCommand:: executeCommand() +{ + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + if (_fwOps->FwType() == FIT_FS3) { + reportErr(true, FLINT_FS3_BB_ERROR); + return FLINT_FAILED; + } + + + printf("\n"); + printf("Block burn: The given image will be burnt as is. No fields (such\n"); + printf("as GUIDS,VSD) are taken from current image on flash.\n"); + printf("Burn process will not be failsafe. No checks will be performed.\n"); + printf("ALL flash, including the Invariant Sector will be overwritten.\n"); + printf("If this process fails, computer may remain in an inoperable state.\n"); + if (!askUser()) { + return FLINT_FAILED; + } + ProgressCallBack progressFunc = _flintParams.silent == true ? (ProgressCallBack)NULL : &burnBCbFunc; + if (!_fwOps->FwBurnBlock(_imgOps, progressFunc)) { + reportErr(true, "Non failsafe burn failed: %s\n", _fwOps->err()); + return FLINT_FAILED; + } + printf("\n"); + write_result_to_log(FLINT_SUCCESS, "", _flintParams.log_specified); + return FLINT_SUCCESS; +} + +/*********************** + *Class: + **********************/ +SgSubCommand:: SgSubCommand() +{ + _name = "sg"; + _desc = "Set GUIDs."; + _extendedDesc = "Set GUIDs/MACs/UIDs in the given device/image.\n" + INDENTEX"Use -guid(s), -mac(s) and -uid(s) flags to set the desired values.\n" + INDENTEX"- On pre-ConnectX devices, the sg command is used in production to apply GUIDs/MACs values\n" + INDENTEX"to cards that were pre-burnt with blank GUIDs. It is not meant for\n" + INDENTEX"use in field.\n" + INDENTEX"- On 4th generation devices, this command can operate on both image file and image on flash.\n" + INDENTEX"If the GUIDs/MACs/UIDs in the image on flash are non-blank,\n" + INDENTEX"flint will re-burn the current image using the given GUIDs/MACs/UIDs."; + _flagLong = "sg"; + _flagShort = ""; + _param = "[nocrc]"; + _paramExp = "nocrc: (optional) When specified the flint would not update\n" + INDENTEX"the full image crc after changing the guids"; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" -guid 0x0002c9000100d050 sg"; + _v = Wtv_Dev_Or_Img; + _cmdType = SC_Sg; +} + +SgSubCommand:: ~SgSubCommand() +{ + +} + +bool SgSubCommand::verifyParams() +{ + if (_flintParams.cmd_params.size() == 1 && _flintParams.cmd_params[0] != "nocrc") { + reportErr(true, "The sg parameter should be \"nocrc\" or nothing\n"); + return false; + } + if (_flintParams.cmd_params.size()> 1) { + reportErr(true, FLINT_CMD_ARGS_ERROR2,_name.c_str(), 1, (int)_flintParams.cmd_params.size()); + return false; + } + if (!(_flintParams.guid_specified || _flintParams.guids_specified ||\ + _flintParams.uid_specified || _flintParams.uids_specified || \ + _flintParams.mac_specified || _flintParams.macs_specified)){ + reportErr(true, FLINT_COMMAND_FLAGS_ERROR, _name.c_str(), "GUIDs / MACs (using command line flags -guid(s) / -mac(s) )"); + return false; + } + if ((_flintParams.guid_specified || _flintParams.guid_specified) && (_flintParams.uid_specified || _flintParams.uids_specified)) { + reportErr(true, FLINT_COMMAND_FLAGS_ERROR, _name.c_str(), "either GUIDs / UIDs (using command line flags -guid(s) / -uid(s) )"); + return false; + } + if ((_flintParams.mac_specified || _flintParams.macs_specified) && (_flintParams.uid_specified || _flintParams.uids_specified)) { + reportErr(true, FLINT_COMMAND_FLAGS_ERROR, _name.c_str(), "either MACs / UIDs (using command line flags -mac(s) / -uid(s) )"); + return false; + } + if (_flintParams.guid_specified && _flintParams.guids_specified) { + reportErr(true, FLINT_INVALID_FLAG_WITH_FLAG_ERROR, "-guids", "-guid" ); + return false; + } + if (_flintParams.mac_specified && _flintParams.macs_specified) { + reportErr(true, FLINT_INVALID_FLAG_WITH_FLAG_ERROR, "-macs", "-mac" ); + return false; + } + if (_flintParams.uid_specified && _flintParams.uids_specified) { + reportErr(true, FLINT_INVALID_FLAG_WITH_FLAG_ERROR, "-uids", "-uid" ); + return false; + } + + _sgParams.guidsSpecified = _flintParams.guid_specified || _flintParams.guids_specified; + _sgParams.macsSpecified = _flintParams.mac_specified || _flintParams.macs_specified; + _sgParams.uidsSpecified = _flintParams.uid_specified || _flintParams.uids_specified; + _sgParams.updateCrc = !(_flintParams.cmd_params.size() == 1); + _sgParams.stripedImage = _flintParams.striped_image; + + return true; +} + +void SgSubCommand::setUserGuidsAndMacs() +{ + // _sgParams.userGuids contains either guids and macs (or just guids) or just uids + // we are required to specifiy to mlxfwops a guid vector of MAX_GUIDS size regardless if user gives only guids + // or only macs or uids + if ( _sgParams.guidsSpecified) { + + _sgParams.userGuids = _flintParams.user_guids; + } + if (_sgParams.macsSpecified) { + if (!_sgParams.guidsSpecified) { + //it inits the guids with zeroes but mlxfwops will set them to 0xffff + //can set default init if needed + _sgParams.userGuids.resize(GUIDS); + } + _sgParams.userGuids.push_back(_flintParams.user_macs[0]); + _sgParams.userGuids.push_back(_flintParams.user_macs[1]); + } + if (_sgParams.uidsSpecified) { + _sgParams.userGuids = _flintParams.user_uids; + } + _sgParams.userGuids.resize(MAX_GUIDS); +} + +bool SgSubCommand::CheckSetGuidsFlags() +{ + bool ibDev; + bool ethDev; + bool bxDev = _info.fw_info.chip_type == CT_BRIDGEX; + FwOperations::SetDevFlags(_info.fw_info.chip_type, _info.fw_info.dev_type, (fw_img_type)_info.fw_type, ibDev, ethDev); + //setDevFlags(_info, ibDev,ethDev); + + if (_sgParams.macsSpecified || _sgParams.guidsSpecified || _sgParams.uidsSpecified) { + if (!checkGuidsFlags((chip_type_t)_info.fw_info.chip_type, _info.fw_info.dev_type,_info.fw_type,\ + _sgParams.guidsSpecified, _sgParams.macsSpecified, _sgParams.uidsSpecified)) { + return false; + } + } else { + printf("-E- "); + printMissingGuidErr(ibDev, ethDev, bxDev); + printf("\n"); + return false; + } + + return true; +} + +FlintStatus SgSubCommand::sgFs2() +{ + //different behaviours for fs2 device with blank guids and fs2 device with guids or image + //different behaviour if isfailesafe or not + + if (_flintParams.device_specified && !_info.fs2_info.blank_guids) { + // 2- FS2 device with no blank Guids + printf(FLINT_SET_GUIDS_WARRNING); + } + + if (!CheckSetGuidsFlags()){ + return FLINT_FAILED; + } + + if (_flintParams.image_specified || !_info.fs2_info.blank_guids) { + //report guid changes + bool ethDev; + bool ibDev; + bool bxDev = _info.fw_info.chip_type == CT_BRIDGEX; + FwOperations::SetDevFlags(_info.fw_info.chip_type, _info.fw_info.dev_type, (fw_img_type)_info.fw_type, ibDev, ethDev); + //setDevFlags(_info, ibDev, ethDev); + //decide what are our new guids/macs + guid_t *new_guids = (_sgParams.guidsSpecified ||_sgParams.uidsSpecified) ? & _sgParams.userGuids[0] : &_info.fs2_info.guids[0] ; + guid_t *new_macs = _sgParams.macsSpecified ? &_sgParams.userGuids[GUIDS] : &_info.fs2_info.guids[GUIDS] ; + + if (!reportGuidChanges(new_guids, new_macs, &_info.fs2_info.guids[0], &_info.fs2_info.guids[GUIDS], ibDev,\ + ethDev, bxDev, _info.fs2_info.guid_num)){ + return FLINT_FAILED; + } + } + if (!_ops->FwSetGuids(_sgParams, &verifyCbFunc, &burnCbFs2Func)) { + reportErr(true, FLINT_SG_GUID_ERROR, _ops->err()); + return FLINT_FAILED; + } + burnCbFs2Func(101); + return FLINT_SUCCESS; +} + +FlintStatus SgSubCommand::sgFs3() +{ + if ( _flintParams.uid_specified) { + // for golan we just need the base guid so we put it in the first location. + _sgParams.userGuids.resize(1); + _sgParams.userGuids[0]= _flintParams.baseUid; + if (!_ops->FwSetGuids(_sgParams, &verifyCbFunc)) { + reportErr(true, FLINT_SG_UID_ERROR, _ops->err()); + return FLINT_FAILED; + } + } else { + reportErr(true, "Can not set GUIDs/MACs: uid is not specified, please run with -uid flag.\n"); + return FLINT_FAILED; + } + return FLINT_SUCCESS; +} + +FlintStatus SgSubCommand::executeCommand() +{ + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + // query device + _ops = _flintParams.device_specified ? _fwOps : _imgOps; + bool stripedImage = _flintParams.striped_image && _flintParams.image_specified; + if (!_ops->FwQuery(&_info, true, stripedImage)) { + reportErr(true, FLINT_SG_GUID_ERROR, _ops->err()); + return FLINT_FAILED; + } + setUserGuidsAndMacs(); + if (_info.fw_type == FIT_FS2) { + return sgFs2(); + } + return sgFs3(); +} + +/***************************** + *Class: Set Manufacture GUIDs + *****************************/ +SmgSubCommand:: SmgSubCommand() +{ + _name = "smg"; + _desc = "Set manufacture GUIDs (For FS3 image only)."; + _extendedDesc = "Set manufacture GUID, Set manufacture GUIDs in the given FS3 image.\n" + INDENTEX"Use -uid flag to set the desired GUIDs."; + _flagLong = "smg"; + _flagShort = ""; + _param = ""; + _paramExp = "None"; + _example = FLINT_NAME" -i fw_image.bin -uid 0x0002c9000100d050 smg"; + _v = Wtv_Dev_Or_Img; + _cmdType = SC_Smg; +} + +SmgSubCommand:: ~SmgSubCommand() +{ + +} + +bool SmgSubCommand::verifyParams() +{ + if (!_flintParams.uid_specified) { + reportErr(true, FLINT_COMMAND_FLAGS_ERROR, _name.c_str(), "\"-uid\" flag"); + return false; + } + if (_flintParams.uids_specified) { + reportErr(true, FLINT_INVALID_OPTION_ERROR, "\"-uids\"", _name.c_str(), "\"-uid\""); + return false; + } + _baseGuid = _flintParams.baseUid; + //printf("-D-"GUID_FORMAT"\n", _baseGuid.h, _baseGuid.l); + return true; +} + +FlintStatus SmgSubCommand::executeCommand() +{ + if (preFwOps()) { + return FLINT_FAILED; + } + FwOperations *ops = _flintParams.device_specified ? _fwOps : _imgOps; + //TODO: dispaly MFG guid changes + if (!ops->FwSetMFG(_baseGuid, &verifyCbFunc)) { + reportErr(true, FLINT_MFG_ERROR, ops->err()); + return FLINT_FAILED; + } + return FLINT_SUCCESS; +} + + +/*********************** + *Class: + **********************/ +SetVpdSubCommand:: SetVpdSubCommand() +{ + _name = "set vpd"; + _desc = "Set read-only VPD (For FS3 image only)."; + _extendedDesc = "Set Read-only VPD, Set VPD in the given FS3 image."; + _flagLong = "set_vpd"; + _flagShort = ""; + _param = "[vpd file]"; + _paramExp = "vpd file: bin file containing the vpd data"; + _example = FLINT_NAME" -i fw_image.bin set_vpd vpd.bin"; + _v = Wtv_Dev_Or_Img; + _cmdType = SC_Set_Vpd; +} + +SetVpdSubCommand:: ~SetVpdSubCommand() +{ + +} + +bool SetVpdSubCommand:: verifyParams() +{ + if( _flintParams.cmd_params.size() != 1) { + reportErr(true, FLINT_CMD_ARGS_ERROR, _name.c_str(), 1, (int)_flintParams.cmd_params.size()); + return false; + } + return true; +} + +FlintStatus SetVpdSubCommand:: executeCommand() +{ + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + FwOperations *ops = _flintParams.device_specified ? _fwOps : _imgOps; + if (!ops->FwSetVPD((char*)_flintParams.cmd_params[0].c_str(), &verifyCbFunc)) { + reportErr(true, FLINT_VPD_ERROR, ops->err()); + return FLINT_FAILED; + } + return FLINT_SUCCESS; +} + +/*********************** + *Class: Set VSD + **********************/ +SvSubCommand:: SvSubCommand() +{ + _name = "sv"; + _desc = "Set the VSD."; + _extendedDesc = "Set VSD in the given device/image.\n" + INDENTEX"Use -vsd flag to set the desired VSD string."; + _flagLong = "sv"; + _flagShort = ""; + _param = ""; + _paramExp = "None"; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" -vsd VSD_STRING sv"; + _v = Wtv_Dev_Or_Img; + _cmdType = SC_Sv; +} + +SvSubCommand:: ~SvSubCommand() +{ + +} + +bool SvSubCommand::verifyParams() +{ + if (!_flintParams.vsd_specified) { + reportErr(true, FLINT_COMMAND_FLAGS_ERROR, _name.c_str(), "\"-vsd\""); + return false; + } + // we verify that -vsd has a parameter in the cmd parser + + return true; +} + +FlintStatus SvSubCommand::executeCommand() +{ + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + FwOperations* ops = _flintParams.device_specified ? _fwOps : _imgOps; + if (!ops->FwSetVSD((char*)_flintParams.vsd.c_str(), &vsdCbFunc, &verifyCbFunc)) { + reportErr(true, FLINT_VSD_ERROR, ops->err()); + return FLINT_FAILED; + } + vsdCbFunc(101); + return FLINT_SUCCESS; +} + + + +/******************************* + *Class: Read Image SubCommand + ******************************/ +RiSubCommand:: RiSubCommand() +{ + _name = "ri"; + _desc = "Read the fw image on the flash."; + _extendedDesc = "Read the FW image from flash and write it to a file."; + _flagLong = "ri"; + _flagShort = ""; + _param = ""; + _paramExp = "file: filename to write the image to (raw binary)."; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" ri file.bin"; + _v = Wtv_Dev; + _cmdType = SC_Ri; +} + +RiSubCommand:: ~RiSubCommand() +{ + +} + +bool RiSubCommand::verifyParams() { + if (_flintParams.cmd_params.size() != 1) { + reportErr(true, FLINT_CMD_ARGS_ERROR,_name.c_str() , 1, (int)_flintParams.cmd_params.size()); + return false; + } + return true; +} + +FlintStatus RiSubCommand::executeCommand() { + //init fw operation object + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + // Check if we have permission to write to file + FILE* fh; + if ((fh = fopen(_flintParams.cmd_params[0].c_str(), "wb")) == NULL) { + reportErr(true, "Can not open %s: %s\n", _flintParams.cmd_params[0].c_str(), strerror(errno)); + return FLINT_FAILED; + } else { + fclose(fh); + } + u_int32_t imgSize; + //on first call we get the image size + if (!_fwOps->FwReadData(NULL, &imgSize)) { + reportErr(true, FLINT_IMAGE_READ_ERROR, _fwOps->err()); + return FLINT_FAILED; + } + std::vector imgBuff(imgSize); + //on second call we fill it + if (!_fwOps->FwReadData((void*)(&imgBuff[0]),&imgSize)) { + reportErr(true, FLINT_IMAGE_READ_ERROR, _fwOps->err()); + return FLINT_FAILED; + } + return writeImageToFile(_flintParams.cmd_params[0].c_str(), &(imgBuff[0]), imgSize ); +} + +FlintStatus RiSubCommand::writeImageToFile(const char *file_name, u_int8_t *data, u_int32_t length) +{ + FILE* fh; + if ((fh = fopen(file_name, "wb")) == NULL) { + reportErr(true, "Can not open %s: %s\n", file_name, strerror(errno)); + return FLINT_FAILED; + } + + // Write output + if (fwrite(data, 1, length, fh) != length) { + fclose(fh); + reportErr(true, "Failed to write to %s: %s\n", file_name, strerror(errno)); + return FLINT_FAILED; + } + fclose(fh); + return FLINT_SUCCESS; +} + +/*********************** + *Class: Dump Conf SubCommand + **********************/ +DcSubCommand:: DcSubCommand() { + _name = "dc"; + _desc = "Dump Configuration: print fw configuration file for the given image."; + _extendedDesc = "Print (to screen or to a file) the FW configuration text file used by the image generation process.\n" + INDENTEX"This command would fail if the image does not contain a FW configuration section. Existence of this\n" + INDENTEX"section depends on the version of the image generation tool."; + _flagLong = "dc"; + _flagShort = ""; + _param = "[out-file]"; + _paramExp = "file: (optional) filename to write the dumped configuration to. If not given, the data\n" + INDENTEX"is printed to screen"; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" dc"; + _v = Wtv_Dev_Or_Img; + _cmdType = SC_Dc; +} + +DcSubCommand:: ~DcSubCommand() { + +} + +bool DcSubCommand::verifyParams() { + if (_flintParams.cmd_params.size() > 1) { + reportErr(true, FLINT_CMD_ARGS_ERROR2, _name.c_str(), 1, (int)_flintParams.cmd_params.size()); + return false; + } + return true; +} + +FlintStatus DcSubCommand::executeCommand() { + FwOperations* ops; + //init fw operation object + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + //check on what we are wroking + ops = (_flintParams.device_specified) ? _fwOps : _imgOps; + const char* file = _flintParams.cmd_params.size() == 1 ? _flintParams.cmd_params[0].c_str() : (const char*) NULL; + if (!ops->FwGetSection(H_FW_CONF, _sect)) { + reportErr(true, FLINT_DUMP_ERROR, "Fw Configuration", ops->err()); + return FLINT_FAILED; + } + if (!dumpFile(file, _sect, "Fw Configuration")) { + return FLINT_FAILED; + } + return FLINT_SUCCESS; +} + +/*********************** + *Class:Dump Hash SubCommand + **********************/ +DhSubCommand:: DhSubCommand() +{ + _name = "dh"; + _desc = "Dump Hash: dump the hash if it is integrated in the FW image"; + _extendedDesc = "Print (to screen or to a file) the HASH text file used by the FW.\n" + INDENTEX"This command would fail if the image does not contain a Hash file."; + _flagLong = "dh"; + _flagShort = ""; + _param = "[out-file]"; + _paramExp = "file - (optional) filename to write the dumped tracer hash file to. If not given, the data\n" + INDENTEX"is printed to screen"; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" dh hash.csv"; + _v = Wtv_Dev_Or_Img; + _cmdType = SC_Dh; +} + +DhSubCommand:: ~DhSubCommand() +{ + +} + +bool DhSubCommand::verifyParams() { + if (_flintParams.cmd_params.size() > 1) { + reportErr(true, FLINT_CMD_ARGS_ERROR2, _name.c_str(), 1, (int)_flintParams.cmd_params.size()); + return false; + } + return true; +} + +FlintStatus DhSubCommand::executeCommand() { + FwOperations* ops; + //init fw operation object + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + //check on what we are wroking + ops = (_flintParams.device_specified) ? _fwOps : _imgOps; + const char* file = _flintParams.cmd_params.size() == 1 ? _flintParams.cmd_params[0].c_str() : (const char*) NULL; + if (!ops->FwGetSection(H_HASH_FILE, _sect)) { + reportErr(true, FLINT_DUMP_ERROR, "Hash file", ops->err()); + return FLINT_FAILED; + } + if (!dumpFile(file, _sect, "Fw Configuration")) { + return FLINT_FAILED; + } + return FLINT_SUCCESS; +} + +/*********************** + *Class:Set Key SubCommand + **********************/ +SetKeySubCommand:: SetKeySubCommand() +{ + _name = "set_key"; + _desc = "Set/Update the HW access key which is used to enable/disable access to HW.\n" + INDENT"The key can be provided in the command line or interactively typed after\n" + INDENT"the command is given\n" + INDENT"NOTE: The new key is activated only after the device is reset."; + _extendedDesc = "Set/Update the HW access key which is used to enable/disable access to HW."; + _flagLong = "set_key"; + _flagShort = ""; + _param = "[key]"; + _paramExp = "key: (optional) The new key you intend to set (in hex)."; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" set_key 1234deaf5678"; + _v = Wtv_Dev; + _cmdType = SC_Set_Key; +} + +SetKeySubCommand:: ~SetKeySubCommand() +{ + +} + +bool SetKeySubCommand::verifyParams() +{ + if (_flintParams.cmd_params.size() > 1 ) { + reportErr(true, FLINT_CMD_ARGS_ERROR2, _name.c_str(), 1, (int)_flintParams.cmd_params.size()); + return false; + } + _getKeyInter = (_flintParams.cmd_params.size() == 0); + return true; +} + +bool SetKeySubCommand::getKeyInteractively() +{ + char keyArr[MAX_PASSWORD_LEN]; + getPasswordFromUser("Enter Key ", keyArr ); + if (!getGUIDFromStr(keyArr, _userKey,\ + "-E- Invalid Key syntax, it should contain only hexa numbers.")) { + return false; + } + // verify key + hw_key_t verKey; + getPasswordFromUser("Verify Key ", keyArr ); + if (!getGUIDFromStr(keyArr, verKey,\ + "-E- Invalid Key syntax, it should contain only hexa numbers.")) { + return false; + } + if (_userKey.h != verKey.h || _userKey.l != verKey.l) { + reportErr(true, FLINT_SET_KEY_ERROR, "The keys you entered did not match."); + return false; + } + return true; +} + +FlintStatus SetKeySubCommand::executeCommand () +{ + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + +#ifdef __WN__ + reportErr(true, FLINT_WIN_NOT_SUPP_ERROR, _name); + return FLINT_FAILED; +#endif + + if (_getKeyInter) { + if (!getKeyInteractively()) { + return FLINT_FAILED; + } + } else { + if (!getGUIDFromStr(_flintParams.cmd_params[0], _userKey, \ + "Invalid Key syntax, it should contain only hexa numbers.")) { + return FLINT_FAILED; + } + } + if (!_fwOps->FwSetAccessKey(_userKey, &setKeyCbFunc)) { + reportErr(true, FLINT_SET_KEY_ERROR, _fwOps->err()); + return FLINT_FAILED; + } + setKeyCbFunc(101); + printf("\n-I- New key was updated successfully in the flash."\ + "In order to activate the new key you should reboot or restart the driver.\n"); + + return FLINT_SUCCESS; +} + +/*********************** + *Class:HwAccess SubCommand + **********************/ +HwAccessSubCommand:: HwAccessSubCommand() +{ + _name = "hw_access"; + _desc = "Enable/disable the access to the HW.\n" + INDENT"The key can be provided in the command line or interactively typed after\n" + INDENT"the command is given"; + _extendedDesc = "Enable/disable the access to the HW."; + _flagLong = "hw_access"; + _flagShort = ""; + _param = " [key]"; + _paramExp = ": Specify if you intend to disable or enable the HW access.\n" + INDENTEX" You will be asked to type a key when you try to enable HW access.\n" + INDENTEX"key: (optional) The key you intend to use for enabling the HW access."; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" hw_access enable"; + _v = Wtv_Dev; + _cmdType = SC_Hw_Access; +} + +HwAccessSubCommand:: ~HwAccessSubCommand() +{ + +} + +bool HwAccessSubCommand::verifyParams() +{ + if (_flintParams.cmd_params.size() == 0) { + reportErr(true, FLINT_MISSED_ARG_ERROR,"",_name.c_str()); + return false; + } + if (_flintParams.cmd_params.size() > 2) { + reportErr(true, FLINT_CMD_ARGS_ERROR2, _name.c_str(), 2, (int)_flintParams.cmd_params.size()); + return false; + } + if( _flintParams.cmd_params[0] != "enable" && _flintParams.cmd_params[0] != "disable") { + reportErr(true, FLINT_INVALID_OPTION_ERROR, _flintParams.cmd_params[0].c_str(), _name.c_str(), "enable or disable"); + return false; + } + return true; +} + +FlintStatus HwAccessSubCommand:: disableHwAccess() +{ + if (((Flash*)_io)->get_cr_space_locked()) { + printf("-I- HW access already disabled\n"); + } else { + if (!((Flash*)_io)->disable_hw_access()) { + printf(FLINT_GEN_COMMAND_ERROR, _name.c_str(), _io->err()); + return FLINT_FAILED; + } + } + return FLINT_SUCCESS; +} +FlintStatus HwAccessSubCommand:: enableHwAccess() +{ + u_int64_t key; + if (((Flash*)_io)->get_cr_space_locked() == 0) { + printf("-I- HW access already enabled\n"); + } else { + hw_key_t keyStruct; + //now we need to get the key from the user (either given in the parameters or we get it during runtime) + if (_flintParams.cmd_params.size() == 2) { + if (!getGUIDFromStr(_flintParams.cmd_params[1], keyStruct,\ + "-E- Invalid Key syntax, it should contain only hexa numbers.")) { + return FLINT_FAILED; + } + } else {//we need to get the key from user during runtime + char keyArr[MAX_PASSWORD_LEN]; + getPasswordFromUser("Enter Key ", keyArr ); + if (!getGUIDFromStr(keyArr, keyStruct,\ + "-E- Invalid Key syntax, it should contain only hexa numbers.")) { + return FLINT_FAILED; + } + } + key = ((u_int64_t)keyStruct.h << 32) | keyStruct.l; + if (!((Flash*)_io)->enable_hw_access(key)) { + reportErr(true, FLINT_GEN_COMMAND_ERROR, _name.c_str(), _io->err()); + return FLINT_FAILED; + } + } + return FLINT_SUCCESS; +} + +FlintStatus HwAccessSubCommand:: executeCommand() +{ +#ifdef __WIN__ + reportErr(true, FLINT_WIN_NOT_SUPP_ERROR, _name.c_str()); + return FLINT_FAILED; +#endif + if (preFwAccess() == FLINT_FAILED) { + return FLINT_FAILED; + } + if (_flintParams.cmd_params[0] == "disable") { + return disableHwAccess(); + } + //else its enable hw access + return enableHwAccess(); +} + +/*********************** + *Class: Hw SubCommand + **********************/ +HwSubCommand:: HwSubCommand() +{ +#ifndef EXTERNAL + _name = "hw"; + _desc = "Set/query HW info and flash attributes."; + _extendedDesc = "Access HW info and flash attributes."; + _flagLong = "hw"; + _flagShort = ""; + _param = " [ATTR=VAL]"; + _paramExp = "query: query HW info\n" + INDENTEX"set [ATTR=VAL]: set flash attribure\n" + INDENTEX"Supported attributes:\n" + INDENTEX" QuadEn: can be 0 or 1\n" + INDENTEX" Flash[0|1|2|3].WriteProtected can be:\n" + INDENTEX" ,<1|2|4|8|16|32|64>-"; + _example = "flint -d /dev/mst/mt4099_pci_cr0 hw query\n" + INDENTEX FLINT_NAME" -d "MST_DEV_EXAMPLE1" hw set QuadEn=1\n" + INDENTEX FLINT_NAME" -d "MST_DEV_EXAMPLE1" hw set Flash1.WriteProtected=Top,1-SubSectors"; +#else + _name = "Hw"; + _desc = "Query HW info and flash attributes."; + _extendedDesc = "Query HW info and flash attributes."; + _flagLong = "hw"; + _flagShort = ""; + _param = "query"; + _paramExp = "query"; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" hw query"; +#endif + _v = Wtv_Dev; + _cmdType = SC_Hw; +} + +HwSubCommand:: ~HwSubCommand() +{ + +} + +bool HwSubCommand::verifyParams() { +#ifdef EXTERNAL + if (_flintParams.cmd_params.size() != 1) { + reportErr(true, FLINT_CMD_ARGS_ERROR2, _name.c_str(), 1, (int)_flintParams.cmd_params.size()); + return false; + } + + if (_flintParams.cmd_params[0] != "query"){ + reportErr(true, FLINT_INVALID_OPTION_ERROR, _flintParams.cmd_params[0].c_str(), _name.c_str(), "query"); + return false; + } +#else + if (_flintParams.cmd_params.size() > 2 || _flintParams.cmd_params.size() == 0) { + reportErr(true, FLINT_CMD_ARGS_ERROR2, _name.c_str(), 2, (int)_flintParams.cmd_params.size()); + return false; + } + if ((_flintParams.cmd_params[0] != "query") && (_flintParams.cmd_params[0] != "set")) { + reportErr(true, FLINT_INVALID_OPTION_ERROR, _flintParams.cmd_params[0].c_str(), _name.c_str(), "query or set"); + return false; + } + if ((_flintParams.cmd_params[0] == "set") && (_flintParams.cmd_params.size() != 2)) { + reportErr(true, FLINT_CMD_ARGS_ERROR, _name.c_str(),2 , (int)_flintParams.cmd_params.size()); + return false; + } +#endif + + return true; +} + +FlintStatus HwSubCommand::printAttr(const ext_flash_attr_t& attr) { + printf("HW Info:\n"); + printf(" HwDevId %d\n", attr.hw_dev_id); + printf(" HwRevId 0x%x\n", attr.rev_id); + + printf("Flash Info:\n"); + if (attr.type_str != NULL) { + // we don't print the flash type in old devices + printf(" Type %s\n", attr.type_str); + } + printf(" TotalSize 0x%x\n", attr.size); + printf(" Banks 0x%x\n", attr.banks_num); + printf(" SectorSize 0x%x\n", attr.sector_size ); + printf(" WriteBlockSize 0x%x\n", attr.block_write); + printf(" CmdSet 0x%x\n", attr.command_set); + + // Quad EN query + if (attr.quad_en_support) { + switch (attr.mf_get_quad_en_rc) { + case MFE_OK: + printf(" "QUAD_EN_PARAM" %d\n", attr.quad_en); + break; + case MFE_MISMATCH_QUAD_EN: + printf("-E- There is a mismatch in the "QUAD_EN_PARAM" attribute between the flashes attached to the device\n"); + break; + case MFE_NOT_SUPPORTED_OPERATION: + break; + default: + printf("Failed to get "QUAD_EN_PARAM" attribute: %s (%s)",\ + errno == 0 ? "" : strerror(errno), mf_err2str(attr.mf_get_quad_en_rc)); + return FLINT_FAILED; + } + } + // Flash write protected info query + if (attr.write_protect_support) { + int bank; + int rc; + for (bank = 0; bank < attr.banks_num; bank++) { + write_protect_info_t protect_info = attr.protect_info_array[bank]; + rc = attr.mf_get_write_protect_rc_array[bank]; + if (rc == MFE_OK) { + printf(" "FLASH_NAME"%d."WRITE_PROTECT" ", bank); + if (protect_info.sectors_num != 0) { + printf("%s,", (protect_info.is_bottom ? WP_BOTTOM_STR : WP_TOP_STR)); + printf("%d-", protect_info.sectors_num); + printf("%s\n", (protect_info.is_subsector ? WP_SUBSEC_STR : WP_SEC_STR)); + } else { + printf(WP_DISABLED_STR"\n"); + } + } else { + if (rc != MFE_NOT_SUPPORTED_OPERATION) { // We ignore the read when operation is not supported! + printf("Failed to get write_protected info: %s (%s)", errno == 0 ? "" : strerror(errno), mf_err2str(rc)); + return FLINT_FAILED; + } + } + } + } + return FLINT_SUCCESS; +} + +FlintStatus HwSubCommand::executeCommand() +{ + //init fw operation object + if (preFwAccess() == FLINT_FAILED) { + return FLINT_FAILED; + } + if (_flintParams.cmd_params[0] == "set") { + char* cmdParam = strcpy(new char[_flintParams.cmd_params[1].size() + 1], + _flintParams.cmd_params[1].c_str()); + char *paramName, *paramValStr; + paramName = strtok(cmdParam, "="); + paramValStr = strtok(NULL, "="); + //printf("-D- param_name = %s, param_val_str=%s, cmdParam=%s\n", paramName, paramValStr, cmdParam); + if (paramName == NULL || paramValStr == NULL) { + delete[] cmdParam; + reportErr(true, FLINT_HW_SET_ARGS_ERROR, _flintParams.cmd_params[1].c_str()); + return FLINT_FAILED; + } + if (!((Flash*) _io)->set_attr(paramName, paramValStr)) { + delete[] cmdParam; + reportErr(true, FLINT_HW_COMMAND_ERROR, "set", _io->err()); + return FLINT_FAILED; + } + printf("-I- %s parameter was set successfully\n", paramName); + delete[] cmdParam; + } else { + ext_flash_attr_t attr; + attr.type_str = (char*)NULL; + if (!((Flash*) _io)->get_attr(attr)) { + reportErr(true, FLINT_HW_COMMAND_ERROR, "query", _io->err()); + if (attr.type_str) { + delete[] attr.type_str; + } + return FLINT_FAILED; + } + FlintStatus rc = printAttr(attr); + //str is allocated in get_attr + if (attr.type_str) { + delete[] attr.type_str; + } + if (rc == FLINT_FAILED) { + return FLINT_FAILED; + } + + } + return FLINT_SUCCESS; +} + +/************************** + *Class: Erase SubCommand + *************************/ +EraseSubCommand:: EraseSubCommand() +{ + _name = "erase"; + _desc = "Erases sector."; + _extendedDesc = "Erases a sector that contains specified address."; + _flagLong = "erase"; + _flagShort = "e"; + _param = ""; + _paramExp = "addr - address of word in sector that you want to erase."; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" erase 0x10000"; + _v = Wtv_Dev; + _cmdType = SC_Erase; +} + +EraseSubCommand:: ~EraseSubCommand() +{ + +} + +bool EraseSubCommand::verifyParams() { + if (_flintParams.cmd_params.size() != 1) { + reportErr(true, FLINT_CMD_ARGS_ERROR,_name.c_str() , 1, (int)_flintParams.cmd_params.size()); + return false; + } + //parameter format will be checked in executeCommand. + return true; +} + +FlintStatus EraseSubCommand::executeCommand() { + if (preFwAccess() == FLINT_FAILED) { + return FLINT_FAILED; + } + u_int32_t addr; + char *addrStr = strcpy(new char[_flintParams.cmd_params[0].size() + 1], _flintParams.cmd_params[0].c_str()); + char *endp; + // Address of sector to erase + addr = strtoul(addrStr, &endp, 0); + if (*endp) { + reportErr(true, FLINT_INVALID_ADDR_ERROR, _flintParams.cmd_params[0].c_str()); + delete[] addrStr; + return FLINT_FAILED; + } + delete[] addrStr; + // Erase + if (!((Flash*)_io)->erase_sector(addr)) { + reportErr(true, FLINT_ERASE_SEC_ERROR, _io->err()); + return FLINT_FAILED; + } + return FLINT_SUCCESS; +} + +/***************************** + *Class: Read Dword SubCommand + *****************************/ +RwSubCommand:: RwSubCommand() { + _name = "rw"; + _desc = "Read one dword from flash"; + _extendedDesc = "Read one dword from flash."; + _flagLong = "rw"; + _flagShort = ""; + _param = ""; + _paramExp = "addr - address of word to read"; + _example = "flint -d /dev/mst/mt4099_pci_cr0 rw 0x20"; + _v = Wtv_Dev_Or_Img; + _cmdType = SC_Rw; +} + +RwSubCommand:: ~RwSubCommand() { + +} + +bool RwSubCommand::verifyParams() { + if (_flintParams.cmd_params.size() != 1) { + reportErr(true, FLINT_CMD_ARGS_ERROR,_name.c_str() , 1, (int)_flintParams.cmd_params.size()); + return false; + } + return true; +} + +FlintStatus RwSubCommand::executeCommand() { + if (preFwAccess() == FLINT_FAILED) { + return FLINT_FAILED; + } + u_int32_t addr; + u_int32_t data; + char *addrStr = strcpy(new char[_flintParams.cmd_params[0].size() + 1], _flintParams.cmd_params[0].c_str()); + char *endp; + addr = strtoul(addrStr, &endp, 0); + if (*endp) { + reportErr(true, FLINT_INVALID_ADDR_ERROR, _flintParams.cmd_params[0].c_str()); + delete[] addrStr; + return FLINT_FAILED; + } + delete[] addrStr; + if (_flintParams.device_specified ? !((Flash*)_io)->read(addr, &data)\ + : !((FImage*)_io)->read(addr, &data)) { + reportErr(true, FLINT_FLASH_READ_ERROR, _io->err()); + return FLINT_FAILED; + } + printf("0x%08x\n", (unsigned int)__cpu_to_be32(data)); + return FLINT_SUCCESS; +} + +/****************************** + *Class: Write Dword Subcommand + ******************************/ +WwSubCommand:: WwSubCommand() +{ + _name = "ww"; + _desc = "Write one dword to flash"; + _extendedDesc = "Write one dword to flash.\n" + INDENTEX"Note that the utility will read an entire flash sector,\n" + INDENTEX"modify one word and write the sector back. This may take\n" + INDENTEX"a few seconds."; + _flagLong = "ww"; + _flagShort = ""; + _param = " "; + _paramExp = "addr - address of word\n" + INDENTEX"data - value of word"; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" ww 0x10008 0x5a445a44"; + _v = Wtv_Dev; + _cmdType = SC_Ww; +} + +WwSubCommand:: ~WwSubCommand() +{ + +} + +bool WwSubCommand::verifyParams() { + if (_flintParams.cmd_params.size() != 2) { + reportErr(true, FLINT_CMD_ARGS_ERROR,_name.c_str() , 2, (int)_flintParams.cmd_params.size()); + return false; + } + return true; +} + +FlintStatus WwSubCommand::executeCommand() { + //init fw operation object + if (preFwAccess() == FLINT_FAILED) { + return FLINT_FAILED; + } + u_int32_t addr; + u_int32_t data; + char *addrStr = strcpy(new char[_flintParams.cmd_params[0].size() + 1], _flintParams.cmd_params[0].c_str()); + char *dataStr = strcpy(new char[_flintParams.cmd_params[1].size() + 1], _flintParams.cmd_params[1].c_str()); + char *endp; + addr = strtoul(addrStr, &endp, 0); + if (*endp) { + reportErr(true, FLINT_INVALID_ADDR_ERROR, _flintParams.cmd_params[0].c_str()); + delete[] addrStr; + delete[] dataStr; + return FLINT_FAILED; + } + data =strtoul(dataStr, &endp, 0); + if (*endp) { + reportErr(true, FLINT_INVALID_DATA_ERROR, _flintParams.cmd_params[1].c_str()); + delete[] addrStr; + delete[] dataStr; + return FLINT_FAILED; + } + delete[] addrStr; + delete[] dataStr; + data = __cpu_to_be32(data); + if (!((Flash*)_io)->write(addr, data)) { + reportErr(true, FLINT_FLASH_WRITE_ERROR, _io->err()); + return FLINT_FAILED; + } + return FLINT_SUCCESS; +} +/*************************************** + *Class: Write Dword No Erase SubCommand + ***************************************/ +WwneSubCommand:: WwneSubCommand() +{ + _name = "wwne"; + _desc = "Write one dword to flash without sector erase"; + _extendedDesc = "Write one dword to flash without sector erase.\n" + INDENTEX"Note that the result of operation is undefined and depends\n" + INDENTEX"on flash type. Usually \"bitwise AND\" (&) between specified\n" + INDENTEX"word and previous flash contents will be written to\n" + INDENTEX"specified address."; + _flagLong = "wwne"; + _flagShort = ""; + _param = " "; + _paramExp = "addr - address of word\n" + INDENTEX"data - value of word"; + _example = "flint -d /dev/mst/mt4099_pci_cr0 wwne 0x10008 0x5a445a44"; + _v = Wtv_Dev; + _cmdType = SC_Wwne; +} + +WwneSubCommand:: ~WwneSubCommand() +{ + +} + +bool WwneSubCommand::verifyParams() { + if (_flintParams.cmd_params.size() != 2) { + reportErr(true, FLINT_CMD_ARGS_ERROR,_name.c_str() , 2, (int)_flintParams.cmd_params.size()); + return false; + } + return true; +} + +FlintStatus WwneSubCommand::executeCommand() { + //init fw operation object + if (preFwAccess() == FLINT_FAILED) { + return FLINT_FAILED; + } + u_int32_t addr; + u_int32_t data; + char *addrStr = strcpy(new char[_flintParams.cmd_params[0].size() + 1], _flintParams.cmd_params[0].c_str()); + char *dataStr = strcpy(new char[_flintParams.cmd_params[1].size() + 1], _flintParams.cmd_params[1].c_str()); + char *endp; + addr = strtoul(addrStr, &endp, 0); + if (*endp) { + reportErr(true, FLINT_INVALID_ADDR_ERROR, _flintParams.cmd_params[0].c_str()); + delete[] addrStr; + delete[] dataStr; + return FLINT_FAILED; + } + data =strtoul(dataStr, &endp, 0); + if (*endp) { + reportErr(true, FLINT_INVALID_DATA_ERROR, _flintParams.cmd_params[1].c_str()); + delete[] addrStr; + delete[] dataStr; + return FLINT_FAILED; + } + delete[] addrStr; + delete[] dataStr; + data = __cpu_to_be32(data); + if (!((Flash*)_io)->write(addr, &data, 4, true)) { + reportErr(true, FLINT_FLASH_WRITE_ERROR, _io->err()); + return FLINT_FAILED; + } + return FLINT_SUCCESS; +} + +/************************************** + *Class:Write Block SubCommand + **************************************/ +WbSubCommand:: WbSubCommand() { + _name = "wb"; + _desc = "Write a data block to flash."; + _extendedDesc = "Write a block of data to the flash."; + _flagLong = "wb"; + _flagShort = ""; + _param = " "; + _paramExp = "data-file - file that contains the data to be written\n" + INDENTEX"addr - address to write the block to\n"; + + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" wb myData.bin 0x0"; + _v = Wtv_Dev; + _cmdType = SC_Wb; +} + +WbSubCommand:: ~WbSubCommand() { + +} + +bool WbSubCommand::verifyParams() { + if (_flintParams.cmd_params.size() != 2) { + reportErr(true, FLINT_CMD_ARGS_ERROR,_name.c_str() , 2, (int)_flintParams.cmd_params.size()); + return false; + } + return true; +} + +bool WbSubCommand::extractData(const std::vector& cmdParams , u_int32_t* addr, std::vector& data) { + // get address + char *endp; + char* addrStr = strcpy(new char[cmdParams[1].size() + 1],cmdParams[1].c_str()); + *addr = strtoul(addrStr, &endp, 0); + if (*endp) { + reportErr(true, FLINT_INVALID_ADDR_ERROR, cmdParams[1].c_str()); + delete[] addrStr; + return false; + } + delete[] addrStr; + // get data + FImage img; + if (!img.open(cmdParams[0].c_str())) { + reportErr(true, FLINT_WB_FILE_ERROR, cmdParams[0].c_str(), img.err()); + return false; + } + //copy data to vector + data.resize(img.getBufLength()); + memcpy(&data[0], img.getBuf(), img.getBufLength()); + + return true; +} + +FlintStatus WbSubCommand::executeCommand() { + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + u_int32_t addr; + std::vector data; + if (!extractData(_flintParams.cmd_params, &addr, data)) { + return FLINT_FAILED; + } + //printf("-D- writing to addr:0x%08x %lu bytes\n",addr , data.size()); + if (!_fwOps->FwWriteBlock(addr, data, wbCbFunc)) { + reportErr(true, FLINT_WB_ERROR, _fwOps->err()); + return FLINT_FAILED; + } + wbCbFunc(101); + return FLINT_SUCCESS; +} + +/************************************** + *Class:Write Block No Erase SubCommand + **************************************/ +WbneSubCommand:: WbneSubCommand() { + _name = "wbne"; + _desc = "Write a data block to flash without sector erase."; + _extendedDesc = "Write a block of data to the flash without erasing."; + _flagLong = "wbne"; + _flagShort = ""; + _param = " "; + _paramExp = "addr - address of block\n" + INDENTEX"size - size of data to write in bytes\n" + INDENTEX"data - data to write - space seperated dwords"; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" wbne 0x10000 12 0x30000 0x76800 0x5a445a44"; + _v = Wtv_Dev; + _cmdType = SC_Wbne; +} + +WbneSubCommand:: ~WbneSubCommand() { + +} + +bool WbneSubCommand::writeBlock(u_int32_t addr, std::vector dataVec) { + //we should work only on flash. + //check if flash is big enough + if (addr + (dataVec.size()*4) > ((Flash*)_io)->get_size()) { + reportErr(true, "Writing %#x bytes from address %#x is out of flash limits (%#x bytes)\n", + (unsigned int)(dataVec.size()*4), (unsigned int)addr, (unsigned int)_io->get_size()); + return false; + } + // convert to be32. + for(std::vector::iterator it = dataVec.begin(); it != dataVec.end(); ++it) { + *it = __cpu_to_be32(*it); + } + if (!((Flash*)_io)->write(addr, &dataVec[0], (dataVec.size()*4), true)) { + reportErr(true, FLINT_FLASH_WRITE_ERROR,_io->err()); + return false; + } + return true; +} + +bool WbneSubCommand::verifyParams() { + if (_flintParams.cmd_params.size() < 3) { + reportErr(true, FLINT_CMD_ARGS_ERROR3,_name.c_str() , 3, (int)_flintParams.cmd_params.size()); + return false; + } + return true; +} + +bool WbneSubCommand::extractData(const std::vector& cmdParams , u_int32_t* addr, std::vector& data) { + char *endp; + char* addrStr = strcpy(new char[cmdParams[0].size() + 1],cmdParams[0].c_str()); + *addr = strtoul(addrStr, &endp, 0); + if (*endp) { + reportErr(true, FLINT_INVALID_ADDR_ERROR, cmdParams[0].c_str()); + delete[] addrStr; + return false; + } + delete[] addrStr; + char* sizeStr = strcpy(new char[cmdParams[1].size() + 1],cmdParams[1].c_str()); + u_int32_t size = strtoul(sizeStr, &endp, 0); + if (*endp || size % 4 || size/4 != (cmdParams.size()-2)) { + reportErr(true, FLINT_INVALID_SIZE_ERROR, sizeStr); + delete[] sizeStr; + return false; + } + delete[] sizeStr; + for (u_int32_t i = 2; i < cmdParams.size(); i++) { + char* dataStr = strcpy(new char[cmdParams[i].size() + 1],cmdParams[i].c_str()); + data.push_back(__cpu_to_be32(strtoul(dataStr, &endp, 0))); + if (*endp) { + reportErr(true, FLINT_INVALID_DATA_ERROR, dataStr); + delete[] dataStr; + return false; + } + delete[] dataStr; + } + return true; +} + +FlintStatus WbneSubCommand::executeCommand() { + if (preFwAccess() == FLINT_FAILED) { + return FLINT_FAILED; + } + u_int32_t addr; + std::vector data; + if (!extractData(_flintParams.cmd_params, &addr, data)) { + return FLINT_FAILED; + } + //printf("-D- writing to addr:0x%08x %lu bytes\n",addr , data.size()*4); + if (!writeBlock(addr, data)) { + return FLINT_FAILED; + } + return FLINT_SUCCESS; +} + +/*********************** + *Class: ReadBlock + **********************/ +RbSubCommand:: RbSubCommand() +{ + _name = "rb"; + _desc = "Read a data block from flash"; + _extendedDesc = "Read a data block from the flash and write it to a file or to screen."; + _flagLong = "rb"; + _flagShort = ""; + _param = " [out-file]"; + _paramExp = "addr - address of block\n" + INDENTEX"size - size of data to read in bytes\n" + INDENTEX"file - filename to write the block (raw binary). If not given, the data\n" + INDENTEX"is printed to screen"; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" rb 0x10000 100 file.bin"; + _v = Wtv_Dev_Or_Img; + _cmdType = SC_Rb; +} + +RbSubCommand:: ~RbSubCommand() +{ + +} + +bool RbSubCommand::readBlock(u_int32_t addr, std::vector& buff, bool isFlash) { + //check if flash is big enough + if (addr + buff.size() > _io->get_size()) { + reportErr(true, "Reading %#x bytes from address %#x is out of flash limits (%#x bytes)\n", + (unsigned int)(buff.size()), (unsigned int)addr, (unsigned int)_io->get_size()); + return false; + } + //read from flash/image + if (isFlash ? !((Flash*)_io)->read(addr, &buff[0], buff.size()) :\ + !((FImage*)_io)->read(addr, &buff[0], buff.size())) { + reportErr(true, FLINT_IMAGE_READ_ERROR, _io->err()); + return false; + } + return true; +} + +bool RbSubCommand::verifyParams() { + if (_flintParams.cmd_params.size() < 2) { + reportErr(true, FLINT_CMD_ARGS_ERROR3,_name.c_str() , 2, (int)_flintParams.cmd_params.size()); + return false; + } + return true; +} + +bool RbSubCommand::printToScreen(const std::vector& buff) { + for (u_int32_t i=0; i < buff.size(); i+=4) { + u_int32_t word = *((u_int32_t*)(&buff[0] + i)); + word = __be32_to_cpu(word); + printf("0x%08x ", word); + } + printf("\n"); + return true; +} + +FlintStatus RbSubCommand::executeCommand() { + //init fw operation object + if (preFwAccess() == FLINT_FAILED) { + return FLINT_FAILED; + } + bool wTF = _flintParams.cmd_params.size() == 3 ? true : false; + //extract address and size to read from cmdline + u_int32_t addr; + u_int32_t size; + char *endp; + char* addrStr = strcpy(new char[_flintParams.cmd_params[0].size() + 1],_flintParams.cmd_params[0].c_str()); + addr = strtoul(addrStr, &endp, 0); + if (*endp) { + reportErr(true, FLINT_INVALID_ADDR_ERROR, _flintParams.cmd_params[0].c_str()); + delete[] addrStr; + return FLINT_FAILED; + } + delete[] addrStr; + char* sizeStr = strcpy(new char[_flintParams.cmd_params[1].size() + 1],_flintParams.cmd_params[1].c_str()); + size = strtoul(sizeStr, &endp, 0); + if (*endp || size % 4) { + reportErr(true, FLINT_INVALID_SIZE_ERROR, sizeStr); + delete[] sizeStr; + return FLINT_FAILED; + } + delete[] sizeStr; + //init byte vector and fill it with data + std::vector data(size); + if (!readBlock(addr, data, _flintParams.device_specified)) { + return FLINT_FAILED; + } + //print either to file or to screen + FlintStatus rc; + if (wTF) { + rc = writeToFile(_flintParams.cmd_params[2], data) == true ? FLINT_SUCCESS : FLINT_FAILED ; + } else { + rc = printToScreen(data) == true ? FLINT_SUCCESS : FLINT_FAILED ; + } + return rc; +} + +/*********************** + *Class: ClearSemaphore + **********************/ +ClearSemSubCommand:: ClearSemSubCommand() +{ + _name = "clear_semaphore"; + _desc = "Clear flash semaphore."; + _extendedDesc = "Clear flash semaphore."; + _flagLong = "clear_semaphore"; + _flagShort = ""; + _param = ""; + _paramExp = ""; + _example = FLINT_NAME" -d "MST_DEV_EXAMPLE1" -clear_semaphore"; + _v = Wtv_Dev; + _cmdType = SC_Clear_Sem; +} + +ClearSemSubCommand:: ~ClearSemSubCommand() +{ + +} + +FlintStatus ClearSemSubCommand::executeCommand() +{ + return preFwAccess(); +} + + +/*********************** + *Class: RomQuery + **********************/ +RomQuerySubCommand:: RomQuerySubCommand() +{ + _name = "qrom"; + _desc = "query rom in a given image."; + _extendedDesc = "query rom in a given image."; + _flagLong = "qrom"; + _flagShort = ""; + _param = ""; + _paramExp = ""; + _example = FLINT_NAME" -i fw_image.bin qrom "; + _v = Wtv_Img; + _cmdType = SC_Qrom; +} + +RomQuerySubCommand:: ~RomQuerySubCommand() +{ + +} + + +FlintStatus RomQuerySubCommand::executeCommand() +{ + if (preFwAccess() == FLINT_FAILED) { + return FLINT_FAILED; + } + + getRomsInfo(_io, _romsInfo); + if (_romsInfo.exp_rom_err_msg_valid != 0){ + reportErr(true, FLINT_ROM_QUERY_ERROR, _flintParams.image.c_str(), _romsInfo.exp_rom_err_msg); + return FLINT_FAILED; + } + displayExpRomInfo(_romsInfo , "Rom Info: "); + return FLINT_SUCCESS; + +} diff --git a/flint/subcommands.h b/flint/subcommands.h new file mode 100644 index 0000000..110e1c6 --- /dev/null +++ b/flint/subcommands.h @@ -0,0 +1,497 @@ +/* + * + * subcommands.h - FLash INTerface + * + * Copyright (c) 2013 Mellanox Technologies Ltd. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Version: $Id$ + * + */ + +#ifndef __SUBCOMMANDS_H__ +#define __SUBCOMMANDS_H__ + +#define FLINT_NAME "mstflint" +#define MAX_PASSWORD_LEN 256 +#ifdef __WIN__ +#define MST_DEV_EXAMPLE1 "mt4099_pci_cr0" +#define MST_DEV_EXAMPLE2 "mt4099_pciconf0" +#else +#define MST_DEV_EXAMPLE1 "03:00.0" +#define MST_DEV_EXAMPLE2 "mlx4_0" +#endif + +#include +#include "flint_params.h" +#include "mlxfwops/lib/fw_ops.h" +#include "err_msgs.h" +using namespace std; + +//we might need to close the log from the main program in case of interrupt +void close_log(); +void print_time_to_log(); +int print_line_to_log(const char* format, ...); +int write_cmd_to_log(char* av[], int ac, CommandType cmd, bool write=true); +int write_result_to_log(int is_failed, const char* err_msg, bool write=true); + + +typedef enum what_to_ver { + Wtv_Img, + Wtv_Dev, + Wtv_Dev_And_Img, + Wtv_Dev_Or_Img, + Wtv_Uninitilized +} what_to_ver_t; +/*Subcommand classes:*/ + +#define FLINT_ERR_LEN 1024 + +class SubCommand +{ +protected: + FwOperations *_fwOps; + FwOperations *_imgOps; + FBase* _io; + what_to_ver_t _v; + FlintParams _flintParams; + //info about the Subcommand + string _name; + string _desc; + string _extendedDesc; + string _flagLong; + string _flagShort; + string _param; + string _paramExp; + string _example; + char _errBuff[FLINT_ERR_LEN]; + sub_cmd_t _cmdType; + + + //Methods that are commonly used in the various subcommands: + //TODO: add middle classes and segregate as much of these common methods between these classes + + virtual bool verifyParams() {return true;}; + bool basicVerifyParams(); + FlintStatus openOps(); + FlintStatus openIo(); + virtual FlintStatus preFwOps(); + virtual FlintStatus preFwAccess(); + + bool getRomsInfo(FBase* io, roms_info_t& romsInfo); + void displayOneExpRomInfo(const rom_info_t& info); + void displayExpRomInfo(const roms_info_t& romsInfo, char *preStr); + + static int verifyCbFunc(char* str); + static int CbCommon(int completion, char*preStr, char* endStr=NULL); + static int burnCbFs2Func(int completion); + static int burnCbFs3Func(int completion); + static int burnBCbFunc(int completion); + static int vsdCbFunc(int completion); + static int setKeyCbFunc(int completion); + static int bromCbFunc(int completion); + static int dromCbFunc(int completion); + static int wbCbFunc(int completion); + + bool printGuidLine(guid_t* new_guids, guid_t* old_guids, int guid_index); + bool printBxGuids(guid_t* new_guids, guid_t* old_guids, int index,\ + int num_of_guids, const char* pre_str); + bool printMacLine(guid_t* new_guids, guid_t* old_guids, int mac_index); + bool printBxMacs(guid_t* new_guids, guid_t* old_guids, int index, int num_of_guids, const char* pre_str); + bool printUidsFunc(guid_t* new_guids, guid_t* old_guids); + bool printGUIDsFunc(guid_t guids[GUIDS],guid_t macs[MACS], guid_t old_guids[GUIDS],\ + guid_t old_macs[MACS], bool print_guids, bool print_macs, int portNum, bool old_guid_fmt); + bool reportGuidChanges(guid_t* new_guids, guid_t* new_macs,\ + guid_t* old_guids, guid_t* old_macs, bool printGuids,\ + bool printMacs, bool printUids, int guidNum); + bool checkGuidsFlags(chip_type_t ct, u_int16_t devType, u_int8_t fwType, + bool guidsSpecified, bool macsSpecified, bool uidsSpecified); + void printMissingGuidErr(bool ibDev, bool ethDev, bool bxDev); + + bool getGUIDFromStr(string str, guid_t& guid, string prefixErr=""); + bool getPasswordFromUser(char *preStr, char buffer[MAX_PASSWORD_LEN]); + bool askUser(const char* question=NULL, bool printAbrtMsg=true); + + bool isCmdSupportLog(); + void openLog(); + inline void closeLog() {close_log();} + //print errors to an err buff, log if needed and stdout + void reportErr(bool shouldPrint, const char *format, ...); + + + bool fwVerLessThan(const u_int16_t r1[3], const u_int16_t r2[3]); + + bool writeToFile(string filePath, const std::vector& buff); + + bool dumpFile(const char* confFile, std::vector& data, const char *sectionName); + bool unzipDataFile (std::vector data, std::vector &newData, const char *sectionName); + + + +public: + SubCommand(): _fwOps(NULL), _imgOps(NULL), _io(NULL), _v(Wtv_Uninitilized){} + virtual ~SubCommand(); + virtual FlintStatus executeCommand() = 0; + inline void setParams(const FlintParams& flintParams) {_flintParams = flintParams;} + inline string& getName() {return this->_name;} + inline string& getDesc() {return this->_desc;} + inline string& getExtDesc() {return this->_extendedDesc;} + inline string& getFlagL() {return this->_flagLong;} + inline string& getFlagS() {return this->_flagShort;} + inline string& getParam() {return this->_param;} + inline string& getParamExp() {return this->_paramExp;} + inline string& getExample() {return this->_example;} +}; + +class BurnSubCommand : public SubCommand +{ +private: + fw_info_t _devInfo; + fw_info_t _imgInfo; + FwOperations::ExtBurnParams _burnParams; + bool _devQueryRes; + + FlintStatus burnFs3(); + FlintStatus burnFs2(); + bool checkFwVersion(); + bool checkPSIDAndIbEth(); + void updateBurnParams(); + void dealWithExpRom(); + bool checkMatchingExpRomDevId(const fw_info_t& info); + bool dealWithGuids(); + bool dealWithVSD(); +public: + BurnSubCommand(); + ~BurnSubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; + +class QuerySubCommand : public SubCommand +{ +private: + FlintStatus printInfo(const fw_info_t& fwInfo, bool fullQuery); + bool displayFs3Uids(const fw_info_t& fwInfo); + bool displayFs2Uids(const fw_info_t& fwInfo); + bool reportBxGuidsQuery(const guid_t* guids, int base1, int guids_num, int index, const char* pre_str); + bool reportBxMacsQuery(const guid_t* guids, int base1, int guids_num, int index, const char* pre_str); + bool reportBxMacsWarnings(const guid_t* guids, int index, int warning, int user_uids); + bool checkMac(u_int64_t mac, string& warrStr); +public: + QuerySubCommand(); + ~QuerySubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; + +class VerifySubCommand : public SubCommand +{ +private: + +public: + VerifySubCommand(); + ~VerifySubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; + +class SwResetSubCommand : public SubCommand +{ +private: + +public: + SwResetSubCommand(); + ~SwResetSubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; + +class BromSubCommand : public SubCommand +{ +private: + fw_info_t _info; + roms_info_t _romsInfo; + FImage _fRom; +public: + BromSubCommand(); + ~BromSubCommand(); + inline FlintStatus executeCommand(); + bool verifyParams(); + bool getExpRomStrVer(roms_info_t& roms_info, char* version); +}; + +class DromSubCommand : public SubCommand +{ +private: + fw_info_t _info; +public: + DromSubCommand(); + ~DromSubCommand(); + FlintStatus executeCommand(); + inline bool verifyParams(); +}; + +class RromSubCommand : public SubCommand +{ +private: + +public: + RromSubCommand(); + ~RromSubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; + +class BbSubCommand : public SubCommand +{ +private: + +public: + BbSubCommand(); + ~BbSubCommand(); + FlintStatus executeCommand(); + inline bool verifyParams(); +}; + +class SgSubCommand : public SubCommand +{ +private: + fw_info_t _info; + FwOperations* _ops; + FwOperations::sg_params_t _sgParams; + + FlintStatus sgFs2(); + FlintStatus sgFs3(); + void setUserGuidsAndMacs(); + bool CheckSetGuidsFlags(); +public: + SgSubCommand(); + ~SgSubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; + +class SmgSubCommand : public SubCommand +{ +private: + guid_t _baseGuid; +public: + SmgSubCommand(); + ~SmgSubCommand(); + inline FlintStatus executeCommand(); + inline bool verifyParams(); +}; + +class SetVpdSubCommand : public SubCommand +{ +private: + +public: + SetVpdSubCommand(); + ~SetVpdSubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; + +class SvSubCommand : public SubCommand +{ +private: + +public: + SvSubCommand(); + ~SvSubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; +class RiSubCommand : public SubCommand +{ +private: + FlintStatus writeImageToFile(const char *file_name, u_int8_t *data, u_int32_t length); +public: + RiSubCommand(); + ~RiSubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; + +class DcSubCommand : public SubCommand +{ +private: + std::vector _sect; +public: + DcSubCommand(); + ~DcSubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; +class DhSubCommand : public SubCommand +{ +private: + std::vector _sect; +public: + DhSubCommand(); + ~DhSubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; + +class SetKeySubCommand : public SubCommand +{ +private: + hw_key_t _userKey; + bool _getKeyInter; + bool getKeyInteractively(); +public: + SetKeySubCommand(); + ~SetKeySubCommand(); + inline FlintStatus executeCommand(); + inline bool verifyParams(); +}; +class HwAccessSubCommand : public SubCommand +{ +private: + FlintStatus disableHwAccess(); + FlintStatus enableHwAccess(); +public: + HwAccessSubCommand(); + ~HwAccessSubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; + +class HwSubCommand : public SubCommand +{ +private: + FlintStatus printAttr(const ext_flash_attr_t& attr); +public: + HwSubCommand(); + ~HwSubCommand(); + inline FlintStatus executeCommand(); + inline bool verifyParams(); +}; +class EraseSubCommand : public SubCommand +{ +private: + +public: + EraseSubCommand(); + ~EraseSubCommand(); + inline FlintStatus executeCommand(); + inline bool verifyParams(); +}; +class RwSubCommand : public SubCommand +{ +private: + +public: + RwSubCommand(); + ~RwSubCommand(); + inline FlintStatus executeCommand(); + inline bool verifyParams(); +}; +class WwSubCommand : public SubCommand +{ +private: + +public: + WwSubCommand(); + ~WwSubCommand(); + inline FlintStatus executeCommand(); + inline bool verifyParams(); +}; + +class WwneSubCommand : public SubCommand +{ +private: + +public: + WwneSubCommand(); + ~WwneSubCommand(); + inline FlintStatus executeCommand(); + inline bool verifyParams(); +}; + +class WbSubCommand : public SubCommand +{ +private: + bool extractData(const std::vector& cmdParams , u_int32_t* addr, std::vector& data); +public: + WbSubCommand(); + ~WbSubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; + + +class WbneSubCommand : public SubCommand +{ +private: + bool extractData(const std::vector& cmdParams , u_int32_t* addr, std::vector& data); + bool writeBlock(u_int32_t addr, std::vector dataVec); +public: + WbneSubCommand(); + ~WbneSubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; + +class RbSubCommand : public SubCommand +{ +private: + bool printToScreen(const std::vector& buff); + bool readBlock(u_int32_t addr, std::vector& buff, bool isFlash); +public: + RbSubCommand(); + ~RbSubCommand(); + FlintStatus executeCommand(); + bool verifyParams(); +}; + +class ClearSemSubCommand : public SubCommand +{ +private: + +public: + ClearSemSubCommand(); + ~ClearSemSubCommand(); + FlintStatus executeCommand(); +}; + +class RomQuerySubCommand : public SubCommand +{ +private: + roms_info_t _romsInfo; +public: + RomQuerySubCommand(); + ~RomQuerySubCommand(); + FlintStatus executeCommand(); +}; + +#endif diff --git a/mflash/Makefile.am b/mflash/Makefile.am index 1b65efc..645c2c6 100644 --- a/mflash/Makefile.am +++ b/mflash/Makefile.am @@ -31,13 +31,17 @@ #-- # Makefile.am -- Process this file with automake to produce Makefile.in -MTCR_DIR = $(top_srcdir)/include/mtcr_ul -INCLUDES = -I. -I$(MTCR_DIR) -I$(top_srcdir)/common +USER_DIR = .. +MTCR_DIR = $(USER_DIR)/mtcr_ul +INCLUDES = -I. -I$(MTCR_DIR) -I$(USER_DIR)/common -I$(USER_DIR)/tools_layouts -AM_CFLAGS = -MD -pipe -Wall -W -g -DNO_INBAND_ACCESS +AM_CFLAGS = -MD -pipe -Wall -W -D_MTCR_UL_ -g ${MFLASH_INBAND_FLAG} -noinst_LIBRARIES = libmflash.a - -libmflash_a_SOURCES = mflash.c \ - mflash.h +lib_LTLIBRARIES = libmflash.la +# +libmflash_la_SOURCES = mflash.c mflash.h\ + mflash_inband.c mflash_inband.h\ + packets_common.c packets_common.h\ + internal_packets.c internal_packets.h internal_packets_types.h\ + mflash_common.c mflash_common.h mflash_access_layer.c mflash_access_layer.h diff --git a/mflash/internal_packets.c b/mflash/internal_packets.c new file mode 100755 index 0000000..246e00d --- /dev/null +++ b/mflash/internal_packets.c @@ -0,0 +1,392 @@ + /* - Mellanox Confidential and Proprietary - + * + * Copyright (C) June 2000, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + * End of legal section ...................................................... + * +*/ +/*** + *** This file was generated at "Mon May 30 15:06:41 2011" + *** by: + *** % csp_pack_unpack.pm ../xml_files/packets_st.csp + ***/ + +#include "packets_common.h" +#include "internal_packets_types.h" +#include "internal_packets.h" +#include + + + +/*************************************/ +/* Name: mfpa + * Size: 288 bits + * Description: mfpa */ + + +u_int32_t mfpa_pack(struct mfpa *data_to_pack, u_int8_t *packed_buffer) { + push_to_buff(packed_buffer, 28, 4, data_to_pack->reserved0); + push_to_buff(packed_buffer, 26, 2, data_to_pack->fs); + push_to_buff(packed_buffer, 24, 2, data_to_pack->reserved1); + push_to_buff(packed_buffer, 23, 1, data_to_pack->p); + push_to_buff(packed_buffer, 0, 23, data_to_pack->reserved2); + push_to_buff(packed_buffer, 40, 24, data_to_pack->boot_address); + push_to_buff(packed_buffer, 32, 8, data_to_pack->reserved3); + push_to_buff(packed_buffer, 64, 64, data_to_pack->reserved4); + push_to_buff(packed_buffer, 156, 4, data_to_pack->flash_num); + push_to_buff(packed_buffer, 128, 28, data_to_pack->reserved5); + push_to_buff(packed_buffer, 168, 24, data_to_pack->jedec_id); + push_to_buff(packed_buffer, 160, 8, data_to_pack->reserved6); + push_to_buff(packed_buffer, 214, 10, data_to_pack->sector_size); + push_to_buff(packed_buffer, 208, 6, data_to_pack->reserved7); + push_to_buff(packed_buffer, 200, 8, data_to_pack->block_allighment); + push_to_buff(packed_buffer, 192, 8, data_to_pack->reserved8); + push_to_buff_32(packed_buffer, 224, data_to_pack->capability_mask); + push_to_buff_32(packed_buffer, 256, data_to_pack->reserved9); + return 36; +} + +void mfpa_unpack(struct mfpa *unpacked_data, u_int8_t *buffer_to_unpack) { + unpacked_data->reserved0 = pop_from_buff(buffer_to_unpack, 28, 4); + unpacked_data->fs = pop_from_buff(buffer_to_unpack, 26, 2); + unpacked_data->reserved1 = pop_from_buff(buffer_to_unpack, 24, 2); + unpacked_data->p = pop_from_buff(buffer_to_unpack, 23, 1); + unpacked_data->reserved2 = pop_from_buff(buffer_to_unpack, 0, 23); + unpacked_data->boot_address = pop_from_buff(buffer_to_unpack, 40, 24); + unpacked_data->reserved3 = pop_from_buff(buffer_to_unpack, 32, 8); + unpacked_data->reserved4 = pop_from_buff(buffer_to_unpack, 64, 64); + unpacked_data->flash_num = pop_from_buff(buffer_to_unpack, 156, 4); + unpacked_data->reserved5 = pop_from_buff(buffer_to_unpack, 128, 28); + unpacked_data->jedec_id = pop_from_buff(buffer_to_unpack, 168, 24); + unpacked_data->reserved6 = pop_from_buff(buffer_to_unpack, 160, 8); + unpacked_data->sector_size = pop_from_buff(buffer_to_unpack, 214, 10); + unpacked_data->reserved7 = pop_from_buff(buffer_to_unpack, 208, 6); + unpacked_data->block_allighment = pop_from_buff(buffer_to_unpack, 200, 8); + unpacked_data->reserved8 = pop_from_buff(buffer_to_unpack, 192, 8); + unpacked_data->capability_mask = pop_from_buff_32(buffer_to_unpack, 224); + unpacked_data->reserved9 = pop_from_buff_32(buffer_to_unpack, 256); +} + +void mfpa_dump(struct mfpa *data_to_print, FILE *out_port) { + fprintf(out_port, "mfpa::reserved0: "U32D_FMT"\n", data_to_print->reserved0); + fprintf(out_port, "mfpa::fs: "U32D_FMT"\n", data_to_print->fs); + fprintf(out_port, "mfpa::reserved1: "U32D_FMT"\n", data_to_print->reserved1); + fprintf(out_port, "mfpa::p: "U32D_FMT"\n", data_to_print->p); + fprintf(out_port, "mfpa::reserved2: "U32D_FMT"\n", data_to_print->reserved2); + fprintf(out_port, "mfpa::boot_address: "U32D_FMT"\n", data_to_print->boot_address); + fprintf(out_port, "mfpa::reserved3: "U32D_FMT"\n", data_to_print->reserved3); + fprintf(out_port, "mfpa::reserved4: "U32D_FMT"\n", data_to_print->reserved4); + fprintf(out_port, "mfpa::flash_num: "U32D_FMT"\n", data_to_print->flash_num); + fprintf(out_port, "mfpa::reserved5: "U32D_FMT"\n", data_to_print->reserved5); + fprintf(out_port, "mfpa::jedec_id: "U32D_FMT"\n", data_to_print->jedec_id); + fprintf(out_port, "mfpa::reserved6: "U32D_FMT"\n", data_to_print->reserved6); + fprintf(out_port, "mfpa::sector_size: "U32D_FMT"\n", data_to_print->sector_size); + fprintf(out_port, "mfpa::reserved7: "U32D_FMT"\n", data_to_print->reserved7); + fprintf(out_port, "mfpa::block_allighment: "U32D_FMT"\n", data_to_print->block_allighment); + fprintf(out_port, "mfpa::reserved8: "U32D_FMT"\n", data_to_print->reserved8); + fprintf(out_port, "mfpa::capability_mask: "U32D_FMT"\n", data_to_print->capability_mask); + fprintf(out_port, "mfpa::reserved9: "U32D_FMT"\n", data_to_print->reserved9); +} + + +/**************************************/ +/* Name: mfbe + * Size: 96 bits + * Description: mfbe */ + + +u_int32_t mfbe_pack(struct mfbe *data_to_pack, u_int8_t *packed_buffer) { + push_to_buff(packed_buffer, 28, 4, data_to_pack->reserved0); + push_to_buff(packed_buffer, 26, 2, data_to_pack->fs); + push_to_buff(packed_buffer, 24, 2, data_to_pack->reserved1); + push_to_buff(packed_buffer, 23, 1, data_to_pack->p); + push_to_buff(packed_buffer, 0, 23, data_to_pack->reserved2); + push_to_buff_32(packed_buffer, 32, data_to_pack->reserved3); + push_to_buff(packed_buffer, 72, 24, data_to_pack->address); + push_to_buff(packed_buffer, 64, 8, data_to_pack->reserved4); + return 12; +} + +void mfbe_unpack(struct mfbe *unpacked_data, u_int8_t *buffer_to_unpack) { + unpacked_data->reserved0 = pop_from_buff(buffer_to_unpack, 28, 4); + unpacked_data->fs = pop_from_buff(buffer_to_unpack, 26, 2); + unpacked_data->reserved1 = pop_from_buff(buffer_to_unpack, 24, 2); + unpacked_data->p = pop_from_buff(buffer_to_unpack, 23, 1); + unpacked_data->reserved2 = pop_from_buff(buffer_to_unpack, 0, 23); + unpacked_data->reserved3 = pop_from_buff_32(buffer_to_unpack, 32); + unpacked_data->address = pop_from_buff(buffer_to_unpack, 72, 24); + unpacked_data->reserved4 = pop_from_buff(buffer_to_unpack, 64, 8); +} + +void mfbe_dump(struct mfbe *data_to_print, FILE *out_port) { + fprintf(out_port, "mfbe::reserved0: "U32D_FMT"\n", data_to_print->reserved0); + fprintf(out_port, "mfbe::fs: "U32D_FMT"\n", data_to_print->fs); + fprintf(out_port, "mfbe::reserved1: "U32D_FMT"\n", data_to_print->reserved1); + fprintf(out_port, "mfbe::p: "U32D_FMT"\n", data_to_print->p); + fprintf(out_port, "mfbe::reserved2: "U32D_FMT"\n", data_to_print->reserved2); + fprintf(out_port, "mfbe::reserved3: "U32D_FMT"\n", data_to_print->reserved3); + fprintf(out_port, "mfbe::address: "U32D_FMT"\n", data_to_print->address); + fprintf(out_port, "mfbe::reserved4: "U32D_FMT"\n", data_to_print->reserved4); +} + + + + +/*************************************/ +/* Name: OperationTlv + * Size: 128 bits + * Description: */ + + +u_int32_t OperationTlv_pack(struct OperationTlv *data_to_pack, u_int8_t *packed_buffer) { + push_to_buff(packed_buffer, 24, 8, data_to_pack->reserved0); + push_to_buff(packed_buffer, 17, 7, data_to_pack->status); + push_to_buff(packed_buffer, 16, 1, data_to_pack->dr); + push_to_buff(packed_buffer, 5, 11, data_to_pack->len); + push_to_buff(packed_buffer, 0, 5, data_to_pack->Type); + push_to_buff(packed_buffer, 56, 8, data_to_pack->class); + push_to_buff(packed_buffer, 49, 7, data_to_pack->method); + push_to_buff(packed_buffer, 48, 1, data_to_pack->r); + push_to_buff(packed_buffer, 32, 16, data_to_pack->register_id); + push_to_buff_64(packed_buffer, 64, data_to_pack->tid); + return 16; +} + +void OperationTlv_unpack(struct OperationTlv *unpacked_data, u_int8_t *buffer_to_unpack) { + unpacked_data->reserved0 = pop_from_buff(buffer_to_unpack, 24, 8); + unpacked_data->status = pop_from_buff(buffer_to_unpack, 17, 7); + unpacked_data->dr = pop_from_buff(buffer_to_unpack, 16, 1); + unpacked_data->len = pop_from_buff(buffer_to_unpack, 5, 11); + unpacked_data->Type = pop_from_buff(buffer_to_unpack, 0, 5); + unpacked_data->class = pop_from_buff(buffer_to_unpack, 56, 8); + unpacked_data->method = pop_from_buff(buffer_to_unpack, 49, 7); + unpacked_data->r = pop_from_buff(buffer_to_unpack, 48, 1); + unpacked_data->register_id = pop_from_buff(buffer_to_unpack, 32, 16); + unpacked_data->tid = pop_from_buff_64(buffer_to_unpack, 64); +} + +void OperationTlv_dump(struct OperationTlv *data_to_print, FILE *out_port) { + fprintf(out_port, "OperationTlv::reserved0: "U32D_FMT"\n", data_to_print->reserved0); + fprintf(out_port, "OperationTlv::status: "U32D_FMT"\n", data_to_print->status); + fprintf(out_port, "OperationTlv::dr: "U32D_FMT"\n", data_to_print->dr); + fprintf(out_port, "OperationTlv::len: "U32D_FMT"\n", data_to_print->len); + fprintf(out_port, "OperationTlv::Type: "U32D_FMT"\n", data_to_print->Type); + fprintf(out_port, "OperationTlv::class: "U32D_FMT"\n", data_to_print->class); + fprintf(out_port, "OperationTlv::method: "U32D_FMT"\n", data_to_print->method); + fprintf(out_port, "OperationTlv::r: "U32D_FMT"\n", data_to_print->r); + fprintf(out_port, "OperationTlv::register_id: "U32D_FMT"\n", data_to_print->register_id); + fprintf(out_port, "OperationTlv::tid: "U64D_FMT"\n", data_to_print->tid); +} + +/*************************************/ +/* Name: reg_tlv + * Size: 32 bits + * Description: reg_tlv */ + + +u_int32_t reg_tlv_pack(struct reg_tlv *data_to_pack, u_int8_t *packed_buffer) { + push_to_buff(packed_buffer, 16, 16, data_to_pack->reserved0); + push_to_buff(packed_buffer, 5, 11, data_to_pack->len); + push_to_buff(packed_buffer, 0, 5, data_to_pack->Type); + return 4; +} + +void reg_tlv_unpack(struct reg_tlv *unpacked_data, u_int8_t *buffer_to_unpack) { + unpacked_data->reserved0 = pop_from_buff(buffer_to_unpack, 16, 16); + unpacked_data->len = pop_from_buff(buffer_to_unpack, 5, 11); + unpacked_data->Type = pop_from_buff(buffer_to_unpack, 0, 5); +} + +void reg_tlv_dump(struct reg_tlv *data_to_print, FILE *out_port) { + fprintf(out_port, "reg_tlv::reserved0: "U32D_FMT"\n", data_to_print->reserved0); + fprintf(out_port, "reg_tlv::len: "U32D_FMT"\n", data_to_print->len); + fprintf(out_port, "reg_tlv::Type: "U32D_FMT"\n", data_to_print->Type); +} + +/*************************************/ +/* Name: mfba_mad + * Size: 352 bits + * Description: mfba_mad */ +/* + +u_int32_t mfba_mad_pack(struct mfba_mad *data_to_pack, u_int8_t *packed_buffer) { + push_to_buff(packed_buffer, 28, 4, data_to_pack->reserved0); + push_to_buff(packed_buffer, 26, 2, data_to_pack->fs); + push_to_buff(packed_buffer, 24, 2, data_to_pack->reserved1); + push_to_buff(packed_buffer, 23, 1, data_to_pack->p); + push_to_buff(packed_buffer, 0, 23, data_to_pack->reserved2); + push_to_buff(packed_buffer, 55, 9, data_to_pack->size); + push_to_buff(packed_buffer, 32, 23, data_to_pack->reserved3); + push_to_buff(packed_buffer, 72, 24, data_to_pack->address); + push_to_buff(packed_buffer, 64, 8, data_to_pack->reserved4); + push_to_buff_32(packed_buffer, 96, data_to_pack->data[0]); + push_to_buff_32(packed_buffer, 128, data_to_pack->data[1]); + push_to_buff_32(packed_buffer, 160, data_to_pack->data[2]); + push_to_buff_32(packed_buffer, 192, data_to_pack->data[3]); + push_to_buff_32(packed_buffer, 224, data_to_pack->data[4]); + push_to_buff_32(packed_buffer, 256, data_to_pack->data[5]); + push_to_buff_32(packed_buffer, 288, data_to_pack->data[6]); + push_to_buff_32(packed_buffer, 320, data_to_pack->data[7]); + return 44; +} + +void mfba_mad_unpack(struct mfba_mad *unpacked_data, u_int8_t *buffer_to_unpack) { + unpacked_data->reserved0 = pop_from_buff(buffer_to_unpack, 28, 4); + unpacked_data->fs = pop_from_buff(buffer_to_unpack, 26, 2); + unpacked_data->reserved1 = pop_from_buff(buffer_to_unpack, 24, 2); + unpacked_data->p = pop_from_buff(buffer_to_unpack, 23, 1); + unpacked_data->reserved2 = pop_from_buff(buffer_to_unpack, 0, 23); + unpacked_data->size = pop_from_buff(buffer_to_unpack, 55, 9); + unpacked_data->reserved3 = pop_from_buff(buffer_to_unpack, 32, 23); + unpacked_data->address = pop_from_buff(buffer_to_unpack, 72, 24); + unpacked_data->reserved4 = pop_from_buff(buffer_to_unpack, 64, 8); + unpacked_data->data[0] = pop_from_buff_32(buffer_to_unpack, 96); + unpacked_data->data[1] = pop_from_buff_32(buffer_to_unpack, 128); + unpacked_data->data[2] = pop_from_buff_32(buffer_to_unpack, 160); + unpacked_data->data[3] = pop_from_buff_32(buffer_to_unpack, 192); + unpacked_data->data[4] = pop_from_buff_32(buffer_to_unpack, 224); + unpacked_data->data[5] = pop_from_buff_32(buffer_to_unpack, 256); + unpacked_data->data[6] = pop_from_buff_32(buffer_to_unpack, 288); + unpacked_data->data[7] = pop_from_buff_32(buffer_to_unpack, 320); +} +*/ + +u_int32_t mfba_mad_pack(struct mfba_mad *data_to_pack, u_int8_t *packed_buffer) { + push_to_buff(packed_buffer, 28, 4, data_to_pack->reserved0); + push_to_buff(packed_buffer, 26, 2, data_to_pack->fs); + push_to_buff(packed_buffer, 24, 2, data_to_pack->reserved1); + push_to_buff(packed_buffer, 23, 1, data_to_pack->p); + push_to_buff(packed_buffer, 0, 23, data_to_pack->reserved2); + push_to_buff(packed_buffer, 55, 9, data_to_pack->size); + push_to_buff(packed_buffer, 32, 23, data_to_pack->reserved3); + push_to_buff(packed_buffer, 72, 24, data_to_pack->address); + push_to_buff(packed_buffer, 64, 8, data_to_pack->reserved4); + push_to_buff_32(packed_buffer, 96, data_to_pack->data[0]); + push_to_buff_32(packed_buffer, 128, data_to_pack->data[1]); + push_to_buff_32(packed_buffer, 160, data_to_pack->data[2]); + push_to_buff_32(packed_buffer, 192, data_to_pack->data[3]); + push_to_buff_32(packed_buffer, 224, data_to_pack->data[4]); + push_to_buff_32(packed_buffer, 256, data_to_pack->data[5]); + push_to_buff_32(packed_buffer, 288, data_to_pack->data[6]); + push_to_buff_32(packed_buffer, 320, data_to_pack->data[7]); + push_to_buff_32(packed_buffer, 352, data_to_pack->data[8]); + push_to_buff_32(packed_buffer, 384, data_to_pack->data[9]); + push_to_buff_32(packed_buffer, 416 , data_to_pack->data[10]); + push_to_buff_32(packed_buffer, 448, data_to_pack->data[11]); + push_to_buff_32(packed_buffer, 480, data_to_pack->data[12]); + push_to_buff_32(packed_buffer, 512, data_to_pack->data[13]); + push_to_buff_32(packed_buffer, 544, data_to_pack->data[14]); + push_to_buff_32(packed_buffer, 576, data_to_pack->data[15]); + push_to_buff_32(packed_buffer, 608, data_to_pack->data[16]); + push_to_buff_32(packed_buffer, 640, data_to_pack->data[17]); + push_to_buff_32(packed_buffer, 672, data_to_pack->data[18]); + push_to_buff_32(packed_buffer, 704, data_to_pack->data[19]); + push_to_buff_32(packed_buffer, 736, data_to_pack->data[20]); + push_to_buff_32(packed_buffer, 768, data_to_pack->data[21]); + push_to_buff_32(packed_buffer, 800, data_to_pack->data[22]); + push_to_buff_32(packed_buffer, 832, data_to_pack->data[23]); + push_to_buff_32(packed_buffer, 864, data_to_pack->data[24]); + push_to_buff_32(packed_buffer, 896, data_to_pack->data[25]); + push_to_buff_32(packed_buffer, 928, data_to_pack->data[26]); + push_to_buff_32(packed_buffer, 960, data_to_pack->data[27]); + push_to_buff_32(packed_buffer, 992, data_to_pack->data[28]); + push_to_buff_32(packed_buffer, 1024, data_to_pack->data[29]); + push_to_buff_32(packed_buffer, 1056, data_to_pack->data[30]); + push_to_buff_32(packed_buffer, 1088, data_to_pack->data[31]); + return 140; +} + +void mfba_mad_unpack(struct mfba_mad *unpacked_data, u_int8_t *buffer_to_unpack) { + unpacked_data->reserved0 = pop_from_buff(buffer_to_unpack, 28, 4); + unpacked_data->fs = pop_from_buff(buffer_to_unpack, 26, 2); + unpacked_data->reserved1 = pop_from_buff(buffer_to_unpack, 24, 2); + unpacked_data->p = pop_from_buff(buffer_to_unpack, 23, 1); + unpacked_data->reserved2 = pop_from_buff(buffer_to_unpack, 0, 23); + unpacked_data->size = pop_from_buff(buffer_to_unpack, 55, 9); + unpacked_data->reserved3 = pop_from_buff(buffer_to_unpack, 32, 23); + unpacked_data->address = pop_from_buff(buffer_to_unpack, 72, 24); + unpacked_data->reserved4 = pop_from_buff(buffer_to_unpack, 64, 8); + unpacked_data->data[0] = pop_from_buff_32(buffer_to_unpack, 96); + unpacked_data->data[1] = pop_from_buff_32(buffer_to_unpack, 128); + unpacked_data->data[2] = pop_from_buff_32(buffer_to_unpack, 160); + unpacked_data->data[3] = pop_from_buff_32(buffer_to_unpack, 192); + unpacked_data->data[4] = pop_from_buff_32(buffer_to_unpack, 224); + unpacked_data->data[5] = pop_from_buff_32(buffer_to_unpack, 256); + unpacked_data->data[6] = pop_from_buff_32(buffer_to_unpack, 288); + unpacked_data->data[7] = pop_from_buff_32(buffer_to_unpack, 320); + unpacked_data->data[8] = pop_from_buff_32(buffer_to_unpack, 352); + unpacked_data->data[9] = pop_from_buff_32(buffer_to_unpack, 384); + unpacked_data->data[10] = pop_from_buff_32(buffer_to_unpack, 416); + unpacked_data->data[11] = pop_from_buff_32(buffer_to_unpack, 448); + unpacked_data->data[12] = pop_from_buff_32(buffer_to_unpack, 480); + unpacked_data->data[13] = pop_from_buff_32(buffer_to_unpack, 512); + unpacked_data->data[14] = pop_from_buff_32(buffer_to_unpack, 544); + unpacked_data->data[15] = pop_from_buff_32(buffer_to_unpack, 576); + unpacked_data->data[16] = pop_from_buff_32(buffer_to_unpack, 608); + unpacked_data->data[17] = pop_from_buff_32(buffer_to_unpack, 640); + unpacked_data->data[18] = pop_from_buff_32(buffer_to_unpack, 672); + unpacked_data->data[19] = pop_from_buff_32(buffer_to_unpack, 704); + unpacked_data->data[20] = pop_from_buff_32(buffer_to_unpack, 736); + unpacked_data->data[21] = pop_from_buff_32(buffer_to_unpack, 768); + unpacked_data->data[22] = pop_from_buff_32(buffer_to_unpack, 800); + unpacked_data->data[23] = pop_from_buff_32(buffer_to_unpack, 832); + unpacked_data->data[24] = pop_from_buff_32(buffer_to_unpack, 864); + unpacked_data->data[25] = pop_from_buff_32(buffer_to_unpack, 896); + unpacked_data->data[26] = pop_from_buff_32(buffer_to_unpack, 928); + unpacked_data->data[27] = pop_from_buff_32(buffer_to_unpack, 960); + unpacked_data->data[28] = pop_from_buff_32(buffer_to_unpack, 992); + unpacked_data->data[29] = pop_from_buff_32(buffer_to_unpack, 1024); + unpacked_data->data[30] = pop_from_buff_32(buffer_to_unpack, 1056); + unpacked_data->data[31] = pop_from_buff_32(buffer_to_unpack, 1088); +} + +void mfba_mad_dump(struct mfba_mad *data_to_print, FILE *out_port) { + fprintf(out_port, "mfba_mad::reserved0: "U32D_FMT"\n", data_to_print->reserved0); + fprintf(out_port, "mfba_mad::fs: "U32D_FMT"\n", data_to_print->fs); + fprintf(out_port, "mfba_mad::reserved1: "U32D_FMT"\n", data_to_print->reserved1); + fprintf(out_port, "mfba_mad::p: "U32D_FMT"\n", data_to_print->p); + fprintf(out_port, "mfba_mad::reserved2: "U32D_FMT"\n", data_to_print->reserved2); + fprintf(out_port, "mfba_mad::size: "U32D_FMT"\n", data_to_print->size); + fprintf(out_port, "mfba_mad::reserved3: "U32D_FMT"\n", data_to_print->reserved3); + fprintf(out_port, "mfba_mad::address: "U32H_FMT"\n", data_to_print->address); + fprintf(out_port, "mfba_mad::reserved4: "U32D_FMT"\n", data_to_print->reserved4); + fprintf(out_port, "mfba_mad::data[0]: "U32H_FMT"\n", data_to_print->data[0]); + fprintf(out_port, "mfba_mad::data[1]: "U32H_FMT"\n", data_to_print->data[1]); + fprintf(out_port, "mfba_mad::data[2]: "U32H_FMT"\n", data_to_print->data[2]); + fprintf(out_port, "mfba_mad::data[3]: "U32H_FMT"\n", data_to_print->data[3]); + fprintf(out_port, "mfba_mad::data[4]: "U32H_FMT"\n", data_to_print->data[4]); + fprintf(out_port, "mfba_mad::data[5]: "U32H_FMT"\n", data_to_print->data[5]); + fprintf(out_port, "mfba_mad::data[6]: "U32H_FMT"\n", data_to_print->data[6]); + fprintf(out_port, "mfba_mad::data[7]: "U32H_FMT"\n", data_to_print->data[7]); + fprintf(out_port, "mfba_mad::data[8]: "U32H_FMT"\n", data_to_print->data[8]); + fprintf(out_port, "mfba_mad::data[9]: "U32H_FMT"\n", data_to_print->data[9]); + fprintf(out_port, "mfba_mad::data[10]: "U32H_FMT"\n", data_to_print->data[10]); + fprintf(out_port, "mfba_mad::data[11]: "U32H_FMT"\n", data_to_print->data[11]); + fprintf(out_port, "mfba_mad::data[12]: "U32H_FMT"\n", data_to_print->data[12]); + fprintf(out_port, "mfba_mad::data[13]: "U32H_FMT"\n", data_to_print->data[13]); + fprintf(out_port, "mfba_mad::data[14]: "U32H_FMT"\n", data_to_print->data[14]); + fprintf(out_port, "mfba_mad::data[15]: "U32H_FMT"\n", data_to_print->data[15]); + fprintf(out_port, "mfba_mad::data[16]: "U32H_FMT"\n", data_to_print->data[16]); + fprintf(out_port, "mfba_mad::data[17]: "U32H_FMT"\n", data_to_print->data[17]); + fprintf(out_port, "mfba_mad::data[18]: "U32H_FMT"\n", data_to_print->data[18]); + fprintf(out_port, "mfba_mad::data[19]: "U32H_FMT"\n", data_to_print->data[19]); + fprintf(out_port, "mfba_mad::data[20]: "U32H_FMT"\n", data_to_print->data[20]); + fprintf(out_port, "mfba_mad::data[21]: "U32H_FMT"\n", data_to_print->data[21]); + fprintf(out_port, "mfba_mad::data[22]: "U32H_FMT"\n", data_to_print->data[22]); + fprintf(out_port, "mfba_mad::data[23]: "U32H_FMT"\n", data_to_print->data[23]); + fprintf(out_port, "mfba_mad::data[24]: "U32H_FMT"\n", data_to_print->data[24]); + fprintf(out_port, "mfba_mad::data[25]: "U32H_FMT"\n", data_to_print->data[25]); + fprintf(out_port, "mfba_mad::data[26]: "U32H_FMT"\n", data_to_print->data[26]); + fprintf(out_port, "mfba_mad::data[27]: "U32H_FMT"\n", data_to_print->data[27]); + fprintf(out_port, "mfba_mad::data[28]: "U32H_FMT"\n", data_to_print->data[28]); + fprintf(out_port, "mfba_mad::data[29]: "U32H_FMT"\n", data_to_print->data[29]); + fprintf(out_port, "mfba_mad::data[30]: "U32H_FMT"\n", data_to_print->data[30]); + fprintf(out_port, "mfba_mad::data[31]: "U32H_FMT"\n", data_to_print->data[31]); +} diff --git a/mflash/internal_packets.h b/mflash/internal_packets.h new file mode 100755 index 0000000..5dcb9b1 --- /dev/null +++ b/mflash/internal_packets.h @@ -0,0 +1,76 @@ +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) June 2000, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + * End of legal section ...................................................... + * +*/ +/*** + *** This file was generated at "Mon May 30 15:06:41 2011" + *** by: + *** % csp_pack_unpack.pm ../xml_files/packets_st.csp + ***/ + +#ifndef internal_packets_functions_H +#define internal_packets_functions_H + +#include "internal_packets_types.h" +#include + +/*************************************/ +/* Name: mfbe + * Size: 96 bits + * Description: mfbe */ + +u_int32_t mfbe_pack(struct mfbe *data_to_pack, u_int8_t *packed_buffer); +void mfbe_unpack(struct mfbe *unpacked_data, u_int8_t *buffer_to_unpack); +void mfbe_dump(struct mfbe *data_to_print, FILE *out_port); + + +/*************************************/ +/* Name: mfpa + * Size: 256 bits + * Description: mfpa */ + +u_int32_t mfpa_pack(struct mfpa *data_to_pack, u_int8_t *packed_buffer); +void mfpa_unpack(struct mfpa *unpacked_data, u_int8_t *buffer_to_unpack); +void mfpa_dump(struct mfpa *data_to_print, FILE *out_port); + + +/*************************************/ +/* Name: reg_tlv + * Size: 32 bits + * Description: reg_tlv */ + +u_int32_t reg_tlv_pack(struct reg_tlv *data_to_pack, u_int8_t *packed_buffer); +void reg_tlv_unpack(struct reg_tlv *unpacked_data, u_int8_t *buffer_to_unpack); +void reg_tlv_dump(struct reg_tlv *data_to_print, FILE *out_port); + +/*************************************/ +/* Name: mfba_mad + * Size: 352 bits + * Description: mfba_mad */ + +u_int32_t mfba_mad_pack(struct mfba_mad *data_to_pack, u_int8_t *packed_buffer); +void mfba_mad_unpack(struct mfba_mad *unpacked_data, u_int8_t *buffer_to_unpack); +void mfba_mad_dump(struct mfba_mad *data_to_print, FILE *out_port); + + +/*************************************/ +/* Name: OperationTlv + * Size: 128 bits + * Description: */ + +u_int32_t OperationTlv_pack(struct OperationTlv *data_to_pack, u_int8_t *packed_buffer); +void OperationTlv_unpack(struct OperationTlv *unpacked_data, u_int8_t *buffer_to_unpack); +void OperationTlv_dump(struct OperationTlv *data_to_print, FILE *out_port); + + +#endif /* internal_packets_functions_H */ diff --git a/mflash/internal_packets_types.h b/mflash/internal_packets_types.h new file mode 100755 index 0000000..5699439 --- /dev/null +++ b/mflash/internal_packets_types.h @@ -0,0 +1,177 @@ +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) June 2000, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + * End of legal section ...................................................... + * +*/ +/*** + *** This file was generated at "Mon May 30 15:06:41 2011" + *** by: + *** % csp_pack_unpack.pm ../xml_files/packets_st.csp + ***/ + +#ifndef internal_packets_structs_H +#define internal_packets_structs_H + +#include +#include + +/*************************************/ +/* Name: mfbe + * Size: 96 bits + * Description: mfbe */ + +struct mfbe { + u_int8_t reserved0; /* bit_offset:0 */ /* element_size: 4 */ + u_int8_t fs; /* bit_offset:4 */ /* element_size: 2 */ /* Flash Select */ + u_int8_t reserved1; /* bit_offset:6 */ /* element_size: 2 */ + u_int8_t p; /* bit_offset:8 */ /* element_size: 1 */ /* Parallel */ + u_int32_t reserved2; /* bit_offset:9 */ /* element_size: 23 */ + u_int32_t reserved3; /* bit_offset:32 */ /* element_size: 32 */ + u_int32_t address; /* bit_offset:64 */ /* element_size: 24 */ /* address in bytes */ + u_int8_t reserved4; /* bit_offset:88 */ /* element_size: 8 */ +}; + + +/*************************************/ +/* Name: mfba + * Size: 2144 bits + * Description: mfba */ + +struct mfba { + u_int8_t reserved0; /* bit_offset:0 */ /* element_size: 4 */ + u_int8_t fs; /* bit_offset:4 */ /* element_size: 2 */ /* Flash Select */ + u_int8_t reserved1; /* bit_offset:6 */ /* element_size: 2 */ + u_int8_t p; /* bit_offset:8 */ /* element_size: 1 */ /* Parallel */ + u_int32_t reserved2; /* bit_offset:9 */ /* element_size: 23 */ + u_int16_t size; /* bit_offset:32 */ /* element_size: 9 */ /* Transaction size */ + u_int32_t reserved3; /* bit_offset:41 */ /* element_size: 23 */ + u_int32_t address; /* bit_offset:64 */ /* element_size: 24 */ /* address in bytes */ + u_int8_t reserved4; /* bit_offset:88 */ /* element_size: 8 */ + u_int32_t data[64]; /* bit_offset:96 */ /* element_size: 32 */ /* data */ +}; + + +/*************************************/ +/* Name: mfpa + * Size: 288 bits + * Description: mfpa */ + +struct mfpa { + u_int8_t reserved0; /* bit_offset:0 */ /* element_size: 4 */ + u_int8_t fs; /* bit_offset:4 */ /* element_size: 2 */ /* Flash Select */ + u_int8_t reserved1; /* bit_offset:6 */ /* element_size: 2 */ + u_int8_t p; /* bit_offset:8 */ /* element_size: 1 */ /* Parallel */ + u_int32_t reserved2; /* bit_offset:9 */ /* element_size: 23 */ + u_int32_t boot_address; /* bit_offset:32 */ /* element_size: 24 */ /* address in bytes */ + u_int8_t reserved3; /* bit_offset:56 */ /* element_size: 8 */ + u_int32_t reserved4; /* bit_offset:64 */ /* element_size: 64 */ + u_int8_t flash_num; /* bit_offset:128 */ /* element_size: 4 */ /* number of flash devices connected */ + u_int32_t reserved5; /* bit_offset:132 */ /* element_size: 28 */ + u_int32_t jedec_id; /* bit_offset:160 */ /* element_size: 24 */ /* Flash JEDEC ID */ + u_int8_t reserved6; /* bit_offset:184 */ /* element_size: 8 */ + u_int16_t sector_size; /* bit_offset:192 */ /* element_size: 10 */ /* Flash sectore size */ + u_int8_t reserved7; /* bit_offset:202 */ /* element_size: 6 */ + u_int8_t block_allighment; /* bit_offset:208 */ /* element_size: 8 */ + u_int8_t reserved8; /* bit_offset:216 */ /* element_size: 8 */ + u_int32_t capability_mask; /* bit_offset:224 */ /* element_size: 32 */ /* capability mask ;bit 0:Parallel flash Support;else:Reserved */ + u_int32_t reserved9; /* bit_offset:256 */ /* element_size: 32 */ +}; + + + +/*************************************/ +/* Name: REG_Mfpa + * Size: 384 bits + * Description: */ + +struct REG_Mfpa { + u_int16_t reserved0; /* bit_offset:0 */ /* element_size: 16 */ + u_int16_t len; /* bit_offset:16 */ /* element_size: 11 */ + u_int8_t type; /* bit_offset:27 */ /* element_size: 5 */ + u_int8_t reserved1; /* bit_offset:32 */ /* element_size: 4 */ + u_int8_t fs; /* bit_offset:36 */ /* element_size: 2 */ /* Flash Select */ + u_int8_t reserved2; /* bit_offset:38 */ /* element_size: 2 */ + u_int8_t p; /* bit_offset:40 */ /* element_size: 1 */ /* parallel - Index */ + u_int32_t reserved3; /* bit_offset:41 */ /* element_size: 23 */ + u_int32_t boot_address; /* bit_offset:64 */ /* element_size: 24 */ /* Boot address points to the FW image in the flash - R/W */ + u_int8_t reserved4; /* bit_offset:88 */ /* element_size: 8 */ + u_int32_t reserved5; /* bit_offset:96 */ /* element_size: 64 */ + u_int8_t flash_num; /* bit_offset:160 */ /* element_size: 4 */ /* Number of Flash Devices connected */ + u_int32_t reserved6; /* bit_offset:164 */ /* element_size: 28 */ + u_int32_t jedec_id; /* bit_offset:192 */ /* element_size: 24 */ /* Flash JEDEC ID */ + u_int8_t reserved7; /* bit_offset:216 */ /* element_size: 8 */ + u_int16_t sector_size; /* bit_offset:224 */ /* element_size: 10 */ /* Flash Sector Size */ + u_int8_t reserved8; /* bit_offset:234 */ /* element_size: 6 */ + u_int8_t block_allignment; /* bit_offset:240 */ /* element_size: 8 */ /* Required allignment for block access */ + u_int8_t reserved9; /* bit_offset:248 */ /* element_size: 8 */ + u_int32_t capcability_mask; /* bit_offset:256 */ /* element_size: 32 */ + u_int32_t reserved10; /* bit_offset:288 */ /* element_size: 96 */ +}; + +/*************************************/ +/* Name: reg_tlv + * Size: 32 bits + * Description: reg_tlv */ + +struct reg_tlv { + u_int16_t reserved0; /* bit_offset:0 */ /* element_size: 16 */ + u_int16_t len; /* bit_offset:16 */ /* element_size: 11 */ + u_int8_t Type; /* bit_offset:27 */ /* element_size: 5 */ /* TX - 0, RX - ignore */ +}; + +/*************************************/ +/* Name: mfba_mad + * Size: 352 bits + * Description: mfba_mad */ + +struct mfba_mad { + u_int8_t reserved0; /* bit_offset:0 */ /* element_size: 4 */ + u_int8_t fs; /* bit_offset:4 */ /* element_size: 2 */ /* Flash Select */ + u_int8_t reserved1; /* bit_offset:6 */ /* element_size: 2 */ + u_int8_t p; /* bit_offset:8 */ /* element_size: 1 */ /* Parallel */ + u_int32_t reserved2; /* bit_offset:9 */ /* element_size: 23 */ + u_int16_t size; /* bit_offset:32 */ /* element_size: 9 */ /* Transaction size */ + u_int32_t reserved3; /* bit_offset:41 */ /* element_size: 23 */ + u_int32_t address; /* bit_offset:64 */ /* element_size: 24 */ /* address in bytes */ + u_int8_t reserved4; /* bit_offset:88 */ /* element_size: 8 */ + u_int32_t data[64]; /* bit_offset:96 */ /* element_size: 32 */ /* data */ +}; + + +/*************************************/ +/* Name: OperationTlv + * Size: 128 bits + * Description: */ + +struct OperationTlv { + u_int8_t reserved0; /* bit_offset:0 */ /* element_size: 8 */ + u_int8_t status; /* bit_offset:8 */ /* element_size: 7 */ + u_int8_t dr; /* bit_offset:15 */ /* element_size: 1 */ + u_int16_t len; /* bit_offset:16 */ /* element_size: 11 */ + u_int8_t Type; /* bit_offset:27 */ /* element_size: 5 */ /* TX - 0, RX - ignore */ + u_int8_t class; /* bit_offset:32 */ /* element_size: 8 */ + u_int8_t method; /* bit_offset:40 */ /* element_size: 7 */ + u_int8_t r; /* bit_offset:47 */ /* element_size: 1 */ + u_int16_t register_id; /* bit_offset:48 */ /* element_size: 16 */ + u_int64_t tid; /* bit_offset:64 */ /* element_size: 64 */ +}; +/*************************************/ +/* Name: SMP_RegAccessMfpa + * Size: 512 bits + * Description: */ + +struct SMP_RegAccessMfpa { + struct OperationTlv OperationTlv; /* bit_offset:0 */ /* element_size: 128 */ + struct REG_Mfpa REG_Mfpa; /* bit_offset:128 */ /* element_size: 384 */ +}; + +#endif /* internal_packets_structs_H */ diff --git a/mflash/mflash.c b/mflash/mflash.c index a20eb9e..a9adaa7 100644 --- a/mflash/mflash.c +++ b/mflash/mflash.c @@ -68,6 +68,8 @@ #define MERGE_C64(rsrc1,rsrc2,start,len) ((((u_int64_t)(rsrc2)<<(start)) & (MASK64((start),(len)))) | ((rsrc1) & (~MASK64((start),(len))))) #define MERGE64(rsrc1,rsrc2,start,len) (((len)==64)?(rsrc2):MERGE_C64(rsrc1,rsrc2,start,len)) +#include "mflash.h" + #ifndef __WIN__ #if defined __DJGPP__ @@ -81,14 +83,20 @@ #define bswap_32(x) ntohl(x) -#else // Linux GCC - +#else +#ifdef __FreeBSD__ +#define SWAPL(l) ntohl(l) +#include +#else // Linux #include #include +#endif #endif // __DJGPP__ +#ifndef __FreeBSD__ #define SWAPL(l) bswap_32(l) +#endif #ifndef __cpu_to_be32 #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -113,11 +121,11 @@ #define __cpu_to_be32(val) SWAPL(val) // Win is only run on LE CPUS #define OP_NOT_SUPPORTED EINVAL +#define usleep(x) Sleep(((x + 999)/1000) ) #endif // __WIN__ #endif -#include "mflash.h" #ifndef __be32_to_cpu #define __be32_to_cpu(val) __cpu_to_be32(val) @@ -141,64 +149,16 @@ /* Flash Functions: */ //typedef struct mflash *mflash; -typedef int (*f_mf_lock) (mflash* mfl, int lock_state); - -typedef int (*f_mf_set_bank) (mflash* mfl, u_int32_t bank); -typedef int (*f_mf_read) (mflash* mfl, u_int32_t addr, u_int32_t len, u_int8_t* data); -typedef int (*f_mf_write) (mflash* mfl, u_int32_t addr, u_int32_t len, u_int8_t* data); -typedef int (*f_mf_erase_sect)(mflash* mfl, u_int32_t addr); -typedef int (*f_mf_reset) (mflash* mfl); - -typedef int (*f_st_spi_status)(mflash* mfl, u_int8_t op_type, u_int8_t* status); -typedef int (*f_mf_get_info) (mflash* mfl, unsigned *type_index, int *log2size, u_int8_t *no_flash); - // This is an interface function when running in IRISC -int mf_open_fw(mflash* mfl, flash_params_t* flash_params); +int mf_open_fw(mflash* mfl, flash_params_t* flash_params, int num_of_banks); int cntx_int_spi_get_status_data(mflash* mfl, u_int8_t op_type, u_int32_t* status, u_int8_t data_num); // // mflash struct // -#ifndef IRISC -#define MFLASH_ERR_STR_SIZE 1024 -#else -#define MFLASH_ERR_STR_SIZE 4 -#endif - -struct mflash { -#ifndef IRISC - mfile* mf; -#endif - - // Functions: - f_mf_lock f_lock; - f_mf_set_bank f_set_bank; - f_mf_get_info f_get_info; - - f_mf_read f_read; - f_mf_write f_write; - f_mf_write f_write_blk; // write and write_block have the same signateure, but theyr'e not the same func ! - f_mf_read f_read_blk; // read and read_block have the same signateure, but theyr'e not the same func ! - f_mf_erase_sect f_erase_sect; - f_mf_reset f_reset; - - // Relevant for SPI flash (InfiniHostIIILx, ConnectX) only. - f_st_spi_status f_spi_status; - - int curr_bank; - int is_locked; - - flash_attr attr; - - int opts[MFO_LAST]; - char last_err_str[MFLASH_ERR_STR_SIZE]; - - u_int8_t access_type; - uefi_Dev_t *uefi_dev; - f_fw_cmd uefi_cmd_func; - -}; +#include "mflash_common.h" +#include "mflash_access_layer.h" // NOTE: This macro returns ... not nice. @@ -217,7 +177,7 @@ struct mflash { #define MWRITE4(offs, val) do { if (mwrite4(mfl->mf, offs, val) != 4) { \ /*fprintf(stderr, "-E- Cr write (0x%08x, 0x%08x) failed: %s(%d)\n", (u_int32_t)(offs), (u_int32_t)(val), strerror(errno), (u_int32_t)errno);*/ \ - mclose(mfl->mf); return 2; } /*printf("-D- %s:%d mwrite4: offs = %#x, val = %#x\n", __FUNCTION__, __LINE__, offs, val);*/ \ + return 2; } /*printf("-D- %s:%d mwrite4: offs = %#x, val = %#x\n", __FUNCTION__, __LINE__, offs, val);*/ \ } while (0) #endif @@ -256,17 +216,29 @@ struct mflash { #define CONNECT_IB_HW_ID 0x1FF +// Write/Erase delays +// ------------------ +// The below delays improve CPU utilization when doing long operations by +// sleeping instead of full throtle polling. +// Their values are set so they will not lenghen burn time (at least not by a meaningfull duration) +// and will save cpu. The delays are divided to an initial_delay, and then retry num_of_retries times waiting retry_delay. +// The initial delay is set according to the fastest flash we currently support (W25QxxBV). +// The retry_delay*num_of_retries is set according to the slowest flash maximum AC timing. +// +// To test there's no performance degradation by these delay: set DELAYS to 0 and RETRIES to infinity, and compare perf. + enum FlashConstant { + // All time values are in usecs + WRITE_BLOCK_INIT_DELAY = 10, + WRITE_ADDITIONAL_BYTE_DELAY = 1, + WRITE_BLOCK_RETRY_DELAY = 10, + WRITE_BLOCK_RETRIES = 30000, + + ERASE_SUBSECTOR_INIT_DELAY = 20000, + ERASE_SUBSECTOR_RETRY_DELAY = 300, + ERASE_SUBSECTOR_RETRIES = 10000, + FLASH_CMD_CNT = 5000, // Number of reads till flash cmd is zeroed - ERASE_DELAY = 200000, // Delay between reads when wating for sector erase - ERASE_CNT = 1000000, // Maximal number of reads when wating for sector erase - READ_CNT_FAST = 50000, // Number of fast reads after write byte - READ_CNT_SLOW = 50, // Number of slow reads after write byte - READ_DELAY = 100000, // Delay between slow reads after write byte - WR_REPORT_FAST = 256, // Report frequency when write (fast interfaces) - WR_REPORT_SLOW = 4, // Report frequency when write (slow interfaces) - RD_REPORT_FAST = 4096, // Report frequency when read (fast interfaces) - RD_REPORT_SLOW = 64, // Report frequency when read (slow interfaces) GPIO_SEM_TRIES = 1024 , // Number of tries to obtain a GPIO sem. MAX_WRITE_BUFFER_SIZE = 256 // Max buffer size for buffer write devices }; @@ -297,29 +269,14 @@ enum IntelFlashStatus { FS_BlockError = 0x3F }; -enum SXAccessType{ - SXT_NO = 0, - SXT_INBAND, - SXT_CMDIF, +enum AccessTypeByMfile{ + ATBM_NO = 0, + ATBM_INBAND, + ATBM_MLNXOS_CMDIF, + ATBM_ICMD, }; -#define WRITE_CHECK_ALLIGN(addr, block_write, size) {\ - if (addr & ((u_int32_t)block_write - 1)) {\ - return MFE_BAD_ALIGN;\ - }\ - if (size & ((u_int32_t)block_write - 1)) {\ - return MFE_BAD_ALIGN;\ - }\ -} - -#define COM_CHECK_ALLIGN(flash_addr, size) {\ - if (flash_addr & (size - 1 )) {\ - return MFE_BAD_ALIGN;\ - }\ -} - - //static inline static u_int32_t log2up (u_int32_t in) { u_int32_t i; @@ -360,7 +317,8 @@ int cntx_st_spi_block_write_ex (mflash* mfl, u_int32_t blk_size, u_int8_t* data, u_int8_t is_first, - u_int8_t is_last); + u_int8_t is_last, + u_int32_t total_size); int cntx_sst_spi_block_write_ex (mflash* mfl, u_int32_t blk_addr, @@ -567,13 +525,16 @@ typedef struct flash_info { #define WINBOND_NAME "W25QxxBV" #define WINBOND_W25X "W25Xxx" #define ATMEL_NAME "AT25DFxxx" -#define FMT_ST_M25P_NAME +#define S25FLXXXP_NAME "S25FLXXXP" +#define S25FL116K_NAME "S25FL11xx" typedef enum flash_vendor { FV_ST = 0x20, FV_SST = 0xbf, FV_WINBOND = 0xef, FV_ATMEL = 0x1f, + FV_S25FLXXXP = 0x01, + FV_S25FL116K = 0x01, } flash_vendor_t; typedef enum flash_memory_type { @@ -584,7 +545,8 @@ typedef enum flash_memory_type { FMT_WINBOND_W25X = 0x30, FMT_ATMEL = 0x2, FMT_N25QXXX = 0xba, - + FMT_S25FLXXXP = 0x02, + FMT_S25FL116K = 0x40, } flash_memory_type; flash_info_t g_flash_info_arr[] = @@ -596,6 +558,8 @@ flash_info_t g_flash_info_arr[] = {WINBOND_NAME, FV_WINBOND, FMT_WINBOND, MCS_STSPI, SFC_SSE, 0x1000, 1, 1}, {WINBOND_W25X, FV_WINBOND, FMT_WINBOND_W25X, MCS_STSPI, SFC_SSE, 0x1000, 0, 0}, {ATMEL_NAME, FV_ATMEL, FMT_ATMEL, MCS_STSPI, SFC_SSE, 0x1000, 0, 0}, + {S25FLXXXP_NAME, FV_S25FLXXXP, FMT_S25FLXXXP, MCS_STSPI, SFC_SE, 0x10000, 0, 0}, + {S25FL116K_NAME, FV_S25FL116K, FMT_S25FL116K, MCS_STSPI, SFC_SSE, 0x1000, 0, 0}, // this flash actually supports quad and write protect but we dont need it at this moment }; int cntx_sst_get_log2size(u_int8_t capacity, int* log2spi_size) @@ -646,6 +610,25 @@ int get_type_index_by_vendor_and_type(u_int8_t vendor, u_int8_t type, unsigned * return MFE_UNSUPPORTED_FLASH_TYPE; } +void mf_flash_list(char *flash_arr) +{ + int i; + int arr_index = 0; + + int arr_size = ARR_SIZE(g_flash_info_arr); + for (i = 0; i < arr_size; i++) { + flash_info_t *flash_info = &g_flash_info_arr[i]; + int name_len = strlen(flash_info->name); + strcpy(&flash_arr[arr_index], flash_info->name); + arr_index += name_len; + if (i != arr_size - 1) { + flash_arr[arr_index++] = ','; + flash_arr[arr_index++] = ' '; + } + } + flash_arr[arr_index] = '\0'; + return; +} int get_type_index_by_name(char *type_name, unsigned *type_index) { @@ -835,6 +818,7 @@ int spi_fill_attr_from_params(mflash* mfl, flash_params_t* flash_params, unsigne return MFE_OK; } +#define GET_FLASH_RETRY 2 int st_spi_fill_attr(mflash* mfl, flash_params_t* flash_params) { int rc; @@ -846,9 +830,19 @@ int st_spi_fill_attr(mflash* mfl, flash_params_t* flash_params) { // printf("-D- st_spi_fill_attr: ignore_detect = %d, log2size = %#x.\n", mfl->ignore_flash_detect, mfl->user_attr.log2size); if (flash_params == NULL) { + int i = 0; // Get flash params from the flash itself cur_flash_params = &tmp_flash_params; - rc = get_flash_params(mfl, cur_flash_params, &type_index); CHECK_RC(rc); + + while (i < GET_FLASH_RETRY) { + rc = get_flash_params(mfl, cur_flash_params, &type_index); + if (rc != MFE_NO_FLASH_DETECTED) { + break; + } + i++; + } + CHECK_RC(rc); + } else { // Get the flash params from the user. rc = get_type_index_by_name(flash_params->type_name, &type_index); CHECK_RC(rc); @@ -863,26 +857,23 @@ int st_spi_fill_attr(mflash* mfl, flash_params_t* flash_params) { return MFE_OK; } -int st_spi_wait_wip(mflash* mfl, u_int32_t delay, u_int32_t retrys, u_int32_t fast_retrys) { +int st_spi_wait_wip(mflash* mfl, u_int32_t init_delay_us, u_int32_t retry_delay_us, u_int32_t num_of_retries) { int rc; u_int8_t status; - u_int32_t cnt = 0; + u_int32_t i; - delay = 0; // UNUSED FOR NOW + usleep(init_delay_us); - do { - if (++cnt > fast_retrys) { - //usleep(delay); - } - if (cnt > retrys) { - return MFE_WRITE_TIMEOUT; + for (i = 0; i < num_of_retries; ++i) { + rc = mfl->f_spi_status(mfl, SFC_RDSR, &status); CHECK_RC(rc); + if ((status & 1) == 0) { + return MFE_OK; } + usleep(retry_delay_us); + } - rc = mfl->f_spi_status(mfl, SFC_RDSR, &status); - } while (status & 0x01); - - return MFE_OK; + return MFE_WRITE_TIMEOUT; } int read_chunks (mflash* mfl, u_int32_t addr, u_int32_t len, u_int8_t* data) { @@ -1107,6 +1098,8 @@ int is_sx(u_int32_t dev_id) { } return 0; } + + int is_is4_family(u_int32_t dev_id) { if (dev_id == 435 || // InfiniScaleIV dev_id == 6100) { // BridgeX @@ -1329,7 +1322,12 @@ int spi_update_num_of_banks(mflash* mfl, int prev_num_of_flashes) num_of_banks = spi_get_num_of_flashes(prev_num_of_flashes); if (num_of_banks == -1) { - mfl->opts[MFO_NUM_OF_BANKS] = MAX_NUM_OF_FLASH_BANKS; + if (is_sx(mfl->attr.hw_dev_id)) { + mfl->opts[MFO_NUM_OF_BANKS] = 2; + } else { + mfl->opts[MFO_NUM_OF_BANKS] = 1; + } + mfl->opts[MFO_USER_BANKS_NUM] = 0; } else { mfl->opts[MFO_NUM_OF_BANKS] = num_of_banks; @@ -1499,7 +1497,7 @@ int cntx_st_spi_page_write (mflash* mfl, u_int32_t addr, u_int32_t size, u_in if (addr == last_blk_addr) { is_last = 1; } - rc = cntx_st_spi_block_write_ex(mfl, addr, mfl->attr.block_write, p, is_first, is_last); CHECK_RC(rc); + rc = cntx_st_spi_block_write_ex(mfl, addr, mfl->attr.block_write, p, is_first, is_last, size); CHECK_RC(rc); is_first = 0; addr += mfl->attr.block_write; @@ -1529,7 +1527,7 @@ int cntx_sst_spi_byte_write (mflash* mfl, u_int32_t addr, u_int32_t size, u_i return MFE_OK; } -int cntx_st_spi_block_write_ex (mflash* mfl, u_int32_t blk_addr, u_int32_t blk_size, u_int8_t* data, u_int8_t is_first, u_int8_t is_last) { +int cntx_st_spi_block_write_ex (mflash* mfl, u_int32_t blk_addr, u_int32_t blk_size, u_int8_t* data, u_int8_t is_first, u_int8_t is_last, u_int32_t total_size) { int rc; u_int32_t offs; u_int32_t gw_cmd = 0; @@ -1593,7 +1591,7 @@ int cntx_st_spi_block_write_ex (mflash* mfl, u_int32_t blk_addr, u_int32_t blk_s // if (is_last) { - rc = st_spi_wait_wip(mfl, READ_DELAY, READ_CNT_SLOW + READ_CNT_FAST, READ_CNT_FAST); CHECK_RC(rc); + rc = st_spi_wait_wip(mfl, WRITE_BLOCK_INIT_DELAY + WRITE_ADDITIONAL_BYTE_DELAY * total_size, WRITE_BLOCK_RETRY_DELAY, WRITE_BLOCK_RETRIES); CHECK_RC(rc); } return MFE_OK; @@ -1634,66 +1632,16 @@ int cntx_sst_spi_block_write_ex (mflash* mfl, u_int32_t blk_addr, u_int32_t blk_ rc = cntx_exec_cmd(mfl, gw_cmd, "PB command"); CHECK_RC(rc); - rc = st_spi_wait_wip(mfl, READ_DELAY, READ_CNT_SLOW + READ_CNT_FAST, READ_CNT_FAST); CHECK_RC(rc); + rc = st_spi_wait_wip(mfl, 0, 0, 50000); CHECK_RC(rc); // Full throttle polling - no cpu optimization for this flash return MFE_OK; } int cntx_st_spi_block_write (mflash* mfl, u_int32_t blk_addr, u_int32_t blk_size, u_int8_t* data) { - return cntx_st_spi_block_write_ex(mfl, blk_addr, blk_size, data, 1, 1); + return cntx_st_spi_block_write_ex(mfl, blk_addr, blk_size, data, 1, 1, blk_size); } -int cntx_st_spi_block_write_old (mflash* mfl, u_int32_t blk_addr, u_int32_t blk_size, u_int8_t* data) { - int rc; - u_int32_t offs; - u_int32_t gw_cmd = 0; - u_int32_t gw_addr = 0; - - COM_CHECK_ALLIGN(blk_addr, blk_size); - - // sanity check ??? remove ??? - if (blk_size != (u_int32_t)mfl->attr.block_write ) { - return MFE_BAD_PARAMS; - } - - rc = set_bank(mfl, blk_addr); CHECK_RC(rc); - - rc = cntx_st_spi_write_enable(mfl); CHECK_RC(rc); - - // Write the data block - gw_cmd = MERGE(gw_cmd, 1 , HBO_CMD_PHASE, 1); - gw_cmd = MERGE(gw_cmd, 1 , HBO_ADDR_PHASE, 1); - gw_cmd = MERGE(gw_cmd, 1 , HBO_DATA_PHASE, 1); - - gw_cmd = MERGE(gw_cmd, log2up(blk_size), HBO_MSIZE, HBS_MSIZE); - gw_cmd = MERGE(gw_cmd, SFC_PP , HBO_CMD, HBS_CMD); - - gw_addr = blk_addr & ONES32(mfl->attr.log2_bank_size); - - MWRITE4(HCR_FLASH_ADDR, gw_addr); - - // Data: - for (offs = 0 ; offs < blk_size ; offs += 4) { - u_int32_t word = zero; - word = MERGE(word, data[offs + 0] , 24 , 8); - word = MERGE(word, data[offs + 1] , 16 , 8); - word = MERGE(word, data[offs + 2] , 8 , 8); - word = MERGE(word, data[offs + 3] , 0 , 8); - MWRITE4(HCR_FLASH_DATA + offs, word ); - } - - rc = cntx_exec_cmd(mfl, gw_cmd, "PP command"); CHECK_RC(rc); - - // - // Wait for end of write in flash (WriteInProgress = 0): - // - - rc = st_spi_wait_wip(mfl, READ_DELAY, READ_CNT_SLOW + READ_CNT_FAST, READ_CNT_FAST); CHECK_RC(rc); - - return MFE_OK; - } - int cntx_st_spi_erase_sect(mflash* mfl, u_int32_t addr) { int rc; @@ -1717,7 +1665,7 @@ int cntx_st_spi_erase_sect(mflash* mfl, u_int32_t addr) { rc = cntx_exec_cmd(mfl, gw_cmd, "ES"); CHECK_RC(rc); // Wait for erase completion - rc = st_spi_wait_wip(mfl, ERASE_DELAY, ERASE_CNT, 0); CHECK_RC(rc); + rc = st_spi_wait_wip(mfl, ERASE_SUBSECTOR_INIT_DELAY, ERASE_SUBSECTOR_RETRY_DELAY, ERASE_SUBSECTOR_RETRIES); CHECK_RC(rc); return MFE_OK; } @@ -1905,7 +1853,7 @@ int check_cache_replacement_gaurd(mflash* mfl, u_int8_t *needs_cache_replacement *needs_cache_replacement = 0; // When we access via command interface, we assume there is a cache replacement! - if (mfl->opts[MFO_SX_TYPE] == SXT_CMDIF) { + if (mfl->opts[MFO_FW_ACCESS_TYPE_BY_MFILE] == ATBM_MLNXOS_CMDIF) { *needs_cache_replacement = 1; return MFE_OK; } @@ -2018,172 +1966,40 @@ int mfl_get_bank_info(mflash *mfl, u_int32_t addr, u_int32_t *flash_off_p, int * return MFE_OK; } - -#ifdef NO_INBAND_ACCESS - -int sx_get_flash_info(mflash* mfl, unsigned *type_index, int *log2size, u_int8_t *no_flash) -{ - mfl = NULL; - type_index = NULL; - log2size = NULL; - no_flash = NULL; - return MFE_NOT_SUPPORTED_OPERATION; -} - -int sx_block_read(mflash* mfl, u_int32_t blk_addr, u_int32_t blk_size, u_int8_t* data) -{ - mfl = NULL; - blk_addr = 0; - blk_size = 0; - data = NULL; - - return MFE_NOT_SUPPORTED_OPERATION; -} - -int sx_block_write(mflash* mfl, u_int32_t addr, u_int32_t size, u_int8_t* data) -{ - mfl = NULL; - addr = 0; - size = 0; - data = NULL; - return MFE_NOT_SUPPORTED_OPERATION; -} - -int sx_flash_lock(mflash* mfl, int lock_state) -{ - mfl = NULL; - lock_state = 0; - return MFE_NOT_SUPPORTED_OPERATION; -} - -int sx_erase_sect(mflash* mfl, u_int32_t addr) -{ - mfl = NULL; - addr = 0; - return MFE_NOT_SUPPORTED_OPERATION; -} - -#else - -#include "mflash_inband.h" -#include "mflash_cmdif.h" -#include "mflash_uefi.h" - typedef int (*f_sx_flash_lock) (mflash* mfl, int lock_state); typedef int (*f_sx_erase_sect) (mflash* mfl, u_int32_t addr); typedef int (*f_sx_block_access) (mflash* mfl, u_int32_t addr, u_int32_t size, u_int8_t* data); typedef int (*f_sx_get_flash_info) (mflash* mfl, unsigned *type_index, int *log2size, u_int8_t *no_flash); -#ifdef __WIN__ - // On windows we don't support cmdIf access! -#define EXEC_FLASH_ACCESS_FUNC(mfl, inband_func, cmdif_func, arg, uefi_func, uefi_args) {\ - int rc;\ - if (mfl->access_type == MFAT_MFILE) {\ - if ( mfl->opts[MFO_SX_TYPE] == SXT_INBAND) {\ - rc = inband_func arg; CHECK_RC(rc);\ - } else {\ - return MFE_NOT_SUPPORTED_OPERATION;\ - }\ - } else {\ - return MFE_UNKOWN_ACCESS_TYPE;\ - }\ -} - -#else - -#define EXEC_FLASH_ACCESS_FUNC(mfl, inband_func, cmdif_func, arg, uefi_func, uefi_args) {\ - int rc;\ - if (mfl->access_type == MFAT_MFILE) {\ - if ( mfl->opts[MFO_SX_TYPE] == SXT_INBAND) {\ - rc = inband_func arg; CHECK_RC(rc);\ - } else {\ - rc = cmdif_func arg; CHECK_RC(rc);\ - }\ - } else if (mfl->access_type == MFAT_UEFI) {\ - rc = uefi_func uefi_args; CHECK_RC(rc);\ - } else {\ - return MFE_UNKOWN_ACCESS_TYPE;\ - }\ -} - -#endif int sx_get_flash_info(mflash* mfl, unsigned *type_index, int *log2size, u_int8_t *no_flash) { - int rc; - u_int8_t vendor, type, capacity; - u_int32_t jedec_id; - - EXEC_FLASH_ACCESS_FUNC(mfl, mfi_get_jedec, mfci_get_jedec, (mfl->mf, mfl->curr_bank, &jedec_id), - mfu_get_jedec, (mfl->uefi_dev, mfl->uefi_cmd_func, mfl->curr_bank, &jedec_id)); - - //printf("-D- jedec_id = %#x\n", jedec_id); - rc = get_info_from_jededc_id(jedec_id, &vendor, &type, &capacity); CHECK_RC(rc); - - // Return there is no flash when all the params are 0xff - if (vendor == 0xff && type == 0xff && capacity == 0xff) { - *no_flash = 1; - return MFE_OK; - } - rc = get_type_index_by_vendor_and_type(vendor, type, type_index); CHECK_RC(rc); - rc = get_log2size_by_capcity(*type_index, capacity, log2size); CHECK_RC(rc); - return MFE_OK; - + return sx_get_flash_info_by_type(mfl, type_index, log2size, no_flash); } -// This + int sx_block_read(mflash* mfl, u_int32_t blk_addr, u_int32_t blk_size, u_int8_t* data) { - int rc, bank; - u_int32_t flash_offset; - - if (blk_size > (u_int32_t)mfl->attr.block_write || blk_size < 4) { - return MFE_BAD_PARAMS; - } - rc = mfl_get_bank_info(mfl, blk_addr, &flash_offset, &bank); CHECK_RC(rc); - COM_CHECK_ALLIGN(flash_offset, blk_size); - EXEC_FLASH_ACCESS_FUNC(mfl, mfi_read_block, mfci_read_block, (mfl->mf, flash_offset, bank, blk_size, data), - mfu_read_block, (mfl->uefi_dev, mfl->uefi_cmd_func, flash_offset, bank, blk_size, data)); - return MFE_OK; + return sx_block_read_by_type(mfl, blk_addr, blk_size, data); } int sx_block_write(mflash* mfl, u_int32_t addr, u_int32_t size, u_int8_t* data) { - int rc, bank; - u_int32_t flash_offset; - - WRITE_CHECK_ALLIGN(addr, mfl->attr.block_write, size); - - - rc = mfl_get_bank_info(mfl, addr, &flash_offset, &bank); CHECK_RC(rc); - COM_CHECK_ALLIGN(flash_offset, size); - EXEC_FLASH_ACCESS_FUNC(mfl, mfi_write_block, mfci_write_block, (mfl->mf, flash_offset, bank, size, data), - mfu_write_block, (mfl->uefi_dev, mfl->uefi_cmd_func, flash_offset, bank, size, data)); - return MFE_OK; + return sx_block_write_by_type(mfl, addr, size, data); } int sx_flash_lock(mflash* mfl, int lock_state) { - EXEC_FLASH_ACCESS_FUNC(mfl, mfi_flash_lock, mfci_flash_lock, (mfl->mf, lock_state), - mfu_flash_lock, (mfl->uefi_dev, mfl->uefi_cmd_func, lock_state)); - - return MFE_OK; + return sx_flash_lock_by_type(mfl, lock_state); } int sx_erase_sect(mflash* mfl, u_int32_t addr) { - int rc, bank; - u_int32_t flash_addr; - - rc = mfl_get_bank_info(mfl, addr, &flash_addr, &bank); CHECK_RC(rc); - EXEC_FLASH_ACCESS_FUNC(mfl, mfi_erase_sector, mfci_erase_sector, (mfl->mf, flash_addr, bank), - mfu_erase_sector, (mfl->uefi_dev, mfl->uefi_cmd_func, flash_addr, bank)); - - return MFE_OK; + return sx_erase_sect_by_type(mfl, addr); } -#endif + int empty_get_status(mflash* mfl, u_int8_t op_type, u_int8_t* status) { // Avoid warnings @@ -2194,8 +2010,6 @@ int empty_get_status(mflash* mfl, u_int8_t op_type, u_int8_t* status) return MFE_NOT_SUPPORTED_OPERATION; } -#define CMDIF_MAX_BLOCK_WRITE 128 -#define INBAND_MAX_BLOCK_WRITE 32 int flash_init_inband_access(mflash* mfl, flash_params_t* flash_params) { int rc; @@ -2219,10 +2033,13 @@ int flash_init_inband_access(mflash* mfl, flash_params_t* flash_params) // Get the flash attribute rc = st_spi_fill_attr(mfl, flash_params); CHECK_RC(rc); - mfl->attr.block_write = INBAND_MAX_BLOCK_WRITE; - mfl->attr.page_write = INBAND_MAX_BLOCK_WRITE; - - + if ( mfl->opts[MFO_FW_ACCESS_TYPE_BY_MFILE] == ATBM_ICMD) { + mfl->attr.block_write = ICMD_MAX_BLOCK_WRITE; + mfl->attr.page_write = ICMD_MAX_BLOCK_WRITE; + } else { + mfl->attr.block_write = INBAND_MAX_BLOCK_WRITE; + mfl->attr.page_write = INBAND_MAX_BLOCK_WRITE; + } return MFE_OK; } @@ -2264,7 +2081,7 @@ int flash_init_fw_access(mflash* mfl, flash_params_t* flash_params) // This function checks the access type in order to select the access functions int rc; - if ( mfl->opts[MFO_SX_TYPE] != SXT_NO) { + if ( mfl->opts[MFO_FW_ACCESS_TYPE_BY_MFILE] != ATBM_NO) { rc = flash_init_inband_access(mfl, flash_params); CHECK_RC(rc); } else { return MFE_DIRECT_FW_ACCESS_DISABLED; @@ -2287,7 +2104,29 @@ int sx_flash_init(mflash* mfl, flash_params_t* flash_params) return MFE_OK; } +#ifndef _MTCR_UL_ +int icmd_init(mflash *mfl) +{ + mfl->cif_dev = gcif_open(mfl->mf); + if (mfl->cif_dev == NULL) { + return MFE_ICMD_INIT_FAILED; + } + // Clear semaphore when asked to by flint or any tool using mflash + if (mfl->opts[MFO_IGNORE_SEM_LOCK]) { + if (gcif_clear_semaphore(mfl->cif_dev) != GCIF_STATUS_SUCCESS) { + return MFE_CR_ERROR; + } + } + mfl->cmdif_context = mfl->cif_dev; + return MFE_OK; +} +#else +int icmd_init(mflash *mfl) { + mfl = NULL; + return MFE_NOT_IMPLEMENTED; +} +#endif int connectib_flash_init(mflash* mfl, flash_params_t* flash_params) { @@ -2297,6 +2136,9 @@ int connectib_flash_init(mflash* mfl, flash_params_t* flash_params) rc = check_cache_replacement_gaurd(mfl, &needs_cache_replacement); CHECK_RC(rc); if (needs_cache_replacement) { + if (mfl->opts[MFO_FW_ACCESS_TYPE_BY_MFILE] == ATBM_ICMD) { + rc = icmd_init(mfl); CHECK_RC(rc); + } rc = flash_init_fw_access(mfl, flash_params); CHECK_RC(rc); } else { rc = connectib_init_direct_access(mfl, flash_params); CHECK_RC(rc); @@ -2308,20 +2150,22 @@ int connectib_flash_init(mflash* mfl, flash_params_t* flash_params) // Interface functions: // +#define CHECK_OUT_OF_RANGE(addr, len, size) {\ + if (addr > size || addr + len > size) {\ + return MFE_OUT_OF_RANGE;\ + }\ +} + int mf_read (mflash* mfl, u_int32_t addr, u_int32_t len, u_int8_t* data) { // printf("mfl->attr.size = %#x, addr = %#x, len = %d\n", mfl->attr.size, addr, len); - if (addr + len > mfl->attr.size) { - return MFE_OUT_OF_RANGE; - } + + CHECK_OUT_OF_RANGE(addr, len, mfl->attr.size); //printf("-D- mf_read: addr: %#x, len: %d\n", addr, len); return mfl->f_read(mfl, addr, len, data); } int mf_write (mflash* mfl, u_int32_t addr, u_int32_t len, u_int8_t* data) { - if (addr + len > mfl->attr.size) { - return MFE_OUT_OF_RANGE; - } - + CHECK_OUT_OF_RANGE(addr, len, mfl->attr.size); return mfl->f_write(mfl, addr, len, data); } @@ -2334,7 +2178,7 @@ int mf_erase_sector(mflash* mfl, u_int32_t addr) { int mf_open_ignore_lock(mflash* mfl) { mfl->opts[MFO_IGNORE_SEM_LOCK] = 1; - return mf_open_fw(mfl, NULL); + return mf_open_fw(mfl, NULL, 0); } @@ -2343,68 +2187,77 @@ int mf_open_ignore_lock(mflash* mfl) { #define CR_LOCK_HW_ID 0xbad0cafe -int update_sx_type(mflash* mfl) +int get_dev_info(mflash* mfl) { u_int32_t dev_flags; int rc; - // The opt MFO_SX_TYPE will be used only when work on SX device - mfl->opts[MFO_SX_TYPE] = SXT_NO; + u_int32_t dev_id; + // The opt MFO_FW_ACCESS_TYPE_BY_MFILE will be used only when work on SX device + mfl->opts[MFO_FW_ACCESS_TYPE_BY_MFILE] = ATBM_NO; rc = mget_mdevs_flags(mfl->mf, &dev_flags); CHECK_RC(rc); - if (dev_flags & MDEVS_IB) { - mfl->opts[MFO_SX_TYPE] = SXT_INBAND; - } else if (dev_flags & MDEVS_MLNX_OS) { - mfl->opts[MFO_SX_TYPE] = SXT_CMDIF; - } + if (dev_flags & MDEVS_MLNX_OS) { + // HACK: When we have a mlnxsw device we don't have any access to cr-space so we will assume we work on SX + dev_id = SWITCHX_HW_ID; + mfl->attr.rev_id = 0; + mfl->attr.hw_dev_id = SWITCHX_HW_ID; + mfl->opts[MFO_FW_ACCESS_TYPE_BY_MFILE] = ATBM_MLNXOS_CMDIF; + } else { + MREAD4(HW_DEV_ID, &dev_id); + if (dev_id == CR_LOCK_HW_ID) { + return MFE_LOCKED_CRSPACE; + } + mfl->attr.rev_id = (dev_id & 0xff0000) >> 16; + mfl->attr.hw_dev_id = dev_id & 0xffff; + + if (dev_flags & MDEVS_IB) { + mfl->opts[MFO_FW_ACCESS_TYPE_BY_MFILE] = ATBM_INBAND; + } else { + if (is_connectib(mfl->attr.hw_dev_id)) { + if (mfl->opts[MFO_IGNORE_CASHE_REP_GUARD] == 0) { + mfl->opts[MFO_FW_ACCESS_TYPE_BY_MFILE] = ATBM_ICMD; + } + } + } + } + return MFE_OK; } //Caller must zero the mflash struct before calling this func. -int mf_open_fw(mflash* mfl, flash_params_t* flash_params) +int mf_open_fw(mflash* mfl, flash_params_t* flash_params, int num_of_banks) { int rc; - u_int32_t dev_id; if (!mfl) { return MFE_BAD_PARAMS; } mfl->curr_bank = -1; - if (mfl->access_type == MFAT_MFILE ) { - rc = update_sx_type(mfl); CHECK_RC(rc); - //printf("-D- mf_open_fw: mget_mdevs_flags\n"); - if (mfl->opts[MFO_SX_TYPE] == SXT_CMDIF) { - // HACK: When we have a mlnxsw device we don't have any access to cr-space so we will assume we work on SX - dev_id = SWITCHX_HW_ID; - } else { - MREAD4(HW_DEV_ID, &dev_id); - } - if (dev_id == CR_LOCK_HW_ID) { - return MFE_LOCKED_CRSPACE; - } + rc = get_dev_info(mfl); CHECK_RC(rc); - mfl->attr.rev_id = (dev_id & 0xff0000) >> 16; + mfl->opts[MFO_NUM_OF_BANKS] = spi_get_num_of_flashes(num_of_banks); + rc = spi_update_num_of_banks(mfl, num_of_banks); CHECK_RC(rc); - dev_id &= 0xffff; - mfl->attr.hw_dev_id = dev_id; - if (dev_id == 23108 || dev_id == 25208 || dev_id == 24204 || dev_id == 25204) { + if (mfl->attr.hw_dev_id == 23108 || mfl->attr.hw_dev_id == 25208 || mfl->attr.hw_dev_id == 24204 || mfl->attr.hw_dev_id == 25204) { rc = MFE_OLD_DEVICE_TYPE; - } else if (is_connectx_family(dev_id)) { + } else if (is_connectx_family(mfl->attr.hw_dev_id)) { rc = cntx_flash_init(mfl, flash_params); - } else if (is_is4_family(dev_id)) { + } else if (is_is4_family(mfl->attr.hw_dev_id)) { rc = is4_flash_init(mfl, flash_params); - } else if (is_sx(dev_id)) { + } else if (is_sx(mfl->attr.hw_dev_id)) { rc = sx_flash_init(mfl, flash_params); - } else if (is_connectib(dev_id)) { + } else if (is_connectib(mfl->attr.hw_dev_id)) { rc = connectib_flash_init(mfl, flash_params); - } else if (dev_id == 0xffff) { - printf("-E- Read a corrupted device id (0x%x). Probably HW/PCI access problem\n", dev_id); + } else if (mfl->attr.hw_dev_id == 0xffff) { + printf("-E- Read a corrupted device id (0x%x). Probably HW/PCI access problem\n", mfl->attr.hw_dev_id); rc = MFE_CR_ERROR; } else { rc = MFE_UNSUPPORTED_DEVICE; } CHECK_RC(rc); } else if (mfl->access_type == MFAT_UEFI) { + mfl->opts[MFO_NUM_OF_BANKS] = 1; // We have only one flash in Golan and ConnectX-3 - Need to specify it better! rc = uefi_flash_init(mfl, flash_params); CHECK_RC(rc); } else { return MFE_UNKOWN_ACCESS_TYPE; @@ -2423,9 +2276,6 @@ int mf_opend_int (mflash** pmfl, void* access_dev, int num_of_banks, f } memset(*pmfl, 0, sizeof(mflash)); - (*pmfl)->opts[MFO_NUM_OF_BANKS] = spi_get_num_of_flashes(num_of_banks); - - rc = spi_update_num_of_banks((*pmfl), num_of_banks); CHECK_RC(rc); (*pmfl)->opts[MFO_IGNORE_CASHE_REP_GUARD] = ignore_cache_rep_guard; (*pmfl)->access_type = access_type; @@ -2436,8 +2286,9 @@ int mf_opend_int (mflash** pmfl, void* access_dev, int num_of_banks, f (*pmfl)->uefi_dev = (uefi_Dev_t*)access_dev; (*pmfl)->uefi_cmd_func = (f_fw_cmd)access_func; } + (*pmfl)->cmdif_context = access_dev; - rc = mf_open_fw(*pmfl, flash_params); + rc = mf_open_fw(*pmfl, flash_params, num_of_banks); return rc; } @@ -2495,6 +2346,13 @@ int mf_close (mflash* mfl) { return MFE_BAD_PARAMS; } + +#ifndef _MTCR_UL_ + if (mfl->cif_dev) { + gcif_close(mfl->cif_dev); + } +#endif + if (mfl->f_reset) { mfl->f_reset(mfl); } @@ -2563,7 +2421,7 @@ const char* mf_err2str (int err_code) { "MFE_CMDIF_BAD_STATUS_ERR", "MFE_CMDIF_TIMEOUT_ERR", "MFE_CMDIF_GO_BIT_BUSY", - "MFE_MISMATCH_KEY", + "The given key is incorrect", "MFE_UNKNOWN_REG", "MFE_REG_ACCESS_FAILED", "MFE_REG_ACCESS_MAD_BAD_STATUS", @@ -2581,6 +2439,10 @@ const char* mf_err2str (int err_code) { "MFE_UNKOWN_ACCESS_TYPE", "MFE_UNSUPPORTED_DEVICE", "MFE_OLD_DEVICE_TYPE", + "MFE_ICMD_INIT_FAILED", + "MFE_REG_ACCESS_ICMD_NOT_SUPPPRTOED", + "Secure host mode is not enabled in this FW.", + "MFE_ICMD_BAD_PARAM", }; return err_code < (int)ARRSIZE(mf_err_str) ? mf_err_str[err_code] : NULL; @@ -2616,18 +2478,9 @@ int mf_cr_write (mflash* mfl, u_int32_t cr_addr, u_int32_t data) { return MFE_OK; } -#define BOOT_CR_SPACE_ADDR 0xf0000 -int mf_update_boot_addr(mflash* mfl, u_int32_t boot_addr) +int mf_update_boot_addr(mflash* mfl, u_int32_t boot_addr) { - int rc; -//orenk -// if (mfl->access_type == MFAT_UEFI || mfl->opts[MFO_SX_TYPE] == SXT_CMDIF) { -// EXEC_FLASH_ACCESS_FUNC(mfl, mfi_update_boot_addr, mfci_update_boot_addr, (mfl->mf, mfl->curr_bank, boot_addr), -// mfu_update_boot_addr, (mfl->uefi_dev, mfl->uefi_cmd_func, mfl->curr_bank, boot_addr)); -// } else { - rc = mf_cr_write(mfl, BOOT_CR_SPACE_ADDR, ((boot_addr << 8) | 0x06)); CHECK_RC(rc); -// } - return MFE_OK; + return mf_update_boot_addr_by_type(mfl, boot_addr); } int mf_read_modify_status (mflash *mfl, u_int8_t bank_num, u_int8_t first_byte, u_int8_t param, u_int8_t offset, u_int8_t size) @@ -2848,6 +2701,7 @@ static int cmd_if_send(mflash* mfl, mf_cmd_if_t* cmd) u_int32_t raw_cmd[CMD_IF_SIZE/4]; int act_retries; int rc; + u_int32_t hcr_header; // Check if the go BIT is ready rc = cmd_if_wait_go(mfl, NULL); @@ -2865,6 +2719,12 @@ static int cmd_if_send(mflash* mfl, mf_cmd_if_t* cmd) raw_cmd[6] = MERGE(raw_cmd[6], 1, 23, 1); // go MWRITE4(TOOLS_HCR_ADDR + 24, raw_cmd[6]); + // Check if the command is supported at all + MREAD4(TOOLS_HCR_ADDR + 24, &hcr_header); + if (!hcr_header) { + return MFE_HW_ACCESS_NOT_SUPP; + } + rc = cmd_if_wait_go(mfl, &act_retries); if (rc) { return MFE_CMDIF_TIMEOUT_ERR; @@ -2899,7 +2759,6 @@ int cmdif_hw_access_int(mflash* mfl, u_int64_t key, u_int8_t opcode_modifier) cmd.in_param = key; rc = cmd_if_send(mfl, &cmd); - // Special case if (rc == MFE_CMDIF_BAD_STATUS_ERR && cmd.opcode_modifier == 0) { if (cmd.status == MISMATCH_KEY_RC) { diff --git a/mflash/mflash.h b/mflash/mflash.h index 4e99d35..a574af2 100644 --- a/mflash/mflash.h +++ b/mflash/mflash.h @@ -117,6 +117,10 @@ typedef enum MfError { MFE_UNKOWN_ACCESS_TYPE, MFE_UNSUPPORTED_DEVICE, MFE_OLD_DEVICE_TYPE, + MFE_ICMD_INIT_FAILED, + MFE_REG_ACCESS_ICMD_NOT_SUPPPRTOED, + MFE_HW_ACCESS_NOT_SUPP, + MFE_ICMD_BAD_PARAM, MFE_LAST } MfError; @@ -129,7 +133,7 @@ typedef enum MfOpt { MFO_NUM_OF_BANKS, MFO_IGNORE_CASHE_REP_GUARD, MFO_USER_BANKS_NUM, - //MFO_FW_ACCESS_TYPE_BY_MFILE, + MFO_FW_ACCESS_TYPE_BY_MFILE, MFO_SX_TYPE, MFO_NEW_CACHE_REPLACEMENT_EN, MFO_LAST @@ -140,8 +144,6 @@ enum MfAccessType { MFAT_UEFI, }; -#define MAX_NUM_OF_FLASH_BANKS 4 - ///////////////////////////////////////////// // // Flash attributes struct @@ -296,6 +298,8 @@ int mf_release_semaphore(); // const char* mf_err2str (int err_code); +void mf_flash_list(char *flash_list); + EXTERN_C_END #endif // MFLASH_H diff --git a/mflash/mflash_access_layer.c b/mflash/mflash_access_layer.c new file mode 100755 index 0000000..014ff74 --- /dev/null +++ b/mflash/mflash_access_layer.c @@ -0,0 +1,180 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + + +#include +#include +#include + +#include "mflash.h" +#include "mflash_common.h" +#include "mflash_inband.h" +#include "mflash_access_layer.h" + + +#ifdef NO_INBAND_ACCESS + +int sx_get_flash_info_by_type(mflash* mfl, unsigned *type_index, int *log2size, u_int8_t *no_flash) +{ + mfl = NULL; + type_index = NULL; + log2size = NULL; + no_flash = NULL; + return MFE_NOT_SUPPORTED_OPERATION; +} + +int sx_block_read_by_type(mflash* mfl, u_int32_t blk_addr, u_int32_t blk_size, u_int8_t* data) +{ + mfl = NULL; + blk_addr = 0; + blk_size = 0; + data = NULL; + + return MFE_NOT_SUPPORTED_OPERATION; +} + +int sx_block_write_by_type(mflash* mfl, u_int32_t addr, u_int32_t size, u_int8_t* data) +{ + mfl = NULL; + addr = 0; + size = 0; + data = NULL; + return MFE_NOT_SUPPORTED_OPERATION; +} + +int sx_flash_lock_by_type(mflash* mfl, int lock_state) +{ + mfl = NULL; + lock_state = 0; + return MFE_NOT_SUPPORTED_OPERATION; +} + +int sx_erase_sect_by_type(mflash* mfl, u_int32_t addr) +{ + mfl = NULL; + addr = 0; + return MFE_NOT_SUPPORTED_OPERATION; +} + +#else + +int sx_get_flash_info_by_type(mflash* mfl, unsigned *type_index, int *log2size, u_int8_t *no_flash) +{ + int rc; + u_int8_t vendor, type, capacity; + u_int32_t jedec_id; + + rc = mfi_get_jedec(mfl->cmdif_context, (mfl->curr_bank), &jedec_id); + CHECK_RC(rc); + + //printf("-D- jedec_id = %#x\n", jedec_id); + rc = get_info_from_jededc_id(jedec_id, &vendor, &type, &capacity); CHECK_RC(rc); + + // Return there is no flash when all the params are 0xff + if (vendor == 0xff && type == 0xff && capacity == 0xff) { + *no_flash = 1; + return MFE_OK; + } + rc = get_type_index_by_vendor_and_type(vendor, type, type_index); CHECK_RC(rc); + rc = get_log2size_by_capcity(*type_index, capacity, log2size); CHECK_RC(rc); + return MFE_OK; + +} + +int sx_block_read_by_type(mflash* mfl, u_int32_t blk_addr, u_int32_t blk_size, u_int8_t* data) +{ + int rc, bank; + u_int32_t flash_offset; + + if (blk_size > (u_int32_t)mfl->attr.block_write || blk_size < 4) { + return MFE_BAD_PARAMS; + } + rc = mfl_get_bank_info(mfl, blk_addr, &flash_offset, &bank); CHECK_RC(rc); + COM_CHECK_ALLIGN(flash_offset, blk_size); + rc = mfi_read_block(mfl->cmdif_context, flash_offset, bank, blk_size, data); + CHECK_RC(rc); + return MFE_OK; +} + +int sx_block_write_by_type(mflash* mfl, u_int32_t addr, u_int32_t size, u_int8_t* data) +{ + int rc, bank; + u_int32_t flash_offset; + + WRITE_CHECK_ALLIGN(addr, mfl->attr.block_write, size); + + rc = mfl_get_bank_info(mfl, addr, &flash_offset, &bank); CHECK_RC(rc); + COM_CHECK_ALLIGN(flash_offset, size); + rc = mfi_write_block(mfl->cmdif_context, flash_offset, bank, size, data); + CHECK_RC(rc); + return MFE_OK; +} + +int sx_flash_lock_by_type(mflash* mfl, int lock_state) +{ + int rc; + rc = mfi_flash_lock(mfl->cmdif_context, lock_state); + CHECK_RC(rc); + + return MFE_OK; +} + +int sx_erase_sect_by_type(mflash* mfl, u_int32_t addr) +{ + int rc, bank; + u_int32_t flash_addr; + + rc = mfl_get_bank_info(mfl, addr, &flash_addr, &bank); + CHECK_RC(rc); + rc = mfi_erase_sector(mfl->cmdif_context, flash_addr, bank); + CHECK_RC(rc); + + return MFE_OK; +} + +#endif + +#define BOOT_CR_SPACE_ADDR 0xf0000 +#define ATBM_MLNXOS_CMDIF 2 +int mf_update_boot_addr_by_type(mflash* mfl, u_int32_t boot_addr) +{ + int rc; + if (mfl->access_type == MFAT_UEFI || mfl->opts[MFO_FW_ACCESS_TYPE_BY_MFILE] == ATBM_MLNXOS_CMDIF) { + return MFE_NOT_SUPPORTED_OPERATION; + } else { + rc = mf_cr_write(mfl, BOOT_CR_SPACE_ADDR, ((boot_addr << 8) | 0x06)); CHECK_RC(rc); + } + return MFE_OK; +} + +//////////////////////////// Function that sends mads ////////////////////////////////////// +int maccess_reg_mad_wrapper(flash_access_t *facces, u_int8_t *data, int w_cmdif_size, int r_cmdif_size) +{ + //avoid warnings + w_cmdif_size=0; + r_cmdif_size=0; + // + + int rc; + if (facces->access_type == FWACCESS_INBAND) { + rc = maccess_reg_mad(facces->mf, data); + if (rc) { + //printf("-E- 2. Access reg mad failed with rc = %#x\n", rc); + return MFE_REG_ACCESS_FAILED; + } + } else { + return MFE_NOT_IMPLEMENTED; + } + return MFE_OK; +} diff --git a/mflash/mflash_access_layer.h b/mflash/mflash_access_layer.h new file mode 100755 index 0000000..3ad013a --- /dev/null +++ b/mflash/mflash_access_layer.h @@ -0,0 +1,93 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +/* + * mflash_inband.h + * + * Created on: Jul 6, 2011 + * Author: mohammad + */ + +#ifndef MFLASH_ACCESS_LAYER_H_ +#define MFLASH_ACCESS_LAYER_H_ + +#include + +#ifndef IRISC +#define MFLASH_ERR_STR_SIZE 1024 +#else +#define MFLASH_ERR_STR_SIZE 4 +#endif + + +typedef int (*f_mf_lock) (mflash* mfl, int lock_state); + +typedef int (*f_mf_set_bank) (mflash* mfl, u_int32_t bank); +typedef int (*f_mf_read) (mflash* mfl, u_int32_t addr, u_int32_t len, u_int8_t* data); +typedef int (*f_mf_write) (mflash* mfl, u_int32_t addr, u_int32_t len, u_int8_t* data); +typedef int (*f_mf_erase_sect)(mflash* mfl, u_int32_t addr); +typedef int (*f_mf_reset) (mflash* mfl); + +typedef int (*f_st_spi_status)(mflash* mfl, u_int8_t op_type, u_int8_t* status); +typedef int (*f_mf_get_info) (mflash* mfl, unsigned *type_index, int *log2size, u_int8_t *no_flash); + +struct mflash { +#ifndef IRISC + mfile* mf; +#endif + + // Functions: + f_mf_lock f_lock; + + f_mf_set_bank f_set_bank; + f_mf_get_info f_get_info; + + f_mf_read f_read; + f_mf_write f_write; + f_mf_write f_write_blk; // write and write_block have the same signateure, but theyr'e not the same func ! + f_mf_read f_read_blk; // read and read_block have the same signateure, but theyr'e not the same func ! + f_mf_erase_sect f_erase_sect; + f_mf_reset f_reset; + + // Relevant for SPI flash (InfiniHostIIILx, ConnectX) only. + f_st_spi_status f_spi_status; + + int curr_bank; + int is_locked; + + flash_attr attr; + + int opts[MFO_LAST]; + char last_err_str[MFLASH_ERR_STR_SIZE]; + + u_int8_t access_type; + uefi_Dev_t *uefi_dev; + f_fw_cmd uefi_cmd_func; + + gcif_dev_t *cif_dev; + void* cmdif_context; + +}; + + +int sx_get_flash_info_by_type(mflash* mfl, unsigned *type_index, int *log2size, u_int8_t *no_flash); +int sx_block_read_by_type(mflash* mfl, u_int32_t blk_addr, u_int32_t blk_size, u_int8_t* data); +int sx_block_write_by_type(mflash* mfl, u_int32_t addr, u_int32_t size, u_int8_t* data); +int sx_flash_lock_by_type(mflash* mfl, int lock_state); +int sx_erase_sect_by_type(mflash* mfl, u_int32_t addr); +int mf_update_boot_addr_by_type(mflash* mfl, u_int32_t boot_addr); +int maccess_reg_mad_wrapper(flash_access_t *facces, u_int8_t *data, int w_cmdif_size, int r_cmdif_size); + + +#endif /* MFLASH_ACCESS_LAYER_H_ */ diff --git a/mflash/mflash_common.c b/mflash/mflash_common.c new file mode 100755 index 0000000..7c7b5f3 --- /dev/null +++ b/mflash/mflash_common.c @@ -0,0 +1,138 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +#include +#include +#include + +#include "mflash.h" +#include "mflash_common.h" + +int init_operation_tlv(struct OperationTlv *operation_tlv, u_int16_t reg_id, u_int8_t method) +{ + memset(operation_tlv, 0, sizeof(*operation_tlv)); + + operation_tlv->Type = TLV_OPERATION; + operation_tlv->class = MAD_CLASS_REG_ACCESS; + operation_tlv->len = TLV_OPERATION_SIZE; + operation_tlv->method = method; + operation_tlv->register_id = reg_id; + return MFE_OK; +} + +int get_reg_info_by_id(u_int16_t reg_id, reg_info_t *reg_info) +{ + u_int32_t i; + reg_info_t reg_info_arr[] = { + {REG_ID_MFPA, RTL_MFPA_LEN, (f_reg_pack)mfpa_pack, (f_reg_unpack)mfpa_unpack, (f_reg_dump)mfpa_dump}, + {REG_ID_MFBA, RTL_MFBA_LEN, (f_reg_pack)mfba_mad_pack, (f_reg_unpack)mfba_mad_unpack, (f_reg_dump)mfba_mad_dump}, + {REG_ID_MFBE, RTL_MFBE_LEN, (f_reg_pack)mfbe_pack, (f_reg_unpack)mfbe_unpack, (f_reg_dump)mfbe_dump}, + }; + + for (i = 0; i < ARR_SIZE(reg_info_arr); i++) { + reg_info_t curr_reg = reg_info_arr[i]; + if (reg_id == curr_reg.id) { + *reg_info = curr_reg; + return MFE_OK; + } + } + return MFE_UNKNOWN_REG; +} + + +int sx_st_block_access(flash_access_t *faccess, u_int32_t flash_addr, u_int8_t bank, u_int32_t size, u_int8_t* data, + u_int8_t method) +{ + struct mfba_mad mfba; + int rc; + u_int32_t max_size = CMDIF_MAX_BLOCK_WRITE; + + if (faccess->access_type == FWACCESS_INBAND) { + max_size = INBAND_MAX_BLOCK_WRITE; + } + + if (size > max_size) { + return MFE_BAD_PARAMS; + } + + // rc = set_bank(mfl, addr); CHECK_RC(rc); + //rc = get_flash_offset(addr, mfl->attr.log2_bank_size, &flash_addr); CHECK_RC(rc); + + + // Init mfba + memset(&mfba, 0, sizeof(mfba)); + mfba.address = flash_addr; + mfba.fs = bank; + mfba.size = size; + + if (method == MAD_METHOD_WRITE) { + u_int32_t i; + for (i = 0; i < size/4; i++) { + mfba.data[i] = __le32_to_cpu(*((u_int32_t*)&(data[4*i]))); + } + } + + rc = mfi_reg_access_mad(faccess, REG_ID_MFBA, method, &mfba, 0); CHECK_RC(rc); + + // Get data from mfba + if (method == MAD_METHOD_QUERY) { + u_int32_t i; + for (i = 0; i < size/4; i++) { + *((u_int32_t*)&(data[i*4]))= __cpu_to_le32(mfba.data[i]); + } + } + return MFE_OK; +} + + +int common_erase_sector(flash_access_t *faccess, u_int32_t addr, u_int8_t flash_bank) +{ + struct mfbe mfbe; + + memset(&mfbe, 0, sizeof(mfbe)); + mfbe.address = addr; + mfbe.fs = flash_bank; + return mfi_reg_access_mad(faccess, REG_ID_MFBE, MAD_METHOD_WRITE, &mfbe, 0); +} + + + +int run_mfpa_command(flash_access_t *faccess, u_int8_t access_cmd, u_int8_t flash_bank, u_int32_t boot_address, u_int32_t *jedec_p) +{ + struct mfpa mfpa; + int rc; + + memset(&mfpa, 0, sizeof(mfpa)); + mfpa.fs = flash_bank; + + if (access_cmd == MAD_METHOD_WRITE) { + mfpa.boot_address = boot_address; + } + + rc = mfi_reg_access_mad(faccess, REG_ID_MFPA, access_cmd, &mfpa, 0); CHECK_RC(rc); + + if (access_cmd == MAD_METHOD_QUERY && jedec_p != NULL) { + *jedec_p = mfpa.jedec_id; + // HACK: FW had a bug and returned the same jedec-ID even there was no flash, so when flash doesn't exist jedec will be modified to 0xffffffff + if (flash_bank >= mfpa.flash_num) { + *jedec_p = 0xffffffff; + } + } + return MFE_OK; +} + +int com_get_jedec(flash_access_t *faccess, u_int8_t flash_bank, u_int32_t *jedec_p) +{ + return run_mfpa_command(faccess, MAD_METHOD_QUERY, flash_bank, 0, jedec_p); +} diff --git a/mflash/mflash_common.h b/mflash/mflash_common.h new file mode 100755 index 0000000..48183a3 --- /dev/null +++ b/mflash/mflash_common.h @@ -0,0 +1,182 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +/* + * mflash_inband.h + * + * Created on: Jul 6, 2011 + * Author: mohammad + */ + +#ifndef MFLASH_COMMON_H_ +#define MFLASH_COMMON_H_ + +#include +#include "internal_packets.h" + +#ifndef _MTCR_UL_ + #include "cib_cif.h" +#else + typedef void gcif_dev_t; +#endif + +#define CMDIF_MAX_BLOCK_WRITE 128 +#define ICMD_MAX_BLOCK_WRITE 128 +#define INBAND_MAX_BLOCK_WRITE 32 + +#ifndef CHECK_RC + #define CHECK_RC(rc) do {if (rc) return rc;} while(0) +#endif + +#ifndef ARR_SIZE + #define ARR_SIZE(arr) sizeof(arr)/sizeof(arr[0]) +#endif + +enum { + FWACCESS_INBAND = 0, + FWACCESS_UEFI, + FWACCESS_GCIF, + FWACCESS_ALL, +}; + +#ifndef __WIN__ + +#ifdef __FreeBSD__ +#define SWAPL(l) ntohl(l) +#include +#else // Linux +#include +#include + +#define SWAPL(l) bswap_32(l) +#endif + +#else + +#include +#include +#define SWAPL(l) ntohl(l) +#define __BYTE_ORDER __LITTLE_ENDIAN +/* +#define __cpu_to_be32(val) SWAPL(val) // Win is only run on LE CPUS +#define inline __inline +#define __cpu_to_be32(val) SWAPL(val) // Win is only run on LE CPUS +*/ +#endif + +#ifndef __cpu_to_le32 + +#if __BYTE_ORDER == __LITTLE_ENDIAN + #define __cpu_to_le32(x) (x) +#elif __BYTE_ORDER == __BIG_ENDIAN + #define __cpu_to_le32(x) SWAPL(x) +#endif // __BYTE_ORDER + +#endif + +#ifndef __le32_to_cpu + #define __le32_to_cpu(x) __cpu_to_le32(x) +#endif + +#ifndef UEFI_BUILD + #define _ENABLE_MFLASH_INBAND_DEBUG 1 +#endif + +typedef struct flash_access { + mfile *mf; + u_int8_t access_type; // 0 = mf, 1 = uefi + uefi_Dev_t *uefi_dev; + f_fw_cmd fw_cmd_func; + gcif_dev_t *gcif_dev; +} flash_access_t; + +enum { + MAD_METHOD_QUERY = 1, + MAD_METHOD_WRITE = 2, +}; +enum { + MAD_CLASS_REG_ACCESS = 1, +}; +enum { + TLV_END = 0, + TLV_OPERATION = 1, + TLV_DR = 2, + TLV_REG = 3, + TLV_USER_DATA = 4, +}; +enum { + REG_ID_MFPA = 0x9010, + REG_ID_MFBA = 0x9011, + REG_ID_MFBE = 0x9012, +}; + +enum { + RTL_MFPA_LEN = 9, + RTL_INBAND_MFBA_LEN = 12, + RTL_MFBA_LEN = 36, + RTL_MFBE_LEN = 4, +}; + +#define WRITE_CHECK_ALLIGN(addr, block_write, size) {\ + if (addr & ((u_int32_t)block_write - 1)) {\ + return MFE_BAD_ALIGN;\ + }\ + if (size & ((u_int32_t)block_write - 1)) {\ + return MFE_BAD_ALIGN;\ + }\ +} + +#define COM_CHECK_ALLIGN(flash_addr, size) {\ + if (flash_addr & (size - 1 )) {\ + return MFE_BAD_ALIGN;\ + }\ +} + +#define TLV_OPERATION_SIZE 4 +#define OP_TLV_SIZE 16 +#define REG_RLV_HEADER_LEN 4 + +//////////////////////////////////// SX FLASH functions //////////////////////////////////// + +typedef u_int32_t (*f_reg_pack) (void *data_to_pack, u_int8_t *packed_buffer); +typedef void (*f_reg_unpack) (void *unpacked_data, u_int8_t *buffer_to_unpack); +typedef void (*f_reg_dump) (void *data_to_print, FILE *out_port); + +typedef struct reg_info { + u_int16_t id; + u_int16_t len; + f_reg_pack pack_func; + f_reg_unpack unpack_func; + f_reg_dump dump_func; +} reg_info_t; + + +int init_operation_tlv(struct OperationTlv *operation_tlv, u_int16_t reg_id, u_int8_t method); + +int get_reg_info_by_id(u_int16_t reg_id, reg_info_t *reg_info); + +int sx_st_block_access(flash_access_t *faccess, u_int32_t flash_addr, u_int8_t bank, u_int32_t size, u_int8_t* data, + u_int8_t method); + +int common_erase_sector(flash_access_t *faccess, u_int32_t addr, u_int8_t flash_bank); + +int run_mfpa_command(flash_access_t *faccess, u_int8_t access_cmd, u_int8_t flash_bank, u_int32_t boot_address, u_int32_t *jedec_p); + +int com_get_jedec(flash_access_t *faccess, u_int8_t flash_bank, u_int32_t *jedec_p); +int get_info_from_jededc_id(u_int32_t jededc_id, u_int8_t *vendor, u_int8_t* type, u_int8_t* capacity); +int get_type_index_by_vendor_and_type(u_int8_t vendor, u_int8_t type, unsigned *type_index); +int get_log2size_by_capcity(unsigned type_index, u_int8_t capacity, int *log2size); +int mfl_get_bank_info(mflash *mfl, u_int32_t addr, u_int32_t *flash_off_p, int *bank_p); + +#endif /* MFLASH_COMMON_H_ */ diff --git a/mflash/mflash_inband.c b/mflash/mflash_inband.c new file mode 100755 index 0000000..a1287ec --- /dev/null +++ b/mflash/mflash_inband.c @@ -0,0 +1,154 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +#include +#include +#include + +#include "mflash.h" +#include "mflash_common.h" +#include "mflash_access_layer.h" +#include "mflash_inband.h" + + +int mfi_reg_access_mad(flash_access_t *faccess, u_int16_t reg_id, u_int8_t method, void *reg, u_int8_t debug) +{ + int rc, mad_rc, cmdif_size = 0, wcmdif_size, rcmdif_size; + struct OperationTlv tlv; + struct reg_tlv tlv_info; + u_int8_t buffer[1024]; + reg_info_t reg_info; + + rc = get_reg_info_by_id(reg_id, ®_info); CHECK_RC(rc); + + init_operation_tlv(&(tlv), reg_id, method); + // Fill Reg TLV + memset(&tlv_info, 0, sizeof(tlv_info)); + tlv_info.Type = TLV_REG; + tlv_info.len = reg_info.len; + + // The max MAD buffer size is 64 so max data that can be read is only 32 byte + if ((reg_id == REG_ID_MFBA && faccess->access_type == FWACCESS_INBAND )|| + (reg_id == REG_ID_MFBA && faccess->access_type == FWACCESS_UEFI) ) { + tlv_info.len = RTL_INBAND_MFBA_LEN; + } + + // Pack the mad + + cmdif_size += OperationTlv_pack(&tlv, buffer); + cmdif_size += reg_tlv_pack(&tlv_info, buffer + OP_TLV_SIZE); + cmdif_size += reg_info.pack_func(reg, buffer + OP_TLV_SIZE + REG_RLV_HEADER_LEN); +#ifdef _ENABLE_MFLASH_INBAND_DEBUG + if (debug) { + printf("-I- The sent MAD content\n"); + OperationTlv_dump(&tlv, stdout); + reg_tlv_dump(&tlv_info, stdout); + reg_info.dump_func(reg, stdout); + } +#endif + // printf("-D- reg_info.len = |%d, OP_TLV: %d, REG_TLV= %d, cmdif_size = %d\n", reg_info.len, OP_TLV_SIZE, REG_RLV_HEADER_LEN, cmdif_size); + wcmdif_size = cmdif_size; + rcmdif_size = cmdif_size; + + // Improve the performance by not writing data in read to icmd buffer or not reading in write command + + if (reg_id == REG_ID_MFBA) { + if (method == MAD_METHOD_QUERY) { + wcmdif_size = cmdif_size - CMDIF_MAX_BLOCK_WRITE; + } else { + rcmdif_size = cmdif_size - CMDIF_MAX_BLOCK_WRITE; + } + } + + mad_rc = maccess_reg_mad_wrapper(faccess, buffer, wcmdif_size, rcmdif_size); + // Unpack the mad + OperationTlv_unpack(&tlv, buffer); + reg_tlv_unpack(&tlv_info, buffer + OP_TLV_SIZE); + reg_info.unpack_func(reg, buffer + OP_TLV_SIZE + REG_RLV_HEADER_LEN); + + +#ifdef _ENABLE_MFLASH_INBAND_DEBUG + if (debug) { + printf("-I- The received MAD content\n"); + OperationTlv_dump(&tlv, stdout); + reg_tlv_dump(&tlv_info, stdout); + reg_info.dump_func(reg, stdout); + } +#endif + // Check the return value from + CHECK_RC(mad_rc); + if (tlv.status) { + + // printf("-E- Access reg mad failed with tlv status = %#x\n", tlv.status); + switch (tlv.status) { + case 0x4: + return MFE_REG_ACCESS_MAD_NOT_SUPPORTED; + case 0x8: + return MFE_REG_ACCESS_RESOURCE_NOT_AVAILABLE; + default: + // printf("-D- status = %d\n", tlv.status); + return MFE_REG_ACCESS_MAD_BAD_STATUS; + } + } + return MFE_OK; +} + +int mfi_erase_sector(mfile *mf, u_int32_t addr, u_int8_t flash_bank) +{ + flash_access_t faccess; + faccess.mf = mf; + faccess.access_type = FWACCESS_INBAND; + return common_erase_sector(&faccess, addr, flash_bank); +} + + +int mfi_get_jedec(mfile *mf, u_int8_t flash_bank, u_int32_t *jedec_p) +{ + flash_access_t faccess; + faccess.mf = mf; + faccess.access_type = FWACCESS_INBAND; + return com_get_jedec(&faccess, flash_bank, jedec_p); +} + +int mfi_read_block(mfile *mf, u_int32_t addr, u_int8_t flash_bank, u_int32_t size, u_int8_t* data) +{ + flash_access_t faccess; + faccess.mf = mf; + faccess.access_type = FWACCESS_INBAND; + // printf("-D- mfi_read_block: addr = %#x, size = %d\n", addr, size); + return sx_st_block_access(&faccess, addr, flash_bank, size, data, MAD_METHOD_QUERY); +} + +int mfi_write_block(mfile *mf, u_int32_t addr, u_int8_t flash_bank, u_int32_t size, u_int8_t* data) +{ + flash_access_t faccess; + faccess.mf = mf; + faccess.access_type = FWACCESS_INBAND; + return sx_st_block_access(&faccess, addr, flash_bank, size, data, MAD_METHOD_WRITE); +} + +int mfi_flash_lock(mfile *mf, int lock_state) +{ + mf = NULL; + lock_state = 0; + return MFE_OK; +} + +int mfi_update_boot_addr(mfile *mf, u_int8_t flash_bank, u_int32_t boot_addr) +{ + mf = NULL; + flash_bank = 0; + boot_addr = 0; + return MFE_NOT_IMPLEMENTED; +} diff --git a/mflash/mflash_inband.h b/mflash/mflash_inband.h new file mode 100755 index 0000000..acbaf4a --- /dev/null +++ b/mflash/mflash_inband.h @@ -0,0 +1,42 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +/* + * mflash_inband.h + * + * Created on: Jul 6, 2011 + * Author: mohammad + */ + +#ifndef MFLASH_INBAND_H_ +#define MFLASH_INBAND_H_ + +#include +#include "mflash_common.h" + +int mfi_reg_access_mad(flash_access_t *faccess, u_int16_t reg_id, u_int8_t method, void *reg, u_int8_t debug); + +int mfi_erase_sector(mfile *mf, u_int32_t addr, u_int8_t flash_bank); + +int mfi_get_jedec(mfile *mf, u_int8_t flash_bank, u_int32_t *jedec_p); + +int mfi_read_block(mfile *mf, u_int32_t addr, u_int8_t flash_bank, u_int32_t size, u_int8_t* data); + +int mfi_write_block(mfile *mf, u_int32_t blk_addr, u_int8_t flash_bank, u_int32_t size, u_int8_t* data); + +int mfi_flash_lock(mfile *mf, int lock_state); + +int mfi_update_boot_addr(mfile *mf, u_int8_t flash_bank, u_int32_t boot_addr); + +#endif /* MFLASH_INBAND_H_ */ diff --git a/mflash/packets_common.c b/mflash/packets_common.c new file mode 100755 index 0000000..78430da --- /dev/null +++ b/mflash/packets_common.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2004-2010 Mellanox Technologies LTD. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#include "packets_common.h" +#include +#include +#include +#include +#ifdef __WIN__ + #include // for htonl +#endif + + +/************************************/ +void push_to_buff_64(u_int8_t *buff, u_int32_t bit_offset, u_int64_t field_value) +{ +#if defined(__ia64__) + u_int32_t *buffer = PTR_32_OF_BUFF(buff, (bit_offset / 8)); + u_int64_t value = CPU_TO_BE64(field_value); + memcpy(buffer, &value, sizeof(value)); +#else + u_int64_t *buffer = PTR_64_OF_BUFF(buff, (bit_offset / 8)); + memcpy(buffer, &field_value, sizeof(field_value)); + *buffer = CPU_TO_BE64(*buffer); +#endif +} + + +/************************************/ +void push_to_buff_32(u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_value) +{ + u_int32_t *buffer = PTR_32_OF_BUFF(buff, (bit_offset / 8)); + memcpy(buffer, &field_value, sizeof(field_value)); + *buffer = CPU_TO_BE32(*buffer); +} + + +/************************************/ +//the next function will push the field into the buffer by inserting it's MSB bits first +//and therefore by doing it we save the CPU_TO_BE operation +void push_to_buff(u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_size, u_int32_t field_value) +{ + u_int32_t i = 0; + u_int32_t byte_n = bit_offset / 8; + u_int32_t byte_n_offset = bit_offset % 8; + u_int32_t to_push; + + //going over all bits in field + while (i < field_size) { + to_push = PCK_MIN(8 - byte_n_offset, field_size - i); + i += to_push; + //printf("Inserting %u bits(%u) to byte %u to bit %u\n", to_push, EXTRACT8(field_value, field_size - i, to_push), byte_n, 8 - to_push - byte_n_offset); + INSERTF_8(BYTE_N(buff, byte_n), 8 - to_push - byte_n_offset, field_value, field_size - i, to_push); + byte_n_offset = 0; //(byte_n_offset + to_push) % 8; + byte_n++; + } +} + + +/************************************/ +u_int64_t pop_from_buff_64(u_int8_t *buff, u_int32_t bit_offset) +{ +#if defined(__ia64__) + u_int64_t value = 0; + memcpy(&value, PTR_32_OF_BUFF(buff, (bit_offset / 8)), sizeof(u_int64_t)); + return (BE64_TO_CPU(value)); +#else + return (BE64_TO_CPU(FIELD_64_OF_BUFF(buff, (bit_offset / 8)))); +#endif +} + + +/************************************/ +u_int32_t pop_from_buff_32(u_int8_t *buff, u_int32_t bit_offset) +{ + return (BE32_TO_CPU(FIELD_32_OF_BUFF(buff, (bit_offset / 8)))); +} + + +/************************************/ +//the next function will pop the field into the buffer by removing it's MSB bits first +//and therefore by doing it we save the BE_TO_CPU operation +u_int32_t pop_from_buff(u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_size) +{ + u_int32_t i = 0; + u_int32_t byte_n = bit_offset / 8; + u_int32_t byte_n_offset = bit_offset % 8; + u_int32_t field_32 = 0; + u_int32_t to_pop; + + //going over all bits in field + while (i < field_size) { + to_pop = PCK_MIN(8 - byte_n_offset, field_size - i); + i += to_pop; + //printf("Removing %u bits(%u) from byte %u to bit %u\n", to_pop, EXTRACT8(BYTE_N(buff, byte_n), 8 - to_pop - byte_n_offset, to_pop), byte_n, field_size - i); + INSERTF_8(field_32, field_size - i, BYTE_N(buff, byte_n), 8 - to_pop - byte_n_offset, to_pop); + byte_n_offset = 0; //(byte_n_offset + to_pop) % 8; + byte_n++; + } + return field_32; +} + + diff --git a/mflash/packets_common.h b/mflash/packets_common.h new file mode 100755 index 0000000..d485a36 --- /dev/null +++ b/mflash/packets_common.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2004-2010 Mellanox Technologies LTD. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#ifndef packet_common_H +#define packet_common_H + +#include +#include +#include + +#ifndef __WIN__ + #include +/************************************/ +/* Endianess Defines */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + #ifndef PLATFORM_MEM + // #define PLATFORM_MEM "Little Endianess" + #endif + #define _LITTLE_ENDIANESS +#endif + +#if __BYTE_ORDER == __BIG_ENDIAN + //#define PLATFORM_MEM "Big Endianess" + #define _BIG_ENDIANESS +#endif + +#else + #define __BYTE_ORDER __LITTLE_ENDIAN + #ifndef PLATFORM_MEM + //#define PLATFORM_MEM "Big Endianess" + #endif + #define _BIG_ENDIANESS + typedef unsigned __int8 u_int8_t; + typedef __int8 int8_t; + typedef unsigned __int16 u_int16_t; + typedef __int16 int16_t; + typedef unsigned __int32 u_int32_t; + typedef __int32 int32_t; + typedef unsigned __int64 u_int64_t; + typedef __int64 int64_t; +#endif + + + +/************************************/ +/* Bit manipulation macros */ + +/* MASK generate a bit mask S bits width */ +//#define MASK32(S) ( ((u_int32_t) ~0L) >> (32-(S)) ) +#define MASK8(S) ( ((u_int8_t) ~0) >> (8-(S)) ) + +/* BITS generate a bit mask with bits O+S..O set (assumes 32 / 8 bit integer) */ +//#define BITS32(O,S) ( MASK32(S) << (O) ) +#define BITS8(O,S) ( MASK8(S) << (O) ) + +/* EXTRACT32/8 macro extracts S bits from (u_int32_t/u_int8_t)W with offset O + * and shifts them O places to the right (right justifies the field extracted) */ +//#define EXTRACT32(W,O,S) ( ((W)>>(O)) & MASK32(S) ) +#define EXTRACT8(W,O,S) ( ((W)>>(O)) & MASK8(S) ) + +#define PCK_MIN(a, b) ((a) < (b) ? (a) : (b)) +/* INSERT32/8 macro inserts S bits with offset O from field F into word W (u_int32_t/u_int8_t) */ +//#define INSERT32(W,F,O,S) ((W)= ( ( (W) & (~BITS32(O,S)) ) | (((F) & MASK32(S))<<(O)) )) +#define INSERT8(W,F,O,S) ((W)= ( ( (W) & (~BITS8(O,S)) ) | (((F) & MASK8(S))<<(O)) )) + +//#define INSERTF_32(W,O1,F,O2,S) (INSERT32(W, EXTRACT32(F, O2, S), O1, S) ) +#define INSERTF_8(W,O1,F,O2,S) (INSERT8(W, EXTRACT8(F, O2, S), O1, S) ) + + +/************************************/ +#define PTR_64_OF_BUFF(buf, offset) ((u_int64_t*)((u_int8_t*)(buf) + (offset))) +#define PTR_32_OF_BUFF(buf, offset) ((u_int32_t*)((u_int8_t*)(buf) + (offset))) +#define PTR_8_OF_BUFF(buf, offset) ((u_int8_t*)((u_int8_t*)(buf) + (offset))) +#define FIELD_64_OF_BUFF(buf, offset) (*PTR_64_OF_BUFF(buf, offset)) +#define FIELD_32_OF_BUFF(buf, offset) (*PTR_32_OF_BUFF(buf, offset)) +#define FIELD_8_OF_BUFF(buf, offset) (*PTR_8_OF_BUFF(buf, offset)) +#define DWORD_N(buf, n) FIELD_32_OF_BUFF((buf), (n) * 4) +#define BYTE_N(buf, n) FIELD_8_OF_BUFF((buf), (n)) + + +/************************************/ +// #define MIN(a, b) ((a) < (b) ? (a) : (b)) + + +/************************************/ +#define CPU_TO_BE32(x) htonl(x) +#define BE32_TO_CPU(x) ntohl(x) +#define CPU_TO_BE16(x) htons(x) +#define BE16_TO_CPU(x) ntohs(x) +#ifdef _LITTLE_ENDIANESS + #define CPU_TO_BE64(x) (((u_int64_t)htonl((u_int32_t)((x) & 0xffffffff)) << 32) | \ + ((u_int64_t)htonl((u_int32_t)((x >> 32) & 0xffffffff)))) + + #define BE64_TO_CPU(x) (((u_int64_t)ntohl((u_int32_t)((x) & 0xffffffff)) << 32) | \ + ((u_int64_t)ntohl((u_int32_t)((x >> 32) & 0xffffffff)))) +#else + #define CPU_TO_BE64(x) (x) + #define BE64_TO_CPU(x) (x) +#endif + + +/************************************/ +/* define macros to the architecture of the CPU */ +#if defined(__linux) || defined(__FreeBSD__) +# if defined(__i386__) +# define ARCH_x86 +# elif defined(__x86_64__) +# define ARCH_x86_64 +# elif defined(__ia64__) +# define ARCH_ia64 +# elif defined(__PPC64__) +# define ARCH_ppc64 +# elif defined(__PPC__) +# define ARCH_ppc +# else +# error Unknown CPU architecture using the linux OS +# endif +#elif defined(_WIN32) + +//# error Windows OS need to define macros +#else /* __linux || __FreeBSD__ */ +# error Unknown OS +#endif /* __linux || __FreeBSD__ */ + + +/**********************************/ +/* define macros for print fields */ +//#if defined (ARCH_ia64) || defined(ARCH_x86_64) || defined(ARCH_ppc64) || defined(__MINGW64__) + +#if !defined(UEFI_BUILD) && (defined (ARCH_ia64) || defined(ARCH_x86_64) || defined(ARCH_ppc64) || defined(__MINGW64__)) +# define U64H_FMT "0x%016lx" +# define U64D_FMT "%lu" +# define U32H_FMT "0x%08x" +# define U16H_FMT "0x%04x" +# define U8H_FMT "0x%02x" +# define U32D_FMT "%u" +# define STR_FMT "%s" +#elif defined(ARCH_x86) || defined(ARCH_ppc) || defined(__MINGW32__) || defined(UEFI_BUILD) +# define U64H_FMT "0x%016llx" +# define U64D_FMT "%llu" +# define U32H_FMT "0x%08x" +# define U16H_FMT "0x%04x" +# define U8H_FMT "0x%02x" +# define U32D_FMT "%u" +# define STR_FMT "%s" +#else /* ARCH */ +# error Unknown architecture +#endif /* ARCH */ + + +/**********************************/ +void push_to_buff_64(u_int8_t *buff, u_int32_t bit_offset, u_int64_t field_value); +void push_to_buff_32(u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_value); +void push_to_buff(u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_size, u_int32_t field_value); +u_int64_t pop_from_buff_64(u_int8_t *buff, u_int32_t bit_offset); +u_int32_t pop_from_buff_32(u_int8_t *buff, u_int32_t bit_offset); +u_int32_t pop_from_buff(u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_size); + + +#endif /* def packet_common_H */ + + diff --git a/mlxfwops/Makefile.am b/mlxfwops/Makefile.am new file mode 100755 index 0000000..a0f9ef0 --- /dev/null +++ b/mlxfwops/Makefile.am @@ -0,0 +1,36 @@ +#-- +# Copyright (c) 2004-2010 Mellanox Technologies LTD. All rights reserved. +# +# This software is available to you under a choice of one of two +# licenses. You may choose to be licensed under the terms of the GNU +# General Public License (GPL) Version 2, available from the file +# COPYING in the main directory of this source tree, or the +# OpenIB.org BSD license below: +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the following +# conditions are met: +# +# - Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# - Redistributions 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. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +#-- + +# Makefile.am -- Process this file with automake to produce Makefile.in + +SUBDIRS = lib + diff --git a/mlxfwops/lib/Makefile.am b/mlxfwops/lib/Makefile.am new file mode 100755 index 0000000..2399723 --- /dev/null +++ b/mlxfwops/lib/Makefile.am @@ -0,0 +1,62 @@ +#-- +# Copyright (c) 2004-2010 Mellanox Technologies LTD. All rights reserved. +# +# This software is available to you under a choice of one of two +# licenses. You may choose to be licensed under the terms of the GNU +# General Public License (GPL) Version 2, available from the file +# COPYING in the main directory of this source tree, or the +# OpenIB.org BSD license below: +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the following +# conditions are met: +# +# - Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# - Redistributions 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. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +#-- + +# Makefile.am -- Process this file with automake to produce Makefile.in +USER_DIR = ../.. +MTCR_DIR = $(USER_DIR)/mtcr_ul +MFLASH_DIR = $(USER_DIR)/mflash +MINIXZ_DIR = $(USER_DIR)/ext_libs/minixz +LIBMFA_DIR = $(USER_DIR)/libmfa +COMMON_DIR = $(USER_DIR)/common +LAYOUTS_DIR = $(USER_DIR)/tools_layouts + + +INCLUDES = -I. -I.. -I$(MTCR_DIR) -I$(MFLASH_DIR) -I$(LIBMFA_DIR) -I$(USER_DIR)/ext_libs/json -I$(MINIXZ_DIR)\ + -I$(COMMON_DIR) -I$(MFT_EXT_LIBS_INC_DIR)/zlib -I $(LAYOUTS_DIR) -I$(top_srcdir)/common + + +MLXFWOPS_VERSION = 1 + +AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe -DNO_MFA_SUPPORT + +lib_LTLIBRARIES = libmlxfwops.la + +libmlxfwops_la_SOURCES = flint_base.cpp \ + flint_io.cpp \ + fw_ops.cpp \ + fs2_ops.cpp fs2_ops.h\ + fs3_ops.cpp fs3_ops.h\ + mlxfwops.cpp mlxfwops.h + +mlxfwopsincludedir=$(includedir)/mft/mlxfwops +mlxfwopsinclude_HEADERS = mlxfwops_com.h mlxfwops.h fw_ops.h flint_base.h flint_io.h + diff --git a/mlxfwops/lib/flint_base.cpp b/mlxfwops/lib/flint_base.cpp new file mode 100755 index 0000000..7a07726 --- /dev/null +++ b/mlxfwops/lib/flint_base.cpp @@ -0,0 +1,281 @@ +/* + * + * flint_base.cpp - FLash INTerface + * + * Copyright (c) 2011 Mellanox Technologies Ltd. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Version: $Id: flint_base.cpp 7522 2011-11-16 15:37:21Z mohammad $ + * + */ + + +#include "flint_base.h" + + +void ErrMsg::err_clear(){ + delete [] _err; + _err = 0; +} + + +bool _print_crc = false; +bool _silent = false; +bool _assume_yes = false; +bool _assume_no = false; + +bool _no_erase = false; +bool _no_burn = false; + +bool _unlock_bypass = false; +bool _byte_write = false; + +const char* g_sectNames[] = { + "UNKNOWN (0 - Reserved)", + "DDR" , + "Configuration" , + "Jump addresses" , + "EMT Service" , + "ROM" , + "GUID" , + "BOARD ID" , + "User Data" , + "FW Configuration", + "Image Info" , + "DDRZ" , + "Hash File" +}; + +void report(const char *format, ...) +#ifdef __GNUC__ +__attribute__ ((format (printf, 1, 2))) +#endif +; +void report(const char *format, ...) +{ + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); +} // report + +#define MAX_STRING_LEN 512 +void report_callback(f_prog_func_str func_str, const char *format, ...) +{ + va_list args; + char buff[MAX_STRING_LEN]; + + va_start(args, format); + vsnprintf(buff, MAX_STRING_LEN, format, args); + va_end(args); + // printf("%s\n", buff); + if (func_str != NULL) { + func_str(buff); + } + +} // report + + +/* +void report_erase(const char *format, ...) +{ + va_list args; + char buf[256]; + int i; + int len; + + if (_silent) + return; + + va_start(args, format); + vsnprintf(buf, sizeof buf, format, args); + va_end(args); + + len = strlen(buf); + for (i=0; i < len; ++i) + printf("\b"); +} // report_erase +*/ +void report_repair_msg(const char* common_msg) +{ + printf("\r%s OK ", common_msg); +} + +#define MAX_ERR_STR_LEN 1024 +#define PRE_ERR_MSG "-E-" +void report_err(char err_buff[MAX_ERR_STR_LEN], const char *format, ...) +{ + va_list args; + + va_start(args, format); + + if (vsnprintf(err_buff, MAX_ERR_STR_LEN, format, args) >= MAX_ERR_STR_LEN) { + strcpy(&err_buff[MAX_ERR_STR_LEN - 5], "...\n"); + } + fprintf(stderr, PRE_ERR_MSG" %s", err_buff); + + va_end(args); + + return; +} + +void report_warn(const char *format, ...) +{ +#ifndef UEFI_BUILD + va_list args; + va_start(args, format); + printf("\n-W- "); + vfprintf(stdout, format, args); + printf(" %s", "\n"); + va_end(args); +#endif +} + + + + +const CommandInfo* GetCommandInfo(CommandType cmd) { + for (u_int32_t i = 0 ; i < numbel(g_commands); i++ ) { + if (cmd == g_commands[i].cmd) { + return &g_commands[i]; + } + } + + return (CommandInfo*)NULL; +} + + +bool ErrMsg::errmsg(const char *format, ...) { + va_list args; + + char* prev_err = _err; + + va_start(args, format); + _err = vprint(format, args); + va_end(args); + + delete[] prev_err; + + return false; +} + + +//////////////////////////////////////////////////////////////////////// +void Crc16::add(u_int32_t o) +{ + if (_debug) + printf("Crc16::add(%08x)\n", o); + for (int i=0; i<32; i++) { + if (_crc & 0x8000) + _crc = (u_int16_t) ((((_crc<<1) | (o>>31)) ^ 0x100b) & 0xffff); + else + _crc= (u_int16_t) (((_crc<<1) | (o>>31)) & 0xffff); + o = (o<<1) & 0xffffffff; + } +} // Crc16::add + + +//////////////////////////////////////////////////////////////////////// +void Crc16::finish() +{ + for (int i=0; i<16; i++) { + if (_crc & 0x8000) + _crc=((_crc<<1) ^ 0x100b) & 0xffff; + else + _crc=(_crc<<1) & 0xffff; + } + + // Revert 16 low bits + _crc = _crc ^ 0xffff; + +} // Crc16::finish + + +#ifdef UEFI_BUILD + +void *operator new(size_t size) +{ + void *p; + p = malloc(size); + return p; +} + +void *operator new[](size_t size) +{ + void *p; + p = malloc(size); + return p; +} + +// delete operator overloaded +void operator delete(void *p) +{ + free(p); +} + +void operator delete[] (void* p) +{ + free(p); +} + + +namespace std { + void __throw_bad_alloc(void) { + // TODO: Check what happens when there is no mem or replace this exit with goto + goto hell; + hell: + goto hell; + } + + void __throw_length_error(const char*) { + // TODO: Check what happens when there is no mem or replace this exit with goto + goto hell; + hell: + goto hell; + } + + void __throw_out_of_range(const char*) { + // TODO: Check what happens when there is no mem or replace this exit with goto + goto hell; + hell: + goto hell; + } +} + +int goto_function() +{ + goto hell; +hell: + return 0; +} +extern "C" void __cxa_pure_virtual(void) {}; + +#endif + diff --git a/mlxfwops/lib/flint_base.h b/mlxfwops/lib/flint_base.h new file mode 100755 index 0000000..b4abed1 --- /dev/null +++ b/mlxfwops/lib/flint_base.h @@ -0,0 +1,685 @@ +/* + * + * flint_base.h - FLash INTerface + * + * Copyright (c) 2011 Mellanox Technologies Ltd. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Version: $Id: flint_base.h 7522 2011-11-16 15:37:21Z mohammad $ + * + */ +#ifndef FLINT_BASE_H +#define FLINT_BASE_H + +#ifndef UEFI_BUILD + #ifndef __FreeBSD__ + #include + #endif +#else + #include "uefi_c.h" + // #include "uefi_c.cpp" +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include "tools_version.h" + +#include + +#ifndef __WIN__ + +// +// GCC Compiler +// + + + #if defined __DJGPP__ +// +// DJGPP - GCC PORT TO MS DOS +// + + #include // This contains the u_* types definitions + + #include + #include + + #define bswap_32(x) ntohl(x) + +// djgpp stdio does not define vsnprintf. I simply call vsprintf (and pray ...) + #define vsnprintf(buf, len, format, args) (vsprintf(buf, format, args)) + #define snprintf(buf, len, format, args...) (sprintf(buf, format, args)) + #else // Linux GCC +#ifndef UEFI_BUILD + #include +#endif + #ifdef __FreeBSD__ + #define SWAPL(l) ntohl(l) + #include + #define bswap_32(x) ntohl(x) + #else // Linux + #include + #include + #endif + #include + #include + + #endif // __DJGPP__ + +#else // __WIN__ + +// +// Windows (Under DDK) +// + + #include + #include + #include +// Sleep adaptor + #define usleep(x) Sleep((x)/1000) + #define sleep(x) Sleep((x)*1000) + + #define vsnprintf _vsnprintf + #define isatty _isatty + + #define COMP_CDECL __cdecl + + #define __LITTLE_ENDIAN 1234 + #define __BIG_ENDIAN 4321 + #define __BYTE_ORDER __LITTLE_ENDIAN + + + + #if __BYTE_ORDER == __LITTLE_ENDIAN + #define bswap_32(x) ntohl(x) + #else + #error windows is assumed to run a on little endian architecture + #endif + + // MINGW + #if defined(__MINGW32__) || (__MINGW64__) + #define strtoull strtoull + #define _UNISTD_H // Zlib includes unistd.h which causes some compilation errors. + + #else + #define strtoull _strtoui64 + #endif +#endif // __WIN__ + +#ifndef NO_ZLIB + #include +#endif + + +#include +#include +#include "compatibility.h" +#include "mlxfwops_com.h" + +#ifndef __be32_to_cpu + #define __be32_to_cpu(x) ntohl(x) + #ifndef bswap_32 + #define bswap_32(x) (htonl(x)) + #endif +#endif +#ifndef __cpu_to_be32 + #define __cpu_to_be32(x) htonl(x) +#endif + +#if __BYTE_ORDER == __LITTLE_ENDIAN + #ifndef __cpu_to_le32 + #define __cpu_to_le32(x) (x) + #endif + #ifndef __le32_to_cpu + #define __le32_to_cpu(x) (x) + #endif +#elif __BYTE_ORDER == __BIG_ENDIAN + #ifndef __cpu_to_le32 + #define __cpu_to_le32(x) bswap_32(x) + #endif + #ifndef __le32_to_cpu + #define __le32_to_cpu(x) bswap_32(x) + #endif +#else + #ifndef __cpu_to_le32 + #define __cpu_to_le32(x) bswap_32(__cpu_to_be32(x)) + #endif + #ifndef __le32_to_cpu + #define __le32_to_cpu(x) __be32_to_cpu(bswap_32(x)) + #endif +#endif + + +static inline void be_guid_to_cpu(guid_t* to, guid_t* from) { + to->h=__be32_to_cpu(from->h); + to->l=__be32_to_cpu(from->l); +} +namespace std {}; using namespace std; + + +#define TOCPU1(s) s = __be32_to_cpu((u_int32_t)(s)); +#define CPUTO1(s) s = __cpu_to_be32((u_int32_t)(s)); +#define TOCPU(s) do { \ + u_int32_t *p = (u_int32_t *)(s); \ + for (u_int32_t ii=0; ii> _sptr1);} + + u_int32_ba range (u_int8_t eptr, + u_int8_t sptr) {return u_int32_ba(*this,eptr,sptr);} + +private: + u_int32_ba(u_int32_ba& other, u_int8_t eptr, u_int8_t sptr) : + _bits(other._bits), + _rbits(other._bits), + _sptr1(sptr), + _eptr(eptr) {} + + u_int32_t mask () { + u_int32_t s_msk = (u_int32_t)-1; // start mask + u_int32_t e_msk = (u_int32_t)-1; // end mask + + s_msk = (s_msk << _sptr1); + e_msk = (_eptr >= (sizeof(_bits)*8-1)) ? e_msk : ~(e_msk << (_eptr+1)); + + return(s_msk & e_msk); + }; + + u_int32_t _bits; + u_int32_t& _rbits; + + u_int8_t _sptr1; + u_int8_t _eptr; +}; + +////////////////////////////////////////////////////////////////////// +// +// class Aligner: +// A utillity class for accessing an addr/size region +// in a specific alignment. +// If a 0 alignment is given, infinity (no alignment requirements) +// is assumed - This is to support single flow for the caller. +// +////////////////////////////////////////////////////////////////////// + +class Aligner { +public: + Aligner(u_int32_t log2_alignment_size) : + _log2_alignment_size(log2_alignment_size), + _alignment_size(1 << log2_alignment_size), + _alignment_mask(_alignment_size - 1) + { + if (_log2_alignment_size == 0) { + _log2_alignment_size = 31; + _alignment_size = 1 << _log2_alignment_size; + _alignment_mask = _alignment_size - 1; + } + } + + void Init (u_int32_t addr, u_int32_t size) { + _curr_addr = addr; + _curr_size = size; + } + + bool GetNextChunk(u_int32_t& chunk_addr, u_int32_t& chunk_size) { + if (_curr_size == 0) { + return false; + } + + chunk_addr = _curr_addr; + + if ( (_curr_addr >> _log2_alignment_size) != + ((_curr_addr + _curr_size) >> _log2_alignment_size)) { + // Next chunk crosses alignment boundary + chunk_size = _alignment_size - (_curr_addr & _alignment_mask); + } else { + chunk_size = _curr_size; + } + + _curr_addr += chunk_size; + _curr_size -= chunk_size; + + return true; + } + +private: + u_int32_t _curr_addr; + u_int32_t _curr_size; + u_int32_t _log2_alignment_size; + u_int32_t _alignment_size; + u_int32_t _alignment_mask; +}; + +#endif + diff --git a/mlxfwops/lib/flint_io.cpp b/mlxfwops/lib/flint_io.cpp new file mode 100755 index 0000000..a266245 --- /dev/null +++ b/mlxfwops/lib/flint_io.cpp @@ -0,0 +1,796 @@ +/* + * + * flint_io.cpp - FLash INTerface + * + * Copyright (c) 2011 Mellanox Technologies Ltd. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Version: $Id: flint_io.cpp 7522 2011-11-16 15:37:21Z mohammad $ + * + */ + + +#include "flint_io.h" + + +extern bool _no_erase; +extern bool _no_burn; + +extern const char* g_sectNames[]; + +//////////////////////////////////////////////////////////////////////// +// +// FImage Class Implementation +// +//////////////////////////////////////////////////////////////////////// + +bool FImage::open(const char *fname, bool read_only) +{ + +#ifndef UEFI_BUILD +//#ifndef 1 + int fsize; + int r_cnt; + FILE *fh; + + read_only = true; // FImage can be opened only for read + fh = fopen(fname, "rb"); + + if (!fh) { + return errmsg("Can not open file \"%s\" - %s", fname, strerror(errno)); + } + + // Get the file size: + if (fseek(fh, 0, SEEK_END) < 0) { + fclose(fh); + return errmsg("Can not get file size for \"%s\" - %s", fname, strerror(errno)); + } + + fsize = ftell(fh); + if (fsize < 0) { + fclose(fh); + return errmsg("Can not get file size for \"%s\" - %s", fname, strerror(errno)); + } + rewind(fh); + + //printf("-D- %s size is %d\n", fname, fsize); + if (fsize & 0x3) { + fclose(fh); + return errmsg("Image size should be 4-bytes aligned. Make sure file %s is in the right format (binary image)", + fname); + } + + _buf = new u_int32_t[fsize/4]; + if ((r_cnt = fread(_buf, 1, fsize, fh)) != fsize) { + fclose(fh); + if (r_cnt < 0) { + return errmsg("Read error on file \"%s\" - %s",fname, strerror(errno)); + } else { + return errmsg("Read error on file \"%s\" - read only %d bytes (from %ld)", + fname, r_cnt, (unsigned long)fsize); + } + } + + _len = fsize; + fclose(fh); + return true; +#else + return false; +#endif +} // FImage::open + +bool FImage::open(u_int32_t *buf, u_int32_t len) +{ + _buf = new u_int32_t[len / 4]; + memcpy(_buf, buf, len); + _len = len; + return true; +} +//////////////////////////////////////////////////////////////////////// +void FImage::close() +{ + delete [] _buf; + _buf = 0; +} // FImage::close + +//////////////////////////////////////////////////////////////////////// +bool FImage::read(u_int32_t addr, u_int32_t *data) +{ + return read(addr, data, 4); +} // FImage::read + +//////////////////////////////////////////////////////////////////////// +bool FImage::read(u_int32_t addr, void *data, int len, bool, const char*) +{ + + if (addr & 0x3) { + return errmsg("Address should be 4-bytes aligned."); + } + if (len & 0x3) { + return errmsg("Length should be 4-bytes aligned."); + } + if (!_buf) { + return errmsg("read() when not opened"); + } + + if (cont2phys(addr + len) > _len) { + return errmsg("Reading 0x%x bytes from %s address 0x%x is out of image limits (0x%x bytes)", + len, + _log2_chunk_size ? "physical " : "", + addr, + _len); + } + + u_int32_t chunk_addr; + u_int32_t chunk_size; + Aligner align(_log2_chunk_size); + align.Init (addr, len); + while (align.GetNextChunk(chunk_addr, chunk_size)) { + u_int32_t phys_addr = cont2phys(chunk_addr); + + memcpy((u_int8_t*)data + (chunk_addr - addr), + (u_int8_t*)_buf + phys_addr, + chunk_size); + } + + return true; +} // FImage::read + +//////////////////////////////////////////////////////////////////////// +u_int32_t FImage::get_sector_size() +{ + u_int32_t log2_sector_sz_ptr; + u_int32_t log2_sector_sz; + u_int32_t signature; + + read(0x24, &signature); + TOCPU1(signature); + if (signature == SIGNATURE) { + // full image: + read(0x14, &log2_sector_sz_ptr); + TOCPU1(log2_sector_sz_ptr); + log2_sector_sz_ptr &= 0xffff; + + read(0x30 + log2_sector_sz_ptr, &log2_sector_sz); + TOCPU1(log2_sector_sz); + log2_sector_sz &= 0xffff; + + return(1 << log2_sector_sz); + + } else { + return 0; + } +} + + + +//////////////////////////////////////////////////////////////////////// +// +// Flash Class Implementation +// +//////////////////////////////////////////////////////////////////////// + + +bool Flash::_byte_mode = false; +bool Flash::_no_flash_verify = false; + +//////////////////////////////////////////////////////////////////////// +bool Flash::open_com_checks(const char *device, int rc, bool force_lock) +{ + if ((rc == MFE_SEM_LOCKED) && force_lock) { + report("Warning: Taking flash lock even though semaphore is set.\n"); + rc = mf_open_ignore_lock(_mfl); + } + + if (rc != MFE_OK) { + if (rc == MFE_SEM_LOCKED) { + return errmsg("Can not obtain Flash semaphore (63). You can run \"flint -clear_semaphore -d \" to force semaphore unlock. See help for details."); + } + if (rc == MFE_LOCKED_CRSPACE) { + _cr_space_locked = 1; + return errmsg("HW access is disabled on the device.\n-E- Run \"flint -d %s hw_access enable\" in order to enable HW access.", device); + } + if (rc == MFE_REG_ACCESS_MAD_NOT_SUPPORTED) { + return errmsg("The target device FW does not support flash access commands.\n-E- Please use the -override_cache_replacement option in order to access the flash directly."); + } + if (rc == MFE_DIRECT_FW_ACCESS_DISABLED) { + return errmsg(" Flash cache replacement is active.\n-E- Please use the -override_cache_replacement option in order to access the flash directly."); + } + + return errmsg("%s %s", errno == 0 ? "" : strerror(errno), mf_err2str(rc)); + } + + rc = mf_get_attr(_mfl, &_attr); + if (rc != MFE_OK) { + return errmsg("Failed getting flash attributes for device %s: %s", device, mf_err2str(rc)); + } + + if (_attr.hw_dev_id == 435 || _attr.hw_dev_id == SWITCHX_HW_ID) { + _port_num = 0; + } else if (_attr.hw_dev_id == 25204 || _attr.hw_dev_id == 24204) { + _port_num = 1; + } else { + _port_num = 2; + } + + if (_byte_mode) { + rc = mf_set_opt(_mfl, MFO_AMD_BYTE_MODE, 1); + if (rc != MFE_OK) { + return errmsg("Failed setting byte mode for device %s: %s", device, mf_err2str(rc)); + } + } + if (_no_flash_verify) { + rc = mf_set_opt(_mfl, MFO_NO_VERIFY, 1); + } + + return true; +} // Flash::open + + +//////////////////////////////////////////////////////////////////////// +bool Flash::open(const char *device, bool force_lock, bool read_only, int num_of_banks, flash_params_t *flash_params, + int ignore_cashe_replacement) +{ + // Open device + int rc; + read_only = false; + rc = mf_open(&_mfl, device, num_of_banks, flash_params, ignore_cashe_replacement); + //printf("device: %s , forceLock: %s , read only: %s, num of banks: %d, flash params is null: %s, ocr: %d, rc: %d\n", + // device, force_lock? "true":"false", read_only?"true":"false", num_of_banks, flash_params? "no":"yes", ignore_cashe_replacement, rc); + return open_com_checks(device, rc, force_lock); +} + +//////////////////////////////////////////////////////////////////////// +bool Flash::open(uefi_Dev_t *uefi_dev, f_fw_cmd fw_cmd_func, bool force_lock) +{ + int rc; + rc = mf_open_uefi(&_mfl, uefi_dev, fw_cmd_func); + return open_com_checks("uefi", rc, force_lock); +} + + +//////////////////////////////////////////////////////////////////////// +void Flash::close() +{ + if (!_mfl) + return; + + mf_close(_mfl); + _mfl = 0; +} // Flash::close + +bool Flash::read(u_int32_t addr, + u_int32_t *data) { + int rc; + + u_int32_t phys_addr = cont2phys(addr); + // printf("-D- read1: addr = %#x, phys_addr = %#x\n", addr, phys_addr); + // here we set a "silent" signal handler and deal with the recieved signal after the read + //mft_signal_set_handling(1); + rc = mf_read(_mfl, phys_addr, 4, (u_int8_t*)data); + deal_with_signal(); + if (rc != MFE_OK) { + return errmsg("Flash read failed at address %s0x%x : %s", + _log2_chunk_size ? "physical " : "", + addr, + mf_err2str(rc)); + } + + return true; +} + +//////////////////////////////////////////////////////////////////////// +bool Flash::read(u_int32_t addr, void *data, int len, bool verbose, const char* message) +{ + int rc; + u_int32_t perc = 0xffffffff; + + if (addr & 0x3) { + return errmsg("Address should be 4-bytes aligned."); + } + if (len & 0x3) { + return errmsg("Length should be 4-bytes aligned."); + } + + // Much better perf for read in a single chunk. need to work on progress report though. + bool read_in_single_chunk = true; + + if (read_in_single_chunk) { + u_int32_t chunk_addr; + u_int32_t chunk_size; + + Aligner align(_log2_chunk_size); + align.Init (addr, len); + while (align.GetNextChunk(chunk_addr, chunk_size)) { + u_int32_t phys_addr = cont2phys(chunk_addr); + // printf("-D- write: addr = %#x, phys_addr = %#x\n", chunk_addr, phys_addr); + //mft_signal_set_handling(1); + rc = mf_read(_mfl, phys_addr, chunk_size, ((u_int8_t*)data) + chunk_addr - addr); + deal_with_signal(); + if (rc != MFE_OK) { + return errmsg("Flash read failed at address %s0x%x : %s", + _log2_chunk_size ? "physical " : "", + chunk_addr, + mf_err2str(rc)); + } + } + + } else { + u_int32_t *p = (u_int32_t *)data; + for (int i=0; i get_size()) { + return errmsg( + "Trying to write %d bytes to address 0x%x, which exceeds max image size (0x%x - half of total flash size).", + cnt, + addr, + get_size() / 2); + } + + u_int8_t *p = (u_int8_t *)data; + u_int32_t sect_size = get_sector_size(); + + u_int32_t chunk_addr; + u_int32_t chunk_size; + + u_int32_t first_set; + for (first_set = 0; ((sect_size >> first_set) & 1) == 0; first_set++ ) + ; + + Aligner align(first_set); + align.Init (addr, cnt); + while (align.GetNextChunk(chunk_addr, chunk_size)) { + // Write / Erase in sector_size alligned chunks + int rc; + + if (!noerase) { + u_int32_t sector = (chunk_addr / sect_size) * sect_size; + if (sector != _curr_sector) { + _curr_sector = sector; + if (!erase_sector(_curr_sector)) { + return false; + } + + } + } + + if (_no_burn) + continue; + + // Actual write: + u_int32_t phys_addr = cont2phys(chunk_addr); + // printf("-D- write: addr = %#x, phys_addr = %#x\n", chunk_addr, phys_addr); + //mft_signal_set_handling(1); + rc = mf_write(_mfl, phys_addr, chunk_size, p); + deal_with_signal(); + + if (rc != MFE_OK) { + return errmsg("Flash write of %d bytes to address %s0x%x failed: %s", + chunk_size, + _log2_chunk_size ? "physical " : "", + chunk_addr, + mf_err2str(rc)); + } + + // Loop advance + p += chunk_size; + } + + return true; +} + + +//////////////////////////////////////////////////////////////////////// +bool Flash::write(u_int32_t addr, u_int32_t data) +{ + u_int32_t word; + + if (!_mfl) { + return errmsg("Not opened"); + } + if (addr & 0x3) { + return errmsg("Address should be 4-bytes aligned."); + } + if (!read(addr, &word)) { + return false; + } + if (word == data) { + return true; // already there + } + return write_sector_with_erase(addr, &data, 4); +} + +bool Flash::write_sector_with_erase(u_int32_t addr, void *data, int cnt) +{ + + u_int32_t sector_size = _attr.sector_size; + u_int32_t sector_mask = ~(sector_size - 1); + + u_int32_t sector = addr & sector_mask; + u_int32_t offest_in_bytes = (addr & ~sector_mask); + u_int32_t word_in_sector = offest_in_bytes / sizeof(u_int32_t); + + if (offest_in_bytes + cnt > sector_size) { + return errmsg("data exceeds current sector"); + } + + vector buff(sector_size/sizeof(u_int32_t)); + if (!read(sector, &buff[0] , sector_size)) { + return false; + } + + memcpy(&buff[word_in_sector], data, cnt); + return write(sector, &buff[0], sector_size); +} + +bool Flash::write_with_erase(u_int32_t addr, void *data, int cnt) +{ + u_int32_t towrite = (u_int32_t)cnt; + u_int32_t currSize; + while (towrite > 0) { + currSize = towrite > _attr.sector_size ? (_attr.sector_size) : towrite; + if (!write_sector_with_erase(addr, data, currSize)) { + return false; + } + towrite -= currSize; + } + return true; +} + +bool Flash::erase_sector (u_int32_t addr) { + int rc; + + u_int32_t phys_addr = cont2phys(addr); + //mft_signal_set_handling(1); + rc = mf_erase_sector(_mfl, phys_addr); + deal_with_signal(); + if (rc != MFE_OK) { + if (rc == MFE_REG_ACCESS_RESOURCE_NOT_AVAILABLE ) { + return errmsg("Flash erase of address 0x%x failed: %s\n" + " This may indicate that a FW image was already updated on flash, but not loaded by the device.\n" + " Please load FW on the device (reset device or restart driver) before burning a new FW.", + phys_addr, + mf_err2str(rc)); + } else { + return errmsg("Flash erase of address 0x%x failed: %s", + phys_addr, + mf_err2str(rc)); + } + } + + return true; +} + +bool Flash::enable_hw_access(u_int64_t key) +{ + int rc; + rc = mf_enable_hw_access(_mfl, key); + + if (rc != MFE_OK) { + return errmsg("Enable HW access failed: %s", mf_err2str(rc)); + } + return true; +} + +bool Flash::disable_hw_access(void) +{ + int rc; + rc = mf_disable_hw_access(_mfl); + + if (rc != MFE_OK) { + return errmsg("Disable HW access failed: %s", mf_err2str(rc)); + } + return true; + +} + +bool Flash::sw_reset() { + if (_attr.hw_dev_id != 435 && _attr.hw_dev_id != SWITCHX_HW_ID) { + return errmsg("operation supported only for InfiniScale4 switch and SwitchX over IB interface"); + } + int rc = mf_sw_reset(_mfl); + if (rc != MFE_OK) { + return errmsg("%s (%s)", errno == 0 ? "" : strerror(errno), mf_err2str(rc)); + } + return true; +} + + +bool Flash::get_attr(ext_flash_attr_t& attr) { + attr.banks_num = _attr.banks_num; + attr.hw_dev_id = _attr.hw_dev_id; + attr.rev_id = _attr.rev_id; + if (_attr.type_str != NULL) { + // we don't print the flash type in old devices + attr.type_str = strcpy(new char[strlen(_attr.type_str)+1], _attr.type_str); + } + attr.size = _attr.size; + attr.sector_size = _attr.sector_size; + attr.block_write = _attr.block_write; + attr.command_set = _attr.command_set; + attr.quad_en_support = _attr.quad_en_support; + // Quad EN query + if (_attr.quad_en_support) { + attr.mf_get_quad_en_rc = (MfError)mf_get_quad_en(_mfl, &attr.quad_en); + } + + // Flash write protected info query + attr.write_protect_support = _attr.write_protect_support; + if (_attr.write_protect_support) { + int bank; + for (bank = 0; bank < _attr.banks_num; bank++) { + attr.mf_get_write_protect_rc_array[bank] = (MfError)mf_get_write_protect(_mfl, bank, &attr.protect_info_array[bank]); + } + } + return true; +} + + +bool Flash::print_attr() { + u_int8_t banks_num = _attr.banks_num; + int rc; + printf("HW Info:\n"); + printf(" HwDevId %d\n", _attr.hw_dev_id); + printf(" HwRevId 0x%x\n", _attr.rev_id); + + printf("Flash Info:\n"); + if (_attr.type_str != NULL) { + // we don't print the flash type in old devices + printf(" Type %s\n", _attr.type_str); + } + printf(" TotalSize 0x%x\n", _attr.size); + printf(" Banks 0x%x\n", banks_num); + printf(" SectorSize 0x%x\n", _attr.sector_size ); + printf(" WriteBlockSize 0x%x\n", _attr.block_write); + printf(" CmdSet 0x%x\n", _attr.command_set); + + // Quad EN query + if (_attr.quad_en_support) { + u_int8_t quad_en; + rc = mf_get_quad_en(_mfl, &quad_en); + switch (rc) { + case MFE_OK: + printf(" "QUAD_EN_PARAM" %d\n", quad_en); + break; + case MFE_MISMATCH_QUAD_EN: + printf("-E- There is a mismatch in the "QUAD_EN_PARAM" attribute between the flashes attached to the device\n"); + break; + case MFE_NOT_SUPPORTED_OPERATION: + break; + default: + return errmsg("Failed to get "QUAD_EN_PARAM" attribute: %s (%s)", errno == 0 ? "" : strerror(errno), mf_err2str(rc)); + } + } + + // Flash write protected info query + if (_attr.write_protect_support) { + int bank; + for (bank = 0; bank < banks_num; bank++) { + write_protect_info_t protect_info; + rc = mf_get_write_protect(_mfl, bank, &protect_info); + if (rc == MFE_OK) { + printf(" "FLASH_NAME"%d."WRITE_PROTECT" ", bank); + if (protect_info.sectors_num != 0) { + printf("%s,", (protect_info.is_bottom ? WP_BOTTOM_STR : WP_TOP_STR)); + printf("%d-", protect_info.sectors_num); + printf("%s\n", (protect_info.is_subsector ? WP_SUBSEC_STR : WP_SEC_STR)); + } else { + printf(WP_DISABLED_STR"\n"); + + } + } else { + if (rc != MFE_NOT_SUPPORTED_OPERATION) { // We ignore the read when operation is not supported! + return errmsg("Failed to get write_protected info: %s (%s)", errno == 0 ? "" : strerror(errno), mf_err2str(rc)); + } + } + + } + } + + // TODO: Print new + + return true; +} + +#define GET_IN_PARAM(param_in, out, first_op, second_op) {\ + if (!strcmp(param_in, first_op)) {\ + out = 1;\ + } else if (!strcmp(param_in, second_op)) {\ + out = 0;\ + } else {\ + return errmsg("bad argument (%s) it can be "first_op" or " second_op"", param_in);\ + }\ +} +bool Flash::set_attr(char *param_name, char *param_val_str) +{ + int rc; + + if (!strcmp(param_name, QUAD_EN_PARAM)) { + char* endp; + u_int8_t quad_en_val; + quad_en_val = strtoul(param_val_str, &endp, 0); + if (*endp != '\0' || quad_en_val > 1) { + return errmsg("Bad "QUAD_EN_PARAM" value (%s), it can be 0 or 1\n", param_val_str); + } + rc = mf_set_quad_en(_mfl, quad_en_val); + if (rc != MFE_OK) { + return errmsg("Setting "QUAD_EN_PARAM" failed: (%s)", mf_err2str(rc)); + } + } else if (strstr(param_name, FLASH_NAME) == param_name) { + char *flash_param, *param_str, *endp, *bank_num_str; + u_int8_t bank_num; + flash_param = strtok(param_name, "."); + param_str = strtok((char*)NULL, "."); + bank_num_str = flash_param + strlen(FLASH_NAME); + bank_num = strtoul(bank_num_str, &endp, 0); + if (*endp != '\0') { + return errmsg("bad number of flash bank (%s), it should be integer!.", bank_num_str); + } + if (!strcmp(param_str, WRITE_PROTECT)) { + write_protect_info_t protect_info; + char *tb, *num_str, *sec; + + if (!strcmp(param_val_str, WP_DISABLED_STR)) { + memset(&protect_info, 0, sizeof(protect_info)); + } else { + tb = strtok(param_val_str, ","); + num_str = strtok((char*)NULL, "-"); + sec = strtok((char*)NULL, ""); + if (tb == NULL || num_str == NULL || sec == NULL) { + return errmsg("missing parameters for setting the "WRITE_PROTECT" attribute, see help for more info."); + } + GET_IN_PARAM(tb, protect_info.is_bottom, WP_BOTTOM_STR, WP_TOP_STR); + GET_IN_PARAM(sec, protect_info.is_subsector, WP_SUBSEC_STR, WP_SEC_STR); + + protect_info.sectors_num = strtoul(num_str, &endp, 0); + if (*endp != '\0') { + return errmsg("bad argument (%s), only integer value is allowed.", num_str); + } + } + rc = mf_set_write_protect(_mfl, bank_num, &protect_info); + if (rc != MFE_OK) { + return errmsg("Setting "WRITE_PROTECT" failed: (%s)", mf_err2str(rc)); + } + } else { + return errmsg("Unknown attribute %s.%s", flash_param, param_str); + } + + + } else { + return errmsg("Unknown attribute %s", param_name); + } + + return true; +} + +void Flash::deal_with_signal() +{ + /* + int sig; + sig = mft_signal_is_fired(); + if (sig) { + // reset recieved signal + mft_signal_set_fired(0); + // retore prev handler + mft_signal_set_handling(0); + //raise signal to let the previous handle deal with it. + raise(sig); + } + mft_signal_set_handling(0); + */ + return; +} + + diff --git a/mlxfwops/lib/flint_io.h b/mlxfwops/lib/flint_io.h new file mode 100755 index 0000000..94bc4a3 --- /dev/null +++ b/mlxfwops/lib/flint_io.h @@ -0,0 +1,325 @@ +/* + * + * flint_io.h - FLash INTerface + * + * Copyright (c) 2011 Mellanox Technologies Ltd. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Version: $Id: flint_io.h 7522 2011-11-16 15:37:21Z mohammad $ + * + */ +#ifndef FLINT_IO_H +#define FLINT_IO_H + +#ifdef __WIN__ + +#ifdef MLXFWOP_EXPORTS +#define MLXFWOP_API __declspec(dllexport) +#else +#define MLXFWOP_API __declspec(dllimport) +#endif + +#else +#define MLXFWOP_API +#endif + +#include "flint_base.h" +#include +//#include + +// external flash attr struct + +#define IO_MAX_BANKS_NUM 4 + +typedef struct ext_flash_attr { + u_int8_t banks_num; + u_int32_t hw_dev_id; + u_int32_t rev_id; + char* type_str; // NULL if not available + u_int32_t size; + u_int32_t sector_size; + int block_write; + int command_set; + u_int8_t quad_en_support; + + u_int8_t quad_en; + MfError mf_get_quad_en_rc; + + u_int8_t write_protect_support; + + write_protect_info_t protect_info_array[IO_MAX_BANKS_NUM]; + MfError mf_get_write_protect_rc_array[IO_MAX_BANKS_NUM]; + +} ext_flash_attr_t; + +// Common base class for Flash and for FImage +class MLXFWOP_API FBase : public ErrMsg { +public: + FBase(bool is_flash) : + _log2_chunk_size(0), + _is_flash(is_flash) {} + virtual ~FBase() {} + + virtual bool open(const char *, bool) {return false;} + virtual void close() = 0; + virtual bool read(u_int32_t addr, u_int32_t *data) = 0; + virtual bool read(u_int32_t addr, void *data, int len, + bool verbose=false, + const char* message = "") = 0; + + virtual u_int32_t get_sector_size() = 0; + virtual u_int32_t get_size() = 0; + + virtual u_int32_t get_dev_id() = 0; + virtual u_int32_t get_rev_id() = 0; + Crc16& get_image_crc() {return _image_crc;}; + bool is_flash() {return _is_flash;}; + + bool read_phy (u_int32_t phy_addr, void* data, int len); + bool read_phy (u_int32_t phy_addr, u_int32_t* data); + + virtual void set_address_convertor(u_int32_t log2_chunk_size, bool is_image_in_odd_chunks) { + _log2_chunk_size = log2_chunk_size; + _is_image_in_odd_chunks = is_image_in_odd_chunks; + } + virtual u_int32_t get_phys_from_cont (u_int32_t cont_addr, u_int32_t log2_chunk_size, bool is_image_in_odd_chunks) { + u_int32_t phys_addr; + u_int32_t log2_chunk_size_bak = _log2_chunk_size; + bool is_image_in_odd_chunks_bak = _is_image_in_odd_chunks; + + set_address_convertor(log2_chunk_size, is_image_in_odd_chunks); + phys_addr = cont2phys(cont_addr); + set_address_convertor(log2_chunk_size_bak, is_image_in_odd_chunks_bak); + return phys_addr; + } + + enum { + MAX_FLASH = 4*1048576 + }; + + +protected: + + // Address translation functions for ConnectX. + // Translate between contiguous "logical" addresses + + // If Failsafe zebra mapping is enabled: + + // Result is concatenation of: + // The lower log2_chunk_size bits of the cons_addr + // The is_image_in_odd_chunk bit + // The remaining upper bits of the cons_addr + + u_int32_t cont2phys(u_int32_t cont_addr) { + u_int32_t result; + if (_log2_chunk_size) { + result = (cont_addr & (0xffffffff >> (32 - _log2_chunk_size))) | + (_is_image_in_odd_chunks << _log2_chunk_size) | + ((cont_addr << 1) & (0xffffffff << (_log2_chunk_size + 1))); + } else { + result = cont_addr; + } + return result; + } + + u_int32_t phys2cont(u_int32_t phys_addr) { + u_int32_t result; + if (_log2_chunk_size) { + result = (phys_addr & (0xffffffff >> (32 - _log2_chunk_size))) | + ((phys_addr >> 1) & (0xffffffff << ( _log2_chunk_size))); + } else { + result = phys_addr; + } + return result; + } + + bool _is_image_in_odd_chunks; + u_int32_t _log2_chunk_size; + Crc16 _image_crc; + const bool _is_flash; + +}; + + + + +// Flash image (R/W) +class MLXFWOP_API FImage : public FBase { +public: + FImage() : FBase(false), _buf(0) {} + virtual ~FImage() { close();} + + u_int32_t *getBuf() { return _buf;} + u_int32_t getBufLength() { return _len;} + virtual bool open(const char *fname, bool read_only = false); + bool open(u_int32_t *buf, u_int32_t len); + virtual void close(); + virtual bool read(u_int32_t addr, u_int32_t *data); + virtual bool read(u_int32_t addr, void *data, int len, bool verbose=false, const char* message= ""); + + virtual u_int32_t get_sector_size(); + virtual u_int32_t get_size() { return getBufLength();} + virtual u_int32_t get_dev_id() { return 0;} + virtual u_int32_t get_rev_id() { return 0;} +private: + u_int32_t *_buf; + u_int32_t _len; +}; + + + + +// +// Flash access (R/W) +// + + + + +class MLXFWOP_API Flash : public FBase { +public: + Flash() : + FBase(true), + _mfl(0), + _curr_sector(0xffffffff), + _port_num(0), + _cr_space_locked(0) + {} + + virtual ~Flash() { close();}; + + // FBase Interface + + virtual bool open (const char *device, + bool force_lock = false, + bool read_only = false, + int num_of_banks = 4, + flash_params_t *flash_params = (flash_params_t *)NULL, + int ignoe_cache_replacement = 0); + + + bool open (uefi_Dev_t *uefi_dev, + f_fw_cmd fw_cmd_func, + bool force_lock = false); + + virtual void close (); + + virtual bool read (u_int32_t addr, + u_int32_t *data); + + virtual bool read (u_int32_t addr, + void* data, + int len, + bool verbose = false, + const char* message = ""); + bool write_phy(u_int32_t phy_addr, void* data, int cnt, bool noerase = false); + bool write_phy(u_int32_t phy_addr, u_int32_t data); + bool erase_sector_phy (u_int32_t phy_addr); + + bool update_boot_addr (u_int32_t boot_addr) + {return mf_update_boot_addr(_mfl, boot_addr) == MFE_OK;} + // + // Flash Interface + // + + u_int32_t get_sector_size () {return _attr.sector_size;} + u_int32_t get_size () {return _attr.size;} + + u_int32_t get_dev_id () {return _attr.hw_dev_id; } + u_int32_t get_rev_id () {return _attr.rev_id; } + u_int32_t get_port_num () {return _port_num;} + u_int8_t get_cr_space_locked () {return _cr_space_locked;} + + bool sw_reset(); + + void set_no_flash_verify(bool val) {_no_flash_verify = val; return;} + void set_byte_mode(bool val) {_byte_mode = val; return;} + + // Write and Erase functions are performed by the Command Set + + virtual bool erase_sector (u_int32_t addr); + + virtual bool write (u_int32_t addr, + void* data, + int cnt, + bool noerase = false); + + virtual bool write (u_int32_t addr, + u_int32_t data); + + virtual bool enable_hw_access(u_int64_t key); + + virtual bool disable_hw_access(); + + bool print_attr(); + + bool get_attr(ext_flash_attr_t& attr); + + bool set_attr(char *param_name, + char *param_val_str); + static void deal_with_signal(); + + enum { + TRANS = 4096 + }; + + bool open_com_checks(const char *device, + int rc, + bool force_lock); + + +//needed for printing flash status in flint hw query cmd +#define QUAD_EN_PARAM "QuadEn" +#define FLASH_NAME "Flash" +#define WRITE_PROTECT "WriteProtected" +#define WP_TOP_STR "Top" +#define WP_BOTTOM_STR "Bottom" +#define WP_SEC_STR "Sectors" +#define WP_SUBSEC_STR "SubSectors" +#define WP_DISABLED_STR "Disabled" + +#ifndef _MSC_VER +protected: +#endif + bool write_sector_with_erase(u_int32_t addr, void *data, int cnt); + bool write_with_erase(u_int32_t addr, void *data, int cnt); + + static bool _byte_mode; + static bool _no_flash_verify; + + mflash* _mfl; + flash_attr _attr; + + u_int32_t _curr_sector; + u_int32_t _port_num; + u_int8_t _cr_space_locked; +}; + +#endif diff --git a/mlxfwops/lib/fs2_ops.cpp b/mlxfwops/lib/fs2_ops.cpp new file mode 100644 index 0000000..6b4584d --- /dev/null +++ b/mlxfwops/lib/fs2_ops.cpp @@ -0,0 +1,1951 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +#include "fs2_ops.h" +// #include "flint_ops.h" + +#define PRE_CRC_OUTPUT " " +#define CRC_CHECK_OUTPUT CRC_CHECK_OLD")" + + +static int part_cnt; +extern const char* g_sectNames[]; + +bool Fs2Operations::FwInit() +{ + FwInitCom(); + memset(&_fs2ImgInfo, 0, sizeof(_fs2ImgInfo)); + return true; +} + + +bool Fs2Operations::CntxGetFsData(u_int32_t fs_info_word, bool& fs_en, u_int32_t& log2chunk_size) { + u_int8_t checksum; + //printf("-D- fs_info_word=%08x\n", fs_info_word); + + checksum = ((fs_info_word ) & 0xff) + + ((fs_info_word >> 8) & 0xff) + + ((fs_info_word >> 16) & 0xff) + + ((fs_info_word >> 24) & 0xff); + + if (checksum != 0) { + return errmsg("Corrupted chunk size checksum"); + } + + fs_en = (fs_info_word & 0x8) != 0; + + if (fs_en) { + log2chunk_size = (fs_info_word & 0x7) + 16; + } else { + log2chunk_size = 0; + } + return true; +} + +bool Fs2Operations::ParseInfoSect(u_int8_t* buff, u_int32_t byteSize) { + + + u_int32_t *p = (u_int32_t*)buff; + u_int32_t offs = 0; + u_int32_t tagNum = 0; + bool endFound = false; + + // TODO: Add new flag on the info which indicates that the ParseInfoSect was already called. + + while (!endFound && offs < byteSize) { + u_int32_t tagSize = __be32_to_cpu(*p) & 0xffffff; + u_int32_t tagId = __be32_to_cpu(*p) >> 24; + + if (offs + tagSize > byteSize) { + return errmsg("Info section corrupted: Tag %d (TagId %d, size %d) exceeds Info section size (%d bytes) ", + tagNum, tagId, tagSize, byteSize); + } + // printf("-D- tagId = (%#x), tagSize = (%#x), offs = %#x\n", tagId, tagSize, offs); + u_int32_t tmp; + const char* str; + switch (tagId) { + case II_FwVersion: + _fwImgInfo.ext_info.fw_ver[0] = u_int16_t(__be32_to_cpu(*(p+1)) >> 16); + tmp = __be32_to_cpu(*(p+2)); + _fwImgInfo.ext_info.fw_ver[1] = tmp >> 16; + _fwImgInfo.ext_info.fw_ver[2] = tmp & 0xffff; + break; + + case II_MinFitVersion: + tmp = __be32_to_cpu(*(p+1)); + _fwImgInfo.ext_info.min_fit_ver[0] = tmp >> 16; + _fwImgInfo.ext_info.min_fit_ver[1] = tmp & 0xffff; + tmp = __be32_to_cpu(*(p+2)); + _fwImgInfo.ext_info.min_fit_ver[2] = tmp >> 16; + _fwImgInfo.ext_info.min_fit_ver[3] = tmp & 0xffff; + break; + case II_MicVersion: + tmp = __be32_to_cpu(*(p+1)); + _fwImgInfo.ext_info.mic_ver[0] = tmp >> 16; + //_fwImgInfo.ext_info.minFitVer[1] = tmp & 0xffff; + tmp = __be32_to_cpu(*(p+2)); + _fwImgInfo.ext_info.mic_ver[1] = tmp >> 16; + _fwImgInfo.ext_info.mic_ver[2] = tmp & 0xffff; + break; + case II_DeviceType: + tmp = __be32_to_cpu(*(p+1)); + _fwImgInfo.ext_info.dev_type = tmp & 0xffff; + //info->devRev = (tmp >> 16) & 0xff; + break; + + case II_VsdVendorId: + tmp = __be32_to_cpu(*(p+1)); + _fwImgInfo.ext_info.vsd_vendor_id = tmp & 0xffff; + break; + + case II_IsGa: + tmp = __be32_to_cpu(*(p+1)); + _fwImgInfo.isGa = tmp ? true : false;; + break; + + case II_PSID: + // set psid only if not previosly found in PS + str = (const char*)p; + str += 4; + + for (int i = 0 ; i < PSID_LEN ; i++) { + _fwImgInfo.ext_info.psid[i] = str[i]; + } + _fwImgInfo.ext_info.psid[PSID_LEN] = '\0'; + break; + + case II_VSD: + // set psid only if not previosly found in PS + str = (const char*)p; + str += 4; + + for (int i = 0 ; i < VSD_LEN ; i++) { + _fwImgInfo.ext_info.vsd[i] = str[i]; + } + _fwImgInfo.ext_info.vsd[VSD_LEN] = '\0'; + _fwImgInfo.ext_info.vsd_sect_found = true; + break; + case II_ProductVer: + + str = (const char*)p; + str += 4; + for (int i = 0 ; i < PRODUCT_VER_LEN ; i++) { + _fwImgInfo.ext_info.product_ver[i] = str[i]; + } + _fwImgInfo.ext_info.product_ver[PRODUCT_VER_LEN] = '\0'; + break; + case II_HwDevsId: + u_int32_t i; + for (i = 1; i <= (tagSize / 4); i++) { + _fwImgInfo.supportedHwId[i - 1] = __be32_to_cpu(*(p + i)); + } + _fwImgInfo.supportedHwIdNum = tagSize / 4; + break; + case II_HwAccessKey: { + _fs2ImgInfo.ext_info.access_key_value.h = __be32_to_cpu(*(p + 1));; + _fs2ImgInfo.ext_info.access_key_value.l = __be32_to_cpu(*(p + 2));; + _fs2ImgInfo.ext_info.access_key_exists= 1; + } + break; + case II_PROFILES_LIST: { + GetSectData(_fs2ImgInfo.profListSectZipped, p + 1, tagSize); + } + break; + case II_TLVS_FORMAT: { + GetSectData(_fs2ImgInfo.TlvFormatSectZipped, p + 1, tagSize); + } + break; + case II_TRACER_HASH: { + GetSectData(_fs2ImgInfo.TracerHashSectZipped, p + 1, tagSize); + } + break; + + case II_CONFIG_INFO: { + // printf("-D- configExists\n"); + _fs2ImgInfo.isConfigurable = true; + _fs2ImgInfo.defPorfile = __be32_to_cpu(*(p + 1));; + } + break; + case II_SUPPORTED_PROFS: { + for (u_int32_t i = 1; i <= (tagSize / 4); i++) { + u_int32_t id; + id = __be32_to_cpu(*(p + i)); + _fs2ImgInfo.supportedProfList.push_back(id); + } + } + break; + + case II_ConfigArea: { + // configuration area should always exsist + _fs2ImgInfo.ext_info.config_sectors = __be32_to_cpu(*(p + 1));; + _fs2ImgInfo.ext_info.config_pad = __be32_to_cpu(*(p + 2));; + } + break; + + case II_End: + endFound = true; + break; + + //default: + //printf("-D- Found tag ID %d of size %d - ignoring.\n", tagId, tagSize); + } + + if (tagId < II_Last) { + _fs2ImgInfo.infoOffs[tagId] = offs + 4; + } + + p += tagSize/4 + 1; + offs += tagSize + 4; + tagNum++; + } + + if (offs != byteSize) { + if (endFound) { + return errmsg("Info section corrupted: Section data size is 0x%x bytes, " + "but end tag found after 0x%x bytes.", byteSize, offs); + } else { + return errmsg("Info section corrupted: Section data size is 0x%x bytes, " + "but end tag not found before section end.", byteSize); + } + } + return true; +} + + +void Fs2Operations::initSectToRead(int imp_index) +{ + for (int i = 0; i < H_LAST; i++) { + if (imp_index == FULL_VERIFY || i == imp_index) { + _sectionsToRead[i] = 1; + } else { + _sectionsToRead[i] = 0; + } + } + if (imp_index == FULL_VERIFY) { + _isFullVerify = true; + } else { + _isFullVerify = false; + } + + return; +} + +bool Fs2Operations::checkGen(u_int32_t beg,u_int32_t offs, u_int32_t& next, const char *pref, + VerifyCallBack verifyCallBackFunc) +{ + // char *pr = (char *)alloca(strlen(pref) + 100); + char pr[strlen(pref) + 100]; + + char unknown_sect_name[128]; + const char* sect_name; + + u_int32_t size = 0; + GPH gph; + bool is_sect_to_read = false; + // printf("-D- checkGen ... \n"); + // GPH + sprintf(pr, "%s /0x%08x/ (GeneralHeader)", pref, offs+beg); + READBUF((*_ioAccess), offs + beg, &gph, sizeof(GPH), pr); + TOCPUBY(gph); + + // Body + part_cnt++; + + // May be BOOT3? + if (gph.type < H_FIRST || gph.type >= H_LAST) { + if (part_cnt > 2) { + //report_callback(verifyCallBackFunc, "%s /0x%x/ - Invalid partition type (%d)\n", + // pref, offs+beg, gph.type); + //return false; + } else { + return checkBoot2(beg, offs, next, _isFullVerify, pref, verifyCallBackFunc); + } + } + + // All partitions here + offs += beg; + + if (gph.type < H_FIRST || gph.type >= H_LAST) { + // For forward compatibility, try analyzing even if section type is unknown + // Assuming the size is in DW, like all other sections (except emt service). + // If this assumption is wrong, CRC calc would fail - no harm done. + sprintf(unknown_sect_name, "UNKNOWN (%d)" , gph.type); + sect_name = unknown_sect_name; + size = gph.size * 4; + is_sect_to_read = true; + + } else { + if (gph.type == H_EMT) { + size = (gph.size + 3) / 4 * 4; + } else { + size = gph.size * 4; + } + sect_name = g_sectNames[gph.type]; + // We verify part of the image only when we verify an image burnt on a device + if (_ioAccess->is_flash()) { + is_sect_to_read = _sectionsToRead[gph.type]; + } else { + is_sect_to_read = true; + } + + } + + sprintf(pr, CRC_CHECK_OUTPUT, + pref, offs, offs+size+(u_int32_t)sizeof(gph)+3, + size+(u_int32_t)sizeof(gph)+4, sect_name); + + if (size > MAX_SECTION_SIZE) { + report_callback(verifyCallBackFunc, "%s - size too big (0x%x)\n", + pr, size); + return false; + } + if (is_sect_to_read) { + // CRC + Crc16 crc; + std::vector buffv(size); + u_int32_t *buff = (u_int32_t*)(&(buffv[0])); + + READBUF((*_ioAccess), offs+sizeof(gph), buff, size, pr); + + TOCPUn(buff,size/4); + CRCBY(crc, gph); + CRCBY(_ioAccess->get_image_crc(), gph); + + CRCn(crc, buff, size/4); + CRCn(_ioAccess->get_image_crc(), buff, size/4); + //printf("-D- GEN: CRC is %#x\n", _ioAccess->get_image_crc().get()); + crc.finish(); + + u_int32_t crc_act; + READ4((*_ioAccess), offs+sizeof(gph)+size, &crc_act, pr); + TOCPU1(crc_act); + bool blank_crc = false; + + + if (gph.type == H_GUID && crc_act == 0xffff) { + blank_crc = true; + _fs2ImgInfo.ext_info.blank_guids = true; + } + + if (!CheckAndPrintCrcRes(pr, blank_crc, offs, crc_act, crc.get(), false, verifyCallBackFunc)) { + return false; + + } + + _ioAccess->get_image_crc() << crc.get(); + // The image info may be null, please check that before using it. + if (gph.type == H_FW_CONF) { + GetSectData(_fwConfSect, buff, size); + } + if (gph.type == H_HASH_FILE) { + GetSectData(_hashFileSect, buff, size); + } + + if (gph.type == H_IMG_INFO) { + CPUTOn(buff, size/4); + if (!ParseInfoSect((u_int8_t*)buff, size)) { + return errmsg("Failed to read the info sector: %s\n", err()); + } + + } + + if (gph.type == H_ROM && _romSect.empty()) { + TOCPUn(buff, size/4); + GetSectData(_romSect, buff, size); + } + } + + + // mark last read addr + _fwImgInfo.lastImageAddr = offs + size + sizeof(gph) + 4; // the 4 is for the trailing crc + next = gph.next; + + return true; +} // checkGen + + +//////////////////////////////////////////////////////////////////////// +bool Fs2Operations::checkList(u_int32_t offs, u_int32_t fw_start, const char *pref, VerifyCallBack verifyCallBackFunc) + +{ + //is initilized in CHECKB2 + u_int32_t next_ptr = 0; + + CHECKB2(offs, fw_start, next_ptr, _isFullVerify, pref, verifyCallBackFunc); + part_cnt = 1; + while (next_ptr && next_ptr != 0xff000000) { + CHECKGN(offs, next_ptr, next_ptr, pref, verifyCallBackFunc); + } + + return true; +} // checkList + +bool Fs2Operations::Fs2Verify(VerifyCallBack verifyCallBackFunc, bool is_striped_image, bool both_images, bool only_get_start, bool ignore_full_image_crc, + bool force_no_striped_image) +{ + u_int32_t cntx_image_start[CNTX_START_POS_SIZE]; + u_int32_t cntx_image_num; + + u_int32_t i; + bool ret = true; + u_int32_t act_crc; + bool check_full_crc = false; + + // printf("-D- VerifyFs2 = ok\n"); + // Look for image in "physical addresses + CntxFindAllImageStart(_ioAccess, cntx_image_start, &cntx_image_num); + if (cntx_image_num == 0) { + return errmsg("No valid image found"); + } else if (cntx_image_num > 2) { + // This check may be redundant - Maybe ignore if more than 2 images found + return errmsg("More than 2 image start locations found at addresses 0x%x, 0x%x and 0x%x. Image may be corrupted.", + cntx_image_start[0], + cntx_image_start[1], + cntx_image_start[2]); + } + + if (!both_images) { + // Check only the first image. This is enough to ensure that the device is bootable. + cntx_image_num = 1; + } + + + // Verify the images: + for (i = 0; i < cntx_image_num; i++) { + bool fs_en; + u_int32_t log2chunk_size; + u_int32_t buff[FS2_BOOT_START / 4]; + + _ioAccess->get_image_crc().clear(); + + _ioAccess->set_address_convertor(0, 0); + + READBUF((*_ioAccess), cntx_image_start[i], buff, FS2_BOOT_START, "Image header"); + + TOCPUn(buff, FS2_BOOT_START / 4); + + u_int32_ba crc_dw = buff[IMG_CRC_OFF / 4]; + act_crc = u_int32_t(crc_dw.range(15, 0)); + crc_dw.range(15, 0) = 0xffff; + buff[IMG_CRC_OFF / 4] |= crc_dw; + + CRCn(_ioAccess->get_image_crc(), buff, FS2_BOOT_START / 4); + //printf("-D- CRC is %#x\n", _ioAccess->get_image_crc().get()); + if (!CntxGetFsData(buff[FS_DATA_OFF / 4], fs_en, log2chunk_size)) { + report_callback(verifyCallBackFunc, "\n Can not read failsafe info word: %s\n", err()); + return(i > 0); + } + + // If fw not enabled, image must start at addr 0 + if (!fs_en && cntx_image_start[i] != 0) { + return errmsg("FS2 Non Failsafe image must start at address 0. Found non-fs image at address 0x%x", + cntx_image_start[i]); + } + + if (fs_en) { + report_callback(verifyCallBackFunc, "\n FS2 failsafe image. Start address: 0x%x. Chunk size 0x%x:\n\n", cntx_image_start[i], 1 << log2chunk_size); + report_callback(verifyCallBackFunc, " NOTE: The addresses below are contiguous logical addresses. Physical addresses on\n" + " flash may be different, based on the image start address and chunk size\n\n"); + } else { + report_callback(verifyCallBackFunc, "\n FS2 non failsafe image:\n\n"); + } + + if (fs_en && cntx_image_start[i] != 0 && cntx_image_start[i] != (u_int32_t)(1 << log2chunk_size)) { + return errmsg("FS2 Failsafe image must start at address 0 or at chunk size. Found a failsafe image at address 0x%x", + cntx_image_start[i]); + } + + _fwImgInfo.imgStart = cntx_image_start[i]; + _fwImgInfo.ext_info.is_failsafe = fs_en; + _fwImgInfo.actuallyFailsafe = true; + _fwImgInfo.cntxLog2ChunkSize = log2chunk_size; + + + + if (_ioAccess->is_flash()) { + // In flash, image layout must match the FS Data + _fwImgInfo.actuallyFailsafe = true; + + + if (fs_en) { + _ioAccess->set_address_convertor(log2chunk_size, cntx_image_start[i] != 0); + } + } else { + // In an image file there are 2 cases: + // 1. Image generated by mlxburn + // The image in the file is contiguous (though it is marked as FS) - no need to set address convertion. + // 2. The image was raw read from flash. In this case it would be in "zebra" format. + // + // So - I try both cases, and see which verify() succeeds. + // + // Heuristics that may come in handy: + // If the image does not start at addr 0, it's not an mlxburn image. + // If there is more than a single valid image, it's not an mlxburn image. + // If the file size matches the image size, it is an mlxburn image. + // + // For now, get the "striped" indication from user. + + if (!force_no_striped_image && is_striped_image) { + _ioAccess->set_address_convertor(log2chunk_size, cntx_image_start[i] != 0); + } else { + _ioAccess->set_address_convertor(0, 0); //disable conversion + } + _fwImgInfo.actuallyFailsafe = is_striped_image; + } + + bool imgStat = true; + // TODO: check what only_get_start means. + if (!only_get_start) { + imgStat = checkList(0, FS2_BOOT_START, PRE_CRC_OUTPUT, verifyCallBackFunc); + } + _ioAccess->get_image_crc().finish(); + + u_int32_t full_crc = _ioAccess->get_image_crc().get(); + + if (!ignore_full_image_crc && _fs2ImgInfo.infoOffs[II_MicVersion]) { // For now we check only that the Mic version existing . + check_full_crc = true; + } + if (imgStat && _isFullVerify && check_full_crc && !only_get_start) { + char pr[256]; + sprintf(pr, CRC_CHECK_OUTPUT, PRE_CRC_OUTPUT, 0, _fwImgInfo.lastImageAddr - 1, _fwImgInfo.lastImageAddr, + "Full Image"); + CheckAndPrintCrcRes(pr, _fs2ImgInfo.ext_info.blank_guids, 0, act_crc, full_crc, false, verifyCallBackFunc); + } + if (i == 0) { + ret = ret && imgStat; + } + } + return ret; +} +bool Fs2Operations::FwVerify(VerifyCallBack verifyCallBackFunc, bool isStripedImage, bool showItoc) +{ + //dummy assignment to avoid compiler warrning (showItoc is not used in fs2) + showItoc = true; + // if (!_wasVerified) { + initSectToRead(FULL_VERIFY); + if (!Fs2Verify(verifyCallBackFunc, isStripedImage)) { + // empty the initSectToRead + initSectToRead(H_LAST); + return false; + } + // empty the initSectToRead + initSectToRead(H_LAST); + _wasVerified = true; + return true; +} + +u_int8_t Fs2Operations::FwType() +{ + return FIT_FS2; +} + +bool Fs2Operations::FwReadData(void* image, u_int32_t* image_size) +{ + if (!Fs2Verify((VerifyCallBack)NULL)) { + return false; + } + *image_size = _fwImgInfo.lastImageAddr; + if (image != NULL) { + if (!_ioAccess->read(0, (u_int32_t*)image, *image_size)) { + return errmsg("Failed to read Image: %s", _ioAccess->err()); + } + } + return true; +} + + +bool Fs2Operations::FwTest(u_int32_t *data) +{ + _ioAccess->set_address_convertor(0,0); + + if (!_ioAccess->read(0, data)) { + return false; + } + + if (!_ioAccess->read(0x80000, data)) { + return false; + } + + if (!_ioAccess->read(0x4, data)) { + return false; + } + if (!_ioAccess->read(0x80004, data)) { + return false; + } + u_int32_t addr = 0x1fffd8; + u_int32_t content = 0x32; + + + if (!_ioAccess->read(addr, data)) { + return false; + } + + if (!((Flash*)_ioAccess)->write(addr, content)) { + + return false; + } + + if (!_ioAccess->read(addr, data)) { + return false; + } + if (*data != content) { + return false; + } + + return true; + +} + +bool Fs2Operations::Fs2Query () { + + u_int32_t guid_ptr, nguids; + guid_t guids[MAX_GUIDS]; + /* + if (_fwImgInfo.wasQueried == true) { + return true; + } + */ + // FW ID + u_int32_t fw_id; + u_int32_t fw_id_offs; + u_int32_t fw_size; + u_int32_t im_start = _fwImgInfo.imgStart; + + if (_fwImgInfo.ext_info.is_failsafe && _fwImgInfo.actuallyFailsafe) { + _ioAccess->set_address_convertor(_fwImgInfo.cntxLog2ChunkSize, im_start != 0); + } else { + _ioAccess->set_address_convertor(0,0); + } + + im_start = 0; // offset is done by address convertor + _fwImgInfo.magicPatternFound = true; + fw_id_offs = 0x20; + + READ4((*_ioAccess), im_start + fw_id_offs, &fw_id, "FW ID"); + TOCPU1(fw_id); + + READ4((*_ioAccess), im_start + fw_id_offs + 0x10, &fw_size, "FW SIZE"); + TOCPU1(fw_size); + _fwImgInfo.ext_info.image_size = fw_size; + + _fwImgInfo.ext_info.dev_rev = fw_id >> 24; + // Read GUIDs + READ4((*_ioAccess), im_start + fw_id_offs + 0x14 , &guid_ptr, "GUID PTR"); + TOCPU1(guid_ptr); + _fs2ImgInfo.guidPtr = guid_ptr; + + guid_ptr += im_start; + if (guid_ptr >= _ioAccess->get_size()) { + return errmsg("Failed to read GUIDs - Illegal GUID pointer (%08x). Probably image is corrupted", guid_ptr); + } + READ4((*_ioAccess), guid_ptr - 3*sizeof(u_int32_t), &nguids, "Number of GUIDs"); + TOCPU1(nguids); + nguids /= 2; + if (nguids > MAX_GUIDS) { + return errmsg("Failed to read GUIDs - Illegal Number of GUIDs (%d)", nguids); + //return false; + } + READBUF((*_ioAccess), guid_ptr, guids, nguids * sizeof(u_int64_t), "GUIDS"); + TOCPUBY64(guids); + + u_int32_t guids_crc; + READ4((*_ioAccess), guid_ptr + nguids * sizeof(u_int64_t), &guids_crc, "GUIDS CRC"); + guids_crc = __be32_to_cpu(guids_crc); + + _fs2ImgInfo.ext_info.blank_guids = true; + if ((guids_crc & 0xffff) != 0xffff ) { + _fs2ImgInfo.ext_info.blank_guids = false; + } + + _fs2ImgInfo.ext_info.guid_num = nguids; + for (u_int32_t i = 0 ; i < nguids ; i++) { + _fs2ImgInfo.ext_info.guids[i] = guids[i]; + if (guids[i].h != 0xffffffff || guids[i].l != 0xffffffff) { + _fs2ImgInfo.ext_info.blank_guids = false; + } + } + // Expansion Rom version: + RomInfo rInfo(_romSect, false); + // There is no check for the return value of this function because it's a wrapper that always succeeds, + // but fills the error string when there is an error + rInfo.ParseInfo(); + rInfo.initRomsInfo(&_fwImgInfo.ext_info.roms_info); + + // Read Info: + u_int32_ba info_ptr_ba; + u_int32_t info_ptr; + u_int32_t info_size; + u_int8_t info_ptr_cs = 0; + READ4((*_ioAccess), im_start + fw_id_offs + 0xC, &info_ptr, "INFO PTR"); + TOCPU1(info_ptr); + + // Verify info_ptr checksum (should be 0) + info_ptr_ba = info_ptr; + for (u_int32_t i = 0; i < 4 ; i++) { + info_ptr_cs += (u_int8_t)info_ptr_ba.range(i*8+7, i*8); + } + + if (info_ptr_cs) { + return errmsg("Failed to read Info Section - Bad checksum for Info section pointer (%08x). Probably the image is corrupted.", info_ptr); + } + + info_ptr = info_ptr_ba.range(23,0); + if (info_ptr_cs == 0 && info_ptr != 0) { + _fs2ImgInfo.infoSectPtr = info_ptr; + + info_ptr += im_start; + if (info_ptr >= _ioAccess->get_size()) { + return errmsg("Failed to read Info Section - Info section pointer (%08x) too large. Probably the image is corrupted.", info_ptr); + } + READ4((*_ioAccess), info_ptr - 3*sizeof(u_int32_t), &info_size, "Info section size"); + TOCPU1(info_size); + + // byte size; + info_size *= 4; + + // u_int8_t* info_buff = (u_int8_t*)alloca(info_size); + u_int8_t info_buff[info_size]; + READBUF((*_ioAccess), info_ptr, info_buff, info_size, "Info Section"); + + if (!ParseInfoSect(info_buff, info_size)) { + return false; + } + } + + _fwImgInfo.imageOk = true; + _fwImgInfo.wasQueried = true; + return true; +} + +bool Fs2Operations::Fs2IntQuery(bool readRom, bool isStripedImage) +{ + if (readRom) { + initSectToRead(H_ROM); + } else { + initSectToRead(H_LAST); + } + if (!Fs2Verify(NULL, isStripedImage)) { + initSectToRead(H_LAST); + return false; + } + initSectToRead(H_LAST); + if (!Fs2Query()) { + return false; + } + _fwImgInfo.ext_info.chip_type = getChipType(); + return true; +} + +bool Fs2Operations::FwQuery(fw_info_t *fwInfo, bool readRom, bool isStripedImage) +{ + if (!Fs2IntQuery(readRom, isStripedImage)) { + return false; + } + memcpy(&(fwInfo->fw_info), &(_fwImgInfo.ext_info), sizeof(fw_info_com_t)); + memcpy(&(fwInfo->fs2_info), &(_fs2ImgInfo.ext_info), sizeof(fs2_info_t)); + //set the chipType in fwInfo + fwInfo->fw_type = FIT_FS2; + return true; +} + +#define MY_MAX(a, b) ((a) > (b) ? (a) : (b)) + +bool Fs2Operations::GetMaxImageSize(u_int32_t flash_size, bool image_is_fs, u_int32_t imgConfigSectors,\ + u_int32_t &max_image_size) +{ + //printf("-D- flash_info->configAddr1 = %#x, image_info->configAddr1 = %#x\n", flash_info->configAddr1, image_info->configAddr1); + //printf("-D- flash_info->configSize = %#x, _ignore_config_section = %#x, image_info->configExists = %#x\n", flash_info->configSize, _ignore_config_section, + // image_info->configExists); + // max_image_size = (image_is_fs) ? flash_size / 2 : flash_size; +/* + if (!ignore_config_section && flash_info->imageOk && (image_info->isConfigurable || flash_info->isConfigurable)) { + // Configurable image and there is a configuration burnt in the flash + if (image_info->isFailsafe) { // failsafe image + max_image_size = (flash_size / 2) - flash_info->configSize; + } else { // non-faislafe image + // Get the minimum config addr + max_image_size = flash_info->configAddr2; + } + } else { + // Non-configurable image or the user asked to ignore the configuration section + } +*/ + + + // Non-configurable image or the user asked to ignore the configuration section + u_int32_t sector_size = _ioAccess->get_sector_size(); + u_int32_t config_sectors = MY_MAX(imgConfigSectors, _fs2ImgInfo.ext_info.config_sectors); + if (image_is_fs) { + max_image_size = (flash_size / 2) - ((config_sectors + _fs2ImgInfo.ext_info.config_pad) * sector_size); + } else { + // For non FS image, there's an optional offset + 2 consecutive config areas + max_image_size = flash_size - (config_sectors * 2 + _fs2ImgInfo.ext_info.config_pad) * sector_size; + } + + return true; +} + +bool Fs2Operations::UpdateFullImageCRC(u_int32_t* buff, u_int32_t size, bool blank_guids) +{ + // Writing 0xffff on the CRC field. + u_int32_ba crc_dw = TOCPU1(buff[IMG_CRC_OFF / 4]); + crc_dw.range(15, 0) = 0xffff; + + + buff[IMG_CRC_OFF / 4] = CPUTO1(crc_dw); + + if (blank_guids) { + return true; + } + + // Calc CRC image. + u_int32_t new_crc = CalcImageCRC(buff, size); + + // Update the CRC. + TOCPU1(crc_dw); + crc_dw.range(15, 0) = new_crc; + buff[IMG_CRC_OFF / 4] = CPUTO1(crc_dw); + + return true; +} +#define ERASE_MESSAGE " Please erase them by using the command: \"" MLXCONFIG_CMD " " ERASE_CMD "\" and then re-burn" +//TODO: remove pre_message from function def +bool Fs2Operations::Fs2FailSafeBurn(Fs2Operations &imageOps, + bool allow_nofs, + const char* pre_message, + ProgressCallBack progressFunc) { + //we do not use pre_message + //setting default val to avoid warrning + pre_message = ""; + + Flash *f = (Flash*)(this->_ioAccess); + FImage *fim = (FImage*)(imageOps._ioAccess); + + + // TODO: See getBuf effect on zebra image. + u_int8_t *data8 = (u_int8_t *) fim->getBuf(); + int image_size = fim->getBufLength(); + u_int32_t zeroes = 0; + bool is_curr_image_in_odd_chunks; + + // Update CRC. + // TODO: No support for blank guids + bool isBlankGuids = ( _burnBlankGuids || imageOps._fs2ImgInfo.ext_info.blank_guids ); + UpdateFullImageCRC(fim->getBuf(), image_size / 4, isBlankGuids); // size in dwords + + // TODO: Do we need the verify ORENK + if (!allow_nofs) { + if (!imageOps._fwImgInfo.ext_info.is_failsafe) { + return errmsg("The given image is not a failsae image"); + } + + if (_fwImgInfo.cntxLog2ChunkSize != imageOps._fwImgInfo.cntxLog2ChunkSize) { + return errmsg("Failsafe chunk sizes in flash (0x%x) and in image (0x%x) are not the same.", + 1 << _fwImgInfo.cntxLog2ChunkSize, + 1 << imageOps._fwImgInfo.cntxLog2ChunkSize); + } + } + + u_int32_t max_image_size; + if (!GetMaxImageSize(f->get_size(), imageOps._fwImgInfo.ext_info.is_failsafe,\ + imageOps._fs2ImgInfo.ext_info.config_sectors, max_image_size)) { + return false; + } + //printf("-D- max image size : %d, image_size : %d\n",max_image_size, imageOps._fwImgInfo.ext_info.image_size); + // Check if size of image is OK + if (imageOps._fwImgInfo.ext_info.image_size > max_image_size) { + const char *image_type = (imageOps._fwImgInfo.ext_info.is_failsafe) ? "failsafe" : "non-failsafe"; + const char *note_str = (imageOps._fwImgInfo.ext_info.is_failsafe) ? " - half of total flash size" : " - total flash size"; + + return errmsg("Size of %s image (0x%x) is greater than max %s image size (0x%x%s)", + image_type, imageOps._fwImgInfo.ext_info.image_size, image_type, max_image_size, note_str); + + } + + u_int32_t new_image_start; + + if (_fwImgInfo.imgStart != 0) { + is_curr_image_in_odd_chunks = 1; + new_image_start = 0; + } else { + is_curr_image_in_odd_chunks = 0; + new_image_start = (1 << imageOps._fwImgInfo.cntxLog2ChunkSize); + } + + + if (imageOps._fwImgInfo.ext_info.is_failsafe) { + f->set_address_convertor(imageOps._fwImgInfo.cntxLog2ChunkSize, !is_curr_image_in_odd_chunks); + } else { + f->set_address_convertor(0,0); + new_image_start = 0; + } + + // Go ahead and burn! + //const char* image_name = new_image_start == 0 ? "first" : "second"; + if (!writeImage(progressFunc, 16 , data8 + 16, image_size - 16)) { + return false; + } + // Write new signature + if (!f->write(0, data8, 16, true)) { + //return false; + return errmsg("Flash write failed. %s", f->err()); + } + bool boot_address_was_updated = true; + // Write new image start address to crspace (for SW reset) + if (!f->update_boot_addr(new_image_start)) { + boot_address_was_updated = false; + } + + if (imageOps._fwImgInfo.ext_info.is_failsafe) { + if (allow_nofs) { + // When burning in nofs, remnant of older image with different chunk size + // may reside on the flash - + // Invalidate all images marking on flash except the one we've just burnt + + u_int32_t cntx_image_start[CNTX_START_POS_SIZE]; + u_int32_t cntx_image_num; + u_int32_t i; + + CntxFindAllImageStart(_ioAccess, cntx_image_start, &cntx_image_num); + // Address convertor is disabled now - use phys addresses + for (i = 0; i < cntx_image_num; i++) { + if (cntx_image_start[i] != new_image_start) { + if (!f->write(cntx_image_start[i], &zeroes, sizeof(zeroes), true)) { + //return false; + return errmsg("Flash write failed. %s", f->err()); + } + } + } + } else { + // invalidate previous signature + f->set_address_convertor(imageOps._fwImgInfo.cntxLog2ChunkSize, is_curr_image_in_odd_chunks); + if (!f->write(0, &zeroes, sizeof(zeroes), true)) { + //return false; + return errmsg("Flash write failed. %s", f->err()); + } + } + } + if (boot_address_was_updated == false) { + report_warn("Failed to update FW boot address. Power cycle the device in order to load the new FW.\n"); + } + + return true; +} + + +bool Fs2Operations::preFS2PatchGUIDs(bool patch_macs, + bool patch_uids, + bool user_guids, + bool user_macs, + bool user_uids, + guid_t new_guids[MAX_GUIDS], + guid_t old_guids[MAX_GUIDS], + guid_t **used_guids_p, + u_int32_t num_of_old_guids) +{ + int i; + guid_t* used_guids; + *used_guids_p = old_guids ? old_guids : new_guids; + + if (new_guids) { + // if only guids or only macs are specified by user, keep the other + // as currently set of flash. This is in order to simplify transitions between + // burning IB and ETH FW. + if (!patch_uids) { + if (old_guids && !user_guids) { + for (i = 0; i < GUIDS; i++) { + new_guids[i] = old_guids[i]; + } + } + + if (old_guids && !user_macs) { + for (i = GUIDS; i < MAX_GUIDS; i++) { + new_guids[i] = old_guids[i]; + } + } + } + *used_guids_p = new_guids; + } + used_guids = *used_guids_p; + + if (!patch_uids) { + if (patch_macs) { + + // To ease upgrade from 4 GUIDS format to 4+2 format, or to move from IB to ETH, + // if macs are not + // explicitly set in flash, they are derived from the GUIDs according to + // Mellanox methodology - 48 bit MAC == 64 bit GUID without the middle 16 bits. + + if (old_guids && ((num_of_old_guids == 4) || + (num_of_old_guids == 6 && + (old_guids[GUIDS ].h & 0xffff) == 0xffff && + (old_guids[GUIDS ].l & 0xffffffff) == 0xffffffff && + (old_guids[GUIDS+1].h & 0xffff) == 0xffff && + (old_guids[GUIDS+1].l & 0xffffffff) == 0xffffffff))) { + for (i = 0 ; i < MACS; i++) { + u_int64_t mac = old_guids[i+1].h >> 8; + mac <<= 24; + mac |= (old_guids[i+1].l & 0xffffff); + + old_guids[GUIDS+i].h = u_int32_t(mac >> 32); + old_guids[GUIDS+i].l = u_int32_t(mac & 0xffffffff); + + // printf("-D- Guid " GUID_FORMAT " to MAC "MAC_FORMAT"\n", old_guids[i+1].h, old_guids[i+1].l, old_guids[i+GUIDS].h,old_guids[i+GUIDS].l ); + } + } + + guid_t* macs = &used_guids[4]; + int i; + + for (i = 0 ; i < MACS ; i++) { + u_int64_t mac = (((u_int64_t)macs[i].h) << 32) | macs[i].l; + if (!_burnBlankGuids && !CheckMac(mac)) { + return errmsg("Bad mac (" MAC_FORMAT ") %s: %s. Please re-burn with a valid -mac flag value.", macs[i].h, + macs[i].l, + user_macs ? "given" : "found on flash", err()); + } + + } + } + } else { + if (!_burnBlankGuids) { + for (i = 0; i < BX_SLICES_NUM; i++ ) { + if (CheckBxMacsFormat(used_guids, i, user_uids) == false) { + return false; + } + } + } + + } + // Avoid warnings + user_uids = true; + + return true; +} + + +bool Fs2Operations::CheckBxMacsFormat(guid_t* guids, int index, int user_uids) +{ + int i, base; + base = index * BX_SLICE_GUIDS + BI_IMACS; + for (i = base; i < base + BX_MACS; i++) { + u_int64_t mac = (((u_int64_t)guids[i].h) << 32) | guids[i].l; + if (!CheckMac(mac)) { + return errmsg("Bad mac (" MAC_FORMAT ") %s: %s. Please re-burn with a valid MACs flag value.", guids[i].h, + guids[i].l, + user_uids ? "given" : "found on flash", err()); + + } + } + return true; +} + +//////////////////////////////////////////////////////////////////////// +void Fs2Operations::patchGUIDsSection(u_int32_t *buf, u_int32_t ind, guid_t guids[MAX_GUIDS], int nguids) +{ + u_int32_t i; + u_int32_t new_buf[MAX_GUIDS*2]; + + // Form new GUID section + for (i=0; i<(u_int32_t)nguids; i++) { + new_buf[i*2] = guids[i].h; + new_buf[i*2+1] = guids[i].l; + } + + // Patch GUIDs + for (i=0; igetBuf(); + + // Call common function + if (!preFS2PatchGUIDs(patch_macs, patch_uids, user_guids, user_macs, user_uids, new_guids, old_guids, &used_guids, num_of_old_guids)) { + return false; + } + // Path GUIDs section + if (imageOps._fs2ImgInfo.guidPtr) { + patchGUIDsSection(buf, imageOps._fwImgInfo.imgStart + imageOps._fs2ImgInfo.guidPtr, used_guids, imageOps._fs2ImgInfo.ext_info.guid_num); + } + + + // Avoid warnings + user_uids = true; + return true; +} + +void Fs2Operations::PatchInfoSect(u_int8_t* rawSect, u_int32_t vsdOffs, const char* vsd) +{ + + u_int32_t vsdSize = __be32_to_cpu(*((u_int32_t*)(rawSect + sizeof(GPH) + vsdOffs - 4))) & 0xffffff; + u_int32_t infoSize = __be32_to_cpu(*((u_int32_t*)(rawSect + 4))); + + // byte size; + infoSize *= 4; + + if (vsd) { + u_int32_t len = strlen(vsd); + + if (len > vsdSize) { + report_warn("The given VSD length is too large (%d chars). Truncating to %d chars.\n", len, vsdSize); + len = vsdSize; + } + + memset(rawSect + sizeof(GPH) + vsdOffs, 0, vsdSize ); + memcpy(rawSect + sizeof(GPH) + vsdOffs, vsd, len); + } + + recalcSectionCrc(rawSect, sizeof(GPH) + infoSize); +} + + +bool Fs2Operations::patchImageVsd(Fs2Operations &imgFwOps, char* userVsd) +{ + u_int32_t *imgBuf = ((FImage*)(imgFwOps._ioAccess))->getBuf(); + u_int8_t *imgInfoSect = (u_int8_t*)imgBuf + imgFwOps._fs2ImgInfo.infoSectPtr - sizeof(GPH); + const char* vsdToUse = (userVsd && ( strlen(userVsd) <= VSD_LEN )) ? userVsd : (const char*)(this->_fwImgInfo.ext_info.vsd); + PatchInfoSect(imgInfoSect, imgFwOps._fs2ImgInfo.infoOffs[II_VSD], vsdToUse); + return true; +} + +/*********************************************************/ + + +#define GUID_PTR_OFF 0x34 +#define IMAGE_INFO_PTR 0x2c +#define IMAGE_SIZE_OFF 0x30 +#define IMAGE_ROM_INDEX 2 +#define CRC_SECT_SIZE 4 +#define TOTAL_SEC_SIZE(data_size) (data_size + sizeof(GPH) + CRC_SECT_SIZE) +#define COPY_DW(dest, dword) {\ + CPUTO1(dword);\ + memcpy(dest, &dword, 4);\ +} + +#define READ_DW(dw, data) {\ + dw = (*((u_int32_t*)(data)));\ + TOCPU1(dw);\ +} + + +bool Fs2Operations::CopyData(u_int8_t* &new_image, u_int8_t* &old_image, int copy_size) +{ + memcpy(new_image, old_image, copy_size); + + new_image += copy_size; + old_image += copy_size; + + return true; +} + + + +bool Fs2Operations::CopyBoot2(u_int8_t* &new_image_p, u_int8_t* &old_image_p) +{ + u_int32_t size; + READ_DW(size, old_image_p + 4); + size = (size + 4) * 4; + CopyData(new_image_p, old_image_p, size); + return true; +} + +bool Fs2Operations::AddNewSect(u_int8_t* &new_image_p, u_int8_t* data, GPH gph, u_int32_t* last_next) +{ + + int size = gph.size * 4 ; + + *last_next = gph.next + sizeof(GPH); + + CPUTOBY(gph); + + // Copy the GPH + memcpy(new_image_p, (u_int8_t*)&gph, sizeof(GPH)); + + // Copy the data + memcpy(new_image_p + sizeof(GPH), data, size); + + // Calc the CRC and copy it + recalcSectionCrc(new_image_p, sizeof(GPH) + size); + + new_image_p = new_image_p + TOTAL_SEC_SIZE(size); + return true; +} +bool Fs2Operations::UpdateRomInImage(u_int8_t* new_image, u_int8_t* old_image, u_int8_t* rom_data, int rom_size, + int* new_image_size) +{ + GPH gph; + u_int32_t header; + u_int32_t next_ptr, last_next; + + u_int8_t *new_image_p, *old_image_p; + new_image_p = new_image; + old_image_p = old_image; + + // Copy first section + CopyData(new_image_p, old_image_p, FS2_BOOT_START); + + //// Read BOOT2 + CopyBoot2(new_image_p, old_image_p); + + READ_DW(header, old_image_p); + + if (header < H_FIRST || header >= H_LAST) { + CopyBoot2(new_image_p, old_image_p); + } + next_ptr = old_image_p - old_image; + + last_next = next_ptr + sizeof(GPH); + int sect_index = 0, rom_inserted = 0; + + // In this case we need to remove the ROM. + if (rom_data == NULL) { + rom_inserted = 1; + } + + while (next_ptr && next_ptr != 0xff000000) { + u_int8_t* old_section = old_image + next_ptr; + gph = (*(GPH*)(old_section)); + TOCPUBY(gph); + u_int32_t new_image_index = (new_image_p - new_image); + sect_index++; + //printf("-D- new_image_index = %#x, next_ptr = %#x\n", new_image_index, next_ptr); + next_ptr = gph.next; + u_int8_t* data; + + //printf("-D- Before GPH: type = %#x, size = %#x, next = %#x, param = %#x\n", gph.type, gph.size, gph.next, gph.param); + + if (!rom_inserted && (sect_index == IMAGE_ROM_INDEX || gph.type == H_ROM)) { + // prepare new ROM. + GPH new_gph; + int rom_whole_size = TOTAL_SEC_SIZE(rom_size); + + data = rom_data; + new_gph.size = rom_size / 4; + new_gph.next = new_image_index + rom_whole_size; + new_gph.param = 0; + new_gph.type = H_ROM; + + AddNewSect(new_image_p, data, new_gph, &last_next); + + rom_inserted = 1; + } + // If this section is ROM section we will ignore it. + if (gph.type == H_ROM) { + continue; + } + + new_image_index = (new_image_p - new_image); + data = old_section + sizeof(GPH); + if (gph.next != 0xff000000) { + gph.next = new_image_index + TOTAL_SEC_SIZE(gph.size * 4); + } + + if (gph.type == H_GUID) { + COPY_DW(new_image + GUID_PTR_OFF, last_next); + } else if (gph.type == H_IMG_INFO) { + u_int32_ba a = last_next; + u_int32_t check_sum = 0; + int i; + for (i = 0; i < 3; i++) { + check_sum += a.range(i * 8 + 7, i * 8); + } + check_sum = 0x100 - (check_sum % 0x100); + a.range(31, 24) = check_sum; + last_next = u_int32_t(a); + COPY_DW(new_image + IMAGE_INFO_PTR, last_next); + } + AddNewSect(new_image_p, data, gph, &last_next); + } + // Update image size. + u_int32_t size = new_image_p - new_image; + /* TODO: reivew this, also deal with if fw is failsafe we should compare with get_size()/2 if not compare with the entire flash size + //check if size is bigger than flash + if (size >= _fwImgInfo.actuallyFailsafe ? (_ioAccess->get_size()/2) : (_ioAccess->get_size())) { + return errmsg("Rom is too big to be integrated with the FW image.(img: %d, flash: %d)", (int)size, (int)_ioAccess->get_size() ); + }*/ + + *new_image_size = size; + + COPY_DW(new_image + IMAGE_SIZE_OFF, size); + + // Writing 0 on the CRC existing field to let the tool verify the image + // and get some information which will be needed later. + u_int32_ba crc_dw = TOCPU1(*(u_int32_t*)(&new_image[IMG_CRC_OFF])); + crc_dw.range(23, 16) = 0; + (*(u_int32_t*)(&new_image[IMG_CRC_OFF])) = CPUTO1(crc_dw); + + return true; +} + + + +bool Fs2Operations::IntegrateDevRomInImage(Fs2Operations &imageOps) +{ + u_int32_t rom_size = _romSect.size(); + FImage* fim = (FImage*)(imageOps._ioAccess); + u_int32_t new_image_size = fim->getBufLength() + TOTAL_SEC_SIZE(rom_size); + vector new_data(new_image_size); + int actual_image_size; + //vector romWithEndian<> + //TOCPUn((u_int8_t*)(&_romSect[0]), rom_size/4); + + // Compine the image and the rom into new daa + if(!UpdateRomInImage((u_int8_t*)(&new_data[0]), (u_int8_t*)(fim->getBuf()), + (u_int8_t*)(&_romSect[0]), rom_size, &actual_image_size)) { + return errmsg(err()); + } + + // close old image and open new image with the rom. + ((FImage*)(imageOps._ioAccess))->close(); + ((FImage*)(imageOps._ioAccess))->open((u_int32_t*)(&new_data[0]), actual_image_size); + + + if (!imageOps.FwVerify(NULL) || !imageOps.Fs2IntQuery()) { + return errmsg("Internal error: verify/query of image after integrating ROM failed\n"); + } + + return true; +} +/********************************************************************/ + +bool Fs2Operations::Fs2Burn(Fs2Operations &imageOps, ExtBurnParams& burnParams) +{ + if (imageOps.FwType() != FIT_FS2) { + return errmsg("FW image type is not FS2\n"); + } + + if (!imageOps.Fs2IntQuery()) { + return false; + } + + bool devIntQueryRes = Fs2IntQuery(); + + if (!devIntQueryRes && burnParams.burnFailsafe) { + return errmsg("%s, burn cannot be failsafe." , err()); + } + + // Check Matching device ID + // HACK +#ifndef UEFI_BUILD // NO Device ID here.. + + if (!burnParams.noDevidCheck) { + if (imageOps._fs2ImgInfo.infoOffs[II_HwDevsId]) { + if (!CheckMatchingHwDevId(_ioAccess->get_dev_id(), + _ioAccess->get_rev_id(), + imageOps._fwImgInfo.supportedHwId, + imageOps._fwImgInfo.supportedHwIdNum)) { + return errmsg("Device/Image mismatch: %s\n",this->err( )); + } + } else if (imageOps._fs2ImgInfo.infoOffs[II_DeviceType]) { + if (!CheckMatchingDevId(_ioAccess->get_dev_id(), imageOps._fwImgInfo.ext_info.dev_type)) { + return errmsg("Device/Image mismatch: %s\n",this->err()); + } + } + + } +#endif + + // Check PSID + if (devIntQueryRes && !CheckPSID(imageOps, burnParams.allowPsidChange)) { + return false; + } + + // Check if the burnt FW version is OK + if (!CheckFwVersion(imageOps, burnParams.ignoreVersionCheck)) { + return false; + } + + // ROM patchs + if (((burnParams.burnRomOptions == ExtBurnParams::BRO_FROM_DEV_IF_EXIST) && (_fwImgInfo.ext_info.roms_info.exp_rom_found)) || // There is ROM in device and user choses ir + ((burnParams.burnRomOptions == ExtBurnParams::BRO_DEFAULT) && (!imageOps._fwImgInfo.ext_info.roms_info.exp_rom_found))) { // No ROM in image + if (!IntegrateDevRomInImage(imageOps)) { + return false; + } + } + + + + + // Guids patch + _burnBlankGuids = burnParams.blankGuids; + bool isGuidsSpecified = burnParams.userMacsSpecified || burnParams.userGuidsSpecified || + burnParams.userUidsSpecified; + if (isGuidsSpecified) { + // Get the GUIDS/MACsUIDs from the user input + bool isBridgeX = (_fwImgInfo.ext_info.chip_type == CT_BRIDGEX); + bool isMacAvailable = Fs2IsMacAvailable(); + if (!patchGUIDs(imageOps, isMacAvailable, isBridgeX, burnParams.userGuidsSpecified, burnParams.userMacsSpecified, burnParams.userUidsSpecified, + (guid_t*)(&(burnParams.userUids[0])), _fs2ImgInfo.ext_info.guids, _fs2ImgInfo.ext_info.guid_num)) { + return false; + } + } else if (!burnParams.useImageGuids) { + // Get the GUIDS/MACsUIDs from the device + if (!patchGUIDs(imageOps, true, false, false, false, false, (guid_t*)NULL, + _fs2ImgInfo.ext_info.guids, _fs2ImgInfo.ext_info.guid_num)) { + return false; + } + } + // Patch the image VSD file + if (burnParams.vsdSpecified || !burnParams.useImagePs) { + if (!patchImageVsd(imageOps, burnParams.userVsd)) { + return false; + } + } + + // TODO: EXp Rom checks - Take from flash ..?? + return Fs2FailSafeBurn(imageOps, !burnParams.burnFailsafe, "", burnParams.progressFunc); +} + + +bool Fs2Operations::Fs2IsMacAvailable() +{ + + if (_fwImgInfo.ext_info.chip_type == CT_IS4 ) { + return false; + } + return true; +} +bool Fs2Operations::FwBurn(FwOperations *imageOps, u_int8_t forceVersion, ProgressCallBack progressFunc) +{ + if (imageOps == NULL) { + return errmsg("bad parameter is given to FwBurn\n"); + } + ExtBurnParams burnParams = ExtBurnParams(); + burnParams.ignoreVersionCheck = forceVersion; + burnParams.progressFunc = progressFunc; + + return Fs2Burn((*(Fs2Operations*)imageOps), burnParams); + +} + +bool Fs2Operations::FwBurnAdvanced(FwOperations *imageOps, ExtBurnParams& burnParams) +{ + if (imageOps == NULL) { + return errmsg("bad parameter is given to FwBurnAdvanced\n"); + } + return Fs2Burn((*(Fs2Operations*)imageOps), burnParams); + +} + +bool Fs2Operations::FwBurnBlock(FwOperations *imageOps, ProgressCallBack progressFunc) +{ + FImage *fim = (FImage*)((Fs2Operations*)imageOps)->_ioAccess; + + if (imageOps == NULL) { + return errmsg("bad parameter is given to FwBurnBlock\n"); + } + + return writeImage(progressFunc, 0, fim->getBuf(), fim->getBufLength()); +} + +bool Fs2Operations::FwReadRom(std::vector& romSect) +{ + if (!Fs2IntQuery()) { + return false; + } + if (_romSect.empty()) { + return errmsg("The FW does not contain a ROM section"); + } + romSect = _romSect; + return true; +} + +bool Fs2Operations::FwSetMFG(guid_t baseGuid, PrintCallBack callBackFunc) +{ + // avoid compiler warrnings + baseGuid = (guid_t){0,0}; + callBackFunc = (PrintCallBack)NULL; + return errmsg("This command doesn not works Only over FS2 FW image."); +} + +bool Fs2Operations::FwGetSection (u_int32_t sectType, std::vector& sectInfo) +{ + if (sectType != H_FW_CONF && sectType != H_HASH_FILE) { + return errmsg("Hash File section not found in the given image."); + } + initSectToRead(sectType); + if (!Fs2Verify()) { + return false; + } + if (sectType == H_FW_CONF) { + sectInfo = _fwConfSect; + } else { + sectInfo = _hashFileSect; + } + if (sectInfo.empty()) { + return errmsg("Hash File section not found in the given image."); + } + return true; +} + +bool Fs2Operations::ModifyVSDSection(char *vsd, ProgressCallBack callBackFunc) +{ + u_int32_t length = _fwImgInfo.lastImageAddr; + vector data(length); + + // Read the image. + if (!_ioAccess->read(0, (u_int8_t*)(&data[0]), length)) { + return errmsg("Flash/Image read failed. %s", _ioAccess->err()); + } + // Change the VSD + PatchInfoSect((u_int8_t*)(&data[0]) + _fs2ImgInfo.infoSectPtr - sizeof(GPH), + _fs2ImgInfo.infoOffs[II_VSD], + vsd); + // Re-burn the new Image after modifying the VSD + return ReburnNewImage((u_int8_t*)(&data[0]), (char*)"VSD", callBackFunc); +} + +bool Fs2Operations::ReburnNewImage(u_int8_t *data, char *feature_name, ProgressCallBack callBackFunc) +{ + u_int32_t length = _fwImgInfo.lastImageAddr; + //char burn_str[100]; + bool is_image = (_fname != NULL); + bool needs_repack = (is_image && _fwImgInfo.actuallyFailsafe); + + // Burn the Image after modifying the VSD. + + // Create a fwOperations object of the modified image + FwOperations* newOps = FwOperationsCreate((void*)data, (void*)&length, (char*)NULL, FHT_FW_BUFF, (char*)NULL, (int)NULL); + + // Verify the new image and exit if it's not VALID. + if (!((Fs2Operations*)newOps)->Fs2IntQuery()) { + return errmsg("Internal error: The prepared image After modifying the %s is corrupted: %s\n", feature_name, newOps->err()); + } + if (!is_image) { + // Modify the flash + if (!Fs2FailSafeBurn(*((Fs2Operations*)newOps), true, NULL, callBackFunc)) { + return false; + } + } else { + u_int8_t *striped_data = new u_int8_t[length * 2]; + u_int32_t striped_length; + + // Modify the image. + // Update the Full image CRC. + UpdateFullImageCRC((u_int32_t*)data, length / 4, false); + + // Re-pack the image as it was given. + // When it was striped this function would return it to that case. + packStripedImageData(striped_data, data, length, striped_length, needs_repack, _fwImgInfo.cntxLog2ChunkSize); + + // Re-write the image to the file. + if (!WriteImageToFile(_fname, striped_data, striped_length)) { + return false; + } + } + return true; +} + +bool Fs2Operations::packStripedImageData(u_int8_t *striped_data, u_int8_t *normal_data, u_int32_t length, u_int32_t &striped_length, + bool needs_repack, u_int32_t cntxLog2ChunkSize) +{ + if (needs_repack) { + u_int32_t chunk_size = 1 << cntxLog2ChunkSize; + u_int32_t chunk_num = (length / chunk_size) + 1; + u_int32_t i; + striped_length = 0; + + // Loop which runs over the chunks + for (i = 0; i < chunk_num; i++) { + u_int32_t normal_index = i * chunk_size; + u_int32_t striped_index = normal_index * 2; + + u_int32_t size = (length - normal_index); + u_int8_t *striped_ptr = striped_data + striped_index; + + size = (size <= chunk_size) ? size : chunk_size; + memcpy(striped_ptr, normal_data + normal_index, size); + striped_length += size; + + if (i != (chunk_num - 1)) { + // Add blank chunk after all the chunks instead the last one. + memset(striped_ptr + chunk_size, 0xff, chunk_size); + striped_length += chunk_size; + } + } + } else { + striped_length = length; + memcpy(striped_data, normal_data, length); + } + return true; + +} + +bool Fs2Operations::ModifyKeySection(guid_t access_key, ProgressCallBack callBackFunc) +{ + + u_int32_t length = _fwImgInfo.lastImageAddr; + vector data(length); + + // Read the image. + if (!_ioAccess->read(0, (u_int8_t*)(&data[0]), length)) { + return errmsg("Flash/Image read failed. %s\n", _ioAccess->err()); + } + + // Change the VSD + PatchKeySect((u_int32_t*)(&data[0] + _fs2ImgInfo.infoSectPtr - sizeof(GPH)), + _fs2ImgInfo.infoOffs[II_HwAccessKey], + access_key); + // Re-burn the new Image after modifying the VSD + return ReburnNewImage((u_int8_t*)(&data[0]), (char*)"HW Key", callBackFunc); +} + +void Fs2Operations::PatchKeySect(u_int32_t* buff, u_int32_t keyOff, guid_t hw_key) +{ + u_int32_t infoSize = __be32_to_cpu(*(buff + 1)); + u_int32_t sectSize = sizeof(GPH) + infoSize * 4; + + u_int32_t realKeyoff = (keyOff + sizeof(GPH)) / 4; + + // Update the key in the buffer which is supposed to be burnt into the flash + buff[realKeyoff] = __cpu_to_be32(hw_key.h); + buff[realKeyoff + 1] = __cpu_to_be32(hw_key.l); + + recalcSectionCrc((u_int8_t*)buff, sectSize); + return; +} + +bool Fs2Operations::ModifyGuidSection(guid_t *user_guids, ProgressCallBack progressFunc) +{ + u_int32_t length = _fwImgInfo.lastImageAddr; + vector data(length); + + // Read the image. + if (!_ioAccess->read(0, (u_int8_t*)(&data[0]), length)) { + return errmsg("Flash/Image read failed: %s\n", _ioAccess->err()); + } + // Change the GUIDs section according to the user given GUIDs + patchGUIDsSection ((u_int32_t*)(&data[0]), _fs2ImgInfo.guidPtr, user_guids, _fs2ImgInfo.ext_info.guid_num); + // Re-burn the new Image after modifying the GUIDs + return ReburnNewImage((u_int8_t*)(&data[0]), (char*)"GUIDs", progressFunc); +} + +bool Fs2Operations::Fs2SetGuidsForBlank(sg_params_t& sgParam) +{ + // There is blank GUIDs on the device (not image) + u_int32_t guid_sect_addr[2] = {0}; + u_int32_t length = _fwImgInfo.ext_info.image_size; + if (!_ioAccess->is_flash()) { + return errmsg("Image file is not supported."); + } + + + guid_sect_addr[0] = _fs2ImgInfo.guidPtr; + + for (int i = 0; i < 2 && guid_sect_addr[i]; i++ ) { + u_int32_t guid_sect[MAX_GUIDS*2 + 5]; // Save room for header + crc + + if (!_ioAccess->read(guid_sect_addr[i] - 16 , guid_sect, 16)) { + return errmsg("Failed to read guids section - flash read error (%s)\n", _ioAccess->err()); + } + // we have blank guids so make sure we have ffff in sgParams.userGuids in the correct pos + if (!sgParam.guidsSpecified) { + memset(&sgParam.userGuids[0], 0xff, (sizeof(guid_t))*GUIDS); + } + if (!sgParam.macsSpecified) { + memset(&sgParam.userGuids[GUIDS], 0xff, (sizeof(guid_t))*MACS); + } + // patchGUIDsSection(u_int32_t *buf, u_int32_t ind, guid_t guids[MAX_GUIDS], int nguids) + patchGUIDsSection (guid_sect, 16, &sgParam.userGuids[0], _fs2ImgInfo.ext_info.guid_num); + + if (!((Flash*)_ioAccess)->write(guid_sect_addr[i], guid_sect + 4 , _fs2ImgInfo.ext_info.guid_num * 8 + 4, true)) { + return errmsg("flash write error (%s)\n", _ioAccess->err()); + } + } + if (sgParam.updateCrc) { + // Read the image. + vector data(length); + + if (!_ioAccess->read(0, (u_int32_t*)(&data[0]), length)) { + return errmsg("Flash read failed: %s\n", _ioAccess->err()); + } + // TODO: Do we need to update the CRC existing ORENK + // Calc & Update CRC. + u_int32_t *new_data = (u_int32_t*)(&data[0]); + u_int32_t crc = CalcImageCRC(new_data, length / 4); + u_int32_ba old_dw = __be32_to_cpu(new_data[IMG_CRC_OFF / 4]); + old_dw.range(15, 0) = crc; + u_int32_t new_crc_dw = CPUTO1(old_dw); + + if (!((Flash*)_ioAccess)->write(IMG_CRC_OFF, &new_crc_dw, 4, true)) { + return errmsg("flash write error (%s).", _ioAccess->err()); + } + } + return true; +} + +bool Fs2Operations::Fs2SetGuids(sg_params_t& sgParam, PrintCallBack callBackFunc, ProgressCallBack progressFunc) +{ + // avoid compiler warrnings + callBackFunc = (PrintCallBack)NULL; + // + bool ib_dev, eth_dev, bx_dev; + // Get the FW types + bx_dev = _fwImgInfo.ext_info.chip_type == CT_BRIDGEX; + SetDevFlags(_fwImgInfo.ext_info.chip_type, _fwImgInfo.ext_info.dev_type, FIT_FS2, ib_dev, eth_dev); + guid_t* old_guids = _fwImgInfo.imageOk ? _fs2ImgInfo.ext_info.guids : NULL; + guid_t* used_guids; + + // Patch the GUIDs and prints any needed warnings + + //resize our user guids vector to MAX_GUIDS + sgParam.userGuids.resize(MAX_GUIDS); + + if (!preFS2PatchGUIDs(eth_dev, bx_dev, sgParam.guidsSpecified, sgParam.macsSpecified, sgParam.uidsSpecified, &sgParam.userGuids[0], + old_guids, &used_guids, _fs2ImgInfo.ext_info.guid_num)) { + return false; + } + + // Modify the guids in the burnt image and re-burn it + if (!ModifyGuidSection(used_guids, progressFunc)) { + return false; + } + return true; +} + +bool Fs2Operations::FwSetGuids(sg_params_t& sgParam, PrintCallBack callBackFunc, + ProgressCallBack progressFunc) +{ + if (!Fs2IntQuery(true, sgParam.stripedImage)) { + return false; + } + if (sgParam.userGuids.size() != MAX_GUIDS) { + return errmsg("invalid userGuid vector size given in sgParams."); + } + if (_fs2ImgInfo.ext_info.blank_guids) { + return Fs2SetGuidsForBlank(sgParam); + } + return Fs2SetGuids(sgParam, callBackFunc, progressFunc); +} + + +bool Fs2Operations::FwBurnRom(FImage* romImg, bool ignoreProdIdCheck, bool ignoreDevidCheck, ProgressCallBack progressFunc) +{ + // we dont support adding rom to an image just yet + if (!_ioAccess->is_flash()) { + return errmsg("Burn ROM not supported for FS2 image."); + } + //make sure we dont get fwImage instead of rom file + + u_int32_t cntx_image_start[CNTX_START_POS_SIZE]; + u_int32_t cntx_image_num; + CntxFindAllImageStart(romImg, cntx_image_start, &cntx_image_num); + if (cntx_image_num != 0) { + return errmsg("Expecting an expansion ROM image, Recieved Mellanox FW image."); + } + + if (!Fs2IntQuery()) { + return false; + } + + if (_fwImgInfo.ext_info.chip_type != CT_CONNECTX) { + // TODO: Indicate the device name. + return errmsg("Unsupported device type %d", _fwImgInfo.ext_info.dev_type); + } + + if (_romSect.empty() && !IsFwSupportingRomModify(_fwImgInfo.ext_info.fw_ver)) { + return errmsg("It is not allowed to burn ROM on device which has fw: %d.%d.%d that doesn't contain ROM.", _fwImgInfo.ext_info.fw_ver[0], + _fwImgInfo.ext_info.fw_ver[1], _fwImgInfo.ext_info.fw_ver[2]); + } + + if (!ignoreProdIdCheck && _fs2ImgInfo.infoOffs[II_ProductVer]) { + return errmsg("The device FW contains common FW/ROM Product Version - The ROM cannot be updated separately."); + } + u_int32_t length = _fwImgInfo.lastImageAddr; + u_int32_t new_data_size = length + TOTAL_SEC_SIZE(romImg->getBufLength()); + vector data(length); + vector new_data(new_data_size); + + // Read the image. + if (!_ioAccess->read(0, (u_int8_t*)(&data[0]), length)) { + return errmsg("Flash read failed: %s", _ioAccess->err()); + } + + u_int32_t new_image_size; + + // Insert the rom to the image. + if(!UpdateRomInImage((u_int8_t*)(&new_data[0]), (u_int8_t*)(&data[0]), + (u_int8_t*)romImg->getBuf(), romImg->getBufLength(), + (int*)&new_image_size)) { + return false; + } + // open the image + FwOperations* newOps = FwOperationsCreate((void*)&new_data[0], (void*)&new_image_size, (char*)NULL, FHT_FW_BUFF, (char*)NULL, (int)NULL); + if (!newOps) { + return errmsg("Internal error: The prepared image is corrupted."); + } + + if (!((Fs2Operations*)newOps)->Fs2Verify((VerifyCallBack)NULL,false, false, false, true) || !((Fs2Operations*)newOps)->Fs2Query()) { + errmsg("Internal error: The prepared image is corrupted: %s", newOps->err()); + newOps->FwCleanUp(); + delete newOps; + return false; + } + // init fw_info_t struct for checkMatchingExpRomDevId + fw_info_t info; + info.fw_type = FIT_FS2; + info.fw_info = ((Fs2Operations*)newOps)->_fwImgInfo.ext_info; + //no need to init the fs2_info part of fw_info_t as the function doesnt use it. + + if (!ignoreDevidCheck && !FwOperations::checkMatchingExpRomDevId(info)) { + errmsg("Image file ROM: FW is for device %d, but Exp-ROM is for device %d\n", ((Fs2Operations*)newOps)->_fwImgInfo.ext_info.dev_type,\ + ((Fs2Operations*)newOps)->_fwImgInfo.ext_info.roms_info.exp_rom_com_devid); + newOps->FwCleanUp(); + delete newOps; + return false; + } + + bool rc = Fs2FailSafeBurn(*((Fs2Operations*)newOps), true, "Burning ROM image", progressFunc); + newOps->FwCleanUp(); + delete newOps; + return rc; +} + +bool Fs2Operations::FwDeleteRom(bool ignoreProdIdCheck, ProgressCallBack progressFunc) +{ + // we dont support delete rom in FS2 image yet + if (!_ioAccess->is_flash()) { + return errmsg("Delete ROM not supported for FS2 image."); + } + // Verify to get some parameters + if (!Fs2IntQuery()) { + return false; + } + + if (_fwImgInfo.ext_info.chip_type != CT_CONNECTX) { + // TODO: Indicate the device name. + return errmsg("Unsupported device type %d", _fwImgInfo.ext_info.dev_type); + } + if (_romSect.empty()) { + return errmsg("The FW does not contain a ROM section."); + } + + if (!IsFwSupportingRomModify(_fwImgInfo.ext_info.fw_ver)) { + return errmsg("Unsupported Fw version (%d.%d.%d).", _fwImgInfo.ext_info.fw_ver[0], + _fwImgInfo.ext_info.fw_ver[1], _fwImgInfo.ext_info.fw_ver[2]); + } + + if (!ignoreProdIdCheck && _fs2ImgInfo.infoOffs[II_ProductVer]) { + return errmsg("The device FW contains common FW/ROM Product Version - The ROM cannot be removed separately.\n"); + } + + u_int32_t length = _fwImgInfo.lastImageAddr; + vector data(length); + vector new_data(length); + + // Read the image. + if (!_ioAccess->read(0, (u_int8_t*)(&data[0]), length)) { + return errmsg("Flash read failed: %s\n", _ioAccess->err()); + } + int new_image_size; + if(!UpdateRomInImage((u_int8_t*)(&new_data[0]), (u_int8_t*)(&data[0]), + NULL, 0, &new_image_size)) { + return errmsg(_ioAccess->err()); + } + + // Burn the Image after the ROM was removed. + FwOperations* newOps = FwOperationsCreate((void*)&new_data[0], (void*)&new_image_size, (char*)NULL, FHT_FW_BUFF, (char*)NULL, (int)NULL); + if (!newOps) { + return errmsg("Internal error: The prepared image after removing the ROM is corrupted."); + } + + // To verify the new image and exit if it's not VALID. + if (!((Fs2Operations*)newOps)->Fs2Verify((VerifyCallBack)NULL,false, false, false, true) || !((Fs2Operations*)newOps)->Fs2Query()) { + errmsg("Internal error: The prepared image after removing the ROM is corrupted: %s", newOps->err()); + newOps->FwCleanUp(); + delete newOps; + return false; + } + bool rc = Fs2FailSafeBurn(*((Fs2Operations*)newOps), true, "Removing ROM image", progressFunc); + newOps->FwCleanUp(); + delete newOps; + return rc; +} + +bool Fs2Operations::FwSetVSD(char* vsdStr, ProgressCallBack progressFunc, PrintCallBack printFunc) +{ + // avoid compiler warrnings + printFunc = (PrintCallBack)NULL; + // + if (!Fs2IntQuery()) { + return false; + } + if (_fwImgInfo.ext_info.chip_type != CT_CONNECTX) { + // TODO: Indicate the device name. + return errmsg("Unsupported device type %d", _fwImgInfo.ext_info.dev_type); + } + + if (!_fs2ImgInfo.infoOffs[II_VSD]) { + return errmsg("No info section on the image."); + } + + if (!ModifyVSDSection(vsdStr, progressFunc)) { + return false; + } + return true; +} + +bool Fs2Operations::FwSetVPD(char* vpdFileStr, PrintCallBack callBackFunc) +{ + // avoid compiler warrnings + vpdFileStr = (char*)NULL; + callBackFunc = (PrintCallBack)NULL; + return errmsg("Setting VPD is not supported in FS2 image format."); +} + +bool Fs2Operations::FwSetAccessKey(hw_key_t userKey, ProgressCallBack progressFunc) +{ + if (!Fs2IntQuery()) { + return false; + } + if (_fwImgInfo.ext_info.chip_type != CT_CONNECTX) { + // TODO: Indicate the device name. + return errmsg("Unsupported device type %d", _fwImgInfo.ext_info.dev_type); + } + + if (!_fs2ImgInfo.infoOffs[II_HwAccessKey]) { + return errmsg("The image does not support this operation."); + } + + if (!ModifyKeySection(userKey, progressFunc)) { + return false; + } + return true; + +} + + diff --git a/mlxfwops/lib/fs2_ops.h b/mlxfwops/lib/fs2_ops.h new file mode 100644 index 0000000..489d869 --- /dev/null +++ b/mlxfwops/lib/fs2_ops.h @@ -0,0 +1,155 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +#ifndef FS2_OPS_ +#define FS2_OPS_ + +#include "fw_ops.h" +#define FULL_VERIFY 0xff + + +class Fs2Operations : public FwOperations { +public: + Fs2Operations(FBase *ioAccess) : + FwOperations(ioAccess), _burnBlankGuids(false), _isFullVerify(false){}; + + virtual ~Fs2Operations() {}; + //virtual void print_type() {}; + virtual bool FwQuery(fw_info_t *fwInfo, bool readRom = true, bool isStripedImage = false); + virtual bool FwVerify(VerifyCallBack verifyCallBackFunc, bool isStripedImage = false, bool showItoc = false); + + virtual bool FwBurn(FwOperations *imageOps, u_int8_t forceVersion, ProgressCallBack progressFunc=(ProgressCallBack)NULL); + virtual bool FwBurnAdvanced(FwOperations *imageOps, ExtBurnParams& burnParams); + virtual bool FwBurnBlock(FwOperations* imageOps, ProgressCallBack progressFunc); + + virtual bool FwBurnRom(FImage* romImg, bool ignoreProdIdCheck = false, bool ignoreDevidCheck = false, + ProgressCallBack progressFunc=(ProgressCallBack)NULL); + virtual bool FwDeleteRom(bool ignoreProdIdCheck, ProgressCallBack progressFunc=(ProgressCallBack)NULL); + + // virtual bool FwSetGuids(std::vector& userGuids, std::vector& userMacs, bool updateCrc=true, PrintCallBack callBackFunc=(PrintCallBack)NULL); + virtual bool FwSetGuids(sg_params_t& sgParam, PrintCallBack callBackFunc, ProgressCallBack progressFunc); + + virtual bool FwSetMFG(guid_t baseGuid, PrintCallBack callBackFunc=(PrintCallBack)NULL); + virtual bool FwSetVSD(char* vsdStr, ProgressCallBack progressFunc=(ProgressCallBack)NULL, PrintCallBack printFunc=(PrintCallBack)NULL); + virtual bool FwSetVPD(char* vpdFileStr, PrintCallBack callBackFunc=(PrintCallBack)NULL); + virtual bool FwSetAccessKey(hw_key_t userKey, ProgressCallBack progressFunc=(ProgressCallBack)NULL); + + virtual bool FwGetSection (u_int32_t sectType, std::vector& sectInfo); + + + + virtual u_int8_t FwType(); + virtual bool FwInit(); + virtual bool FwReadData(void* image, u_int32_t* image_size); + virtual bool FwReadRom(std::vector& romSect); + virtual bool FwTest(u_int32_t *data); // Add callback print + + +private: + + enum Fs2ImageInfoTags { + II_IiFormatRevision = 0, + II_FwVersion = 1, + II_FwBuildTime = 2, + II_DeviceType = 3, + II_PSID = 4, + II_VSD = 5, + II_SuppurtedPsids = 6, + II_ProductVer = 7, + II_VsdVendorId = 8, + II_IsGa = 9, + II_HwDevsId = 10, + II_MicVersion = 11, + II_MinFitVersion = 12, + II_HwAccessKey = 13, + II_PROFILES_LIST = 14, + II_SUPPORTED_PROFS = 15, + II_CONFIG_INFO = 16, + II_TLVS_FORMAT = 17, + II_TRACER_HASH = 18, + II_ConfigArea = 19, + II_Last, // Mark the end of used tag ids + II_End = 0xff + }; + struct Fs2ImgInfo { + fs2_info_t ext_info; + u_int32_t infoOffs[II_Last]; + bool psOk; + // Configuraqtion info + std::vector profListSectZipped; + std::vector TlvFormatSectZipped; + std::vector TracerHashSectZipped; + std::vector supportedProfList; + u_int32_t defPorfile; + u_int32_t configAddr1; + u_int32_t configAddr2; + u_int32_t configSize; + bool isConfigurable; + u_int32_t infoSectPtr; + u_int32_t guidPtr; + + }; + + + bool Fs2Verify(VerifyCallBack verifyCallBackFunc = (VerifyCallBack)NULL, bool is_striped_image = false, bool both_images = false, + bool only_get_start = false, bool ignore_full_image_crc = false, bool force_no_striped_image = false); + bool Fs2Query (); + bool Fs2Burn(Fs2Operations &imageOps, ExtBurnParams& burnParams); + + + bool CntxGetFsData(u_int32_t fs_info_word, bool& fs_en, u_int32_t& log2chunk_size); + bool checkList(u_int32_t offs, u_int32_t fw_start, const char *pref, VerifyCallBack verifyCallBackFunc = (VerifyCallBack)NULL); + bool checkGen(u_int32_t beg,u_int32_t offs, u_int32_t& next, const char *pref, VerifyCallBack verifyCallBackFunc = (VerifyCallBack)NULL); + bool ParseInfoSect(u_int8_t* buff, u_int32_t byteSize); + bool Fs2IntQuery(bool readRom = true, bool isStripedImage=false); + bool GetMaxImageSize(u_int32_t flash_size, bool image_is_fs, u_int32_t imgConfigSectors, u_int32_t &max_image_size); + bool UpdateFullImageCRC(u_int32_t* buff, u_int32_t size, bool blank_guids); + bool Fs2FailSafeBurn(Fs2Operations &imageOps, bool allow_nofs, const char* pre_message, + ProgressCallBack progressFunc); + bool ModifyGuidSection(guid_t *user_guids, ProgressCallBack progressFunc=(ProgressCallBack)NULL); + bool preFS2PatchGUIDs(bool patch_macs, bool patch_uids, bool user_guids, bool user_macs, + bool user_uids, guid_t new_guids[MAX_GUIDS], guid_t old_guids[MAX_GUIDS], guid_t **used_guids_p, u_int32_t num_of_old_guids); + bool patchGUIDs (Fs2Operations& imageOps, bool patch_macs, bool patch_uids, bool user_guids, bool user_macs, bool user_uids, + guid_t new_guids[MAX_GUIDS], guid_t old_guids[MAX_GUIDS], u_int32_t num_of_old_guids); + void patchGUIDsSection(u_int32_t *buf, u_int32_t ind, guid_t guids[MAX_GUIDS], int nguids); + bool patchImageVsd(Fs2Operations &imgFwOps, char* userVsd=(char*)NULL); + void PatchInfoSect(u_int8_t* rawSect, u_int32_t vsdOffs, const char* vsd); + void initSectToRead(int imp_index); + //needed for fs2burn + bool IntegrateDevRomInImage(Fs2Operations &imgFwOps); + bool UpdateRomInImage(u_int8_t* new_image, u_int8_t* old_image, u_int8_t* rom_data, int rom_size, + int* new_image_size); + bool AddNewSect(u_int8_t* &new_image_p, u_int8_t* data, GPH gph, u_int32_t* last_next); + bool CopyBoot2(u_int8_t* &new_image_p, u_int8_t* &old_image_p); + bool CopyData(u_int8_t* &new_image, u_int8_t* &old_image, int copy_size); + + bool ModifyKeySection(guid_t access_key, ProgressCallBack callBackFunc=(ProgressCallBack)NULL); + void PatchKeySect(u_int32_t* buff, u_int32_t keyOff, guid_t hw_key); + bool Fs2IsMacAvailable(); + bool CheckBxMacsFormat(guid_t* guids, int index, int user_uids); + + bool ModifyVSDSection(char *vsd, ProgressCallBack callBackFunc=(ProgressCallBack)NULL); + bool ReburnNewImage(u_int8_t *data, char *feature_name, ProgressCallBack callBackFunc=(ProgressCallBack)NULL); + bool packStripedImageData(u_int8_t *striped_data, u_int8_t *normal_data, u_int32_t length, u_int32_t &striped_length, + bool needs_repack, u_int32_t cntxLog2ChunkSize); + bool Fs2SetGuids(sg_params_t& sgParam, PrintCallBack callBackFunc=(PrintCallBack)NULL, ProgressCallBack progressFunc=(ProgressCallBack)NULL); + bool Fs2SetGuidsForBlank(sg_params_t& sgParam); + + + Fs2ImgInfo _fs2ImgInfo; + bool _burnBlankGuids; + bool _isFullVerify; +}; + +#endif // FS2_OPS_o diff --git a/mlxfwops/lib/fs3_ops.cpp b/mlxfwops/lib/fs3_ops.cpp new file mode 100644 index 0000000..9b7772c --- /dev/null +++ b/mlxfwops/lib/fs3_ops.cpp @@ -0,0 +1,1376 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +#include + +#include "fs3_ops.h" + +#include + + +const u_int32_t Fs3Operations::_itocSignature[4] = { + ITOC_ASCII, // Ascii of "MTFW" + TOC_RAND1, // Random data + TOC_RAND2, + TOC_RAND3 +}; + +const Fs3Operations::SectionInfo Fs3Operations::_fs3SectionsInfoArr[] = { + {FS3_END, "END"}, + {FS3_ITOC, "ITOC_Header"}, + + {FS3_BOOT_CODE, "BOOT_CODE"}, + {FS3_PCI_CODE, "PCI_CODE"}, + {FS3_MAIN_CODE, "MAIN_CODE"}, + {FS3_PCIE_LINK_CODE, "PCIE_LINK_CODE"}, + {FS3_IRON_PREP_CODE, "IRON_PREP_CODE"}, + {FS3_POST_IRON_BOOT_CODE, "POST_IRON_BOOT_CODE"}, + {FS3_HW_BOOT_CFG, "HW_BOOT_CFG"}, + {FS3_HW_MAIN_CFG, "HW_MAIN_CFG"}, + {FS3_IMAGE_INFO, "IMAGE_INFO"}, + {FS3_FW_BOOT_CFG, "FW_BOOT_CFG"}, + {FS3_FW_MAIN_CFG, "FW_MAIN_CFG"}, + {FS3_ROM_CODE, "ROM_CODE"}, + {FS3_DBG_LOG_MAP, "DBG_LOG_MAP"}, + {FS3_DBG_FW_INI, "DBG_FW_INI"}, + {FS3_DBG_FW_PARAMS, "DBG_FW_PARAMS"}, + {FS3_FW_ADB, "FW_ADB"}, + + {FS3_MFG_INFO, MFG_INFO}, + {FS3_DEV_INFO, "DEV_INFO"}, + {FS3_NV_DATA, "NV_DATA"}, + {FS3_VPD_R0, "VPD_R0"}, +}; + +bool Fs3Operations::Fs3UpdateImgCache(u_int8_t *buff, u_int32_t addr, u_int32_t size) +{ + // vector::iterator it; + u_int32_t min_required_size = addr + size; + u_int32_t i; + + if (_fs3ImgInfo.imageCache.size() < min_required_size) { + _fs3ImgInfo.imageCache.resize(min_required_size); + } + for (i = 0; i < size; i++) { + _fs3ImgInfo.imageCache.at(addr + i) = buff[i]; + } + return true; +} + +bool Fs3Operations::UpdateImgCache(u_int8_t *buff, u_int32_t addr, u_int32_t size) +{ + return Fs3UpdateImgCache(buff, addr, size); +} + +const char *Fs3Operations::GetSectionNameByType(u_int8_t section_type) { + + for (u_int32_t i = 0; i < ARR_SIZE(_fs3SectionsInfoArr); i++) { + const SectionInfo *sect_info = &_fs3SectionsInfoArr[i]; + if (sect_info->type == section_type) { + return sect_info->name; + } + } + return UNKNOWN_SECTION; +} + +bool Fs3Operations::DumpFs3CRCCheck(u_int8_t sect_type, u_int32_t sect_addr, u_int32_t sect_size, u_int32_t crc_act, + u_int32_t crc_exp, bool ignore_crc, VerifyCallBack verifyCallBackFunc) +{ + char pr[256]; + const char *sect_type_str = GetSectionNameByType(sect_type); + sprintf(pr, CRC_CHECK_OLD, PRE_CRC_OUTPUT, sect_addr, sect_addr + sect_size - 1, sect_size, + sect_type_str); + if (!strcmp(sect_type_str, UNKNOWN_SECTION)) { + sprintf(pr + strlen(pr), ":0x%x", sect_type); + } + sprintf(pr + strlen(pr), ")"); + return CheckAndPrintCrcRes(pr, 0, sect_addr, crc_exp, crc_act, ignore_crc, verifyCallBackFunc); + +} + +bool Fs3Operations::CheckTocSignature(struct cibfw_itoc_header *itoc_header, u_int32_t first_signature) +{ + if ( itoc_header->signature0 != first_signature || + itoc_header->signature1 != TOC_RAND1 || + itoc_header->signature2 != TOC_RAND2 || + itoc_header->signature3 != TOC_RAND3) { + return false; + } + return true; +} + +#define CHECK_UID_STRUCTS_SIZE(uids_context, cibfw_guids_context) {\ + if (sizeof(uids_context) != sizeof(cibfw_guids_context)) {\ + return errmsg("Internal error: Size of uids_t (%d) is not equal to size of struct cibfw_guids guids (%d)\n",\ + (int)sizeof(uids_context), (int)sizeof(cibfw_guids_context));\ + }\ +} +bool Fs3Operations::GetMfgInfo(u_int8_t *buff) +{ + struct cibfw_mfg_info mfg_info; + cibfw_mfg_info_unpack(&mfg_info, buff); + // cibfw_mfg_info_dump(&mfg_info, stdout); + + CHECK_UID_STRUCTS_SIZE(_fs3ImgInfo.ext_info.orig_fs3_uids_info, mfg_info.guids); + memcpy(&_fs3ImgInfo.ext_info.orig_fs3_uids_info, &mfg_info.guids, sizeof(mfg_info.guids)); + strcpy(_fs3ImgInfo.ext_info.orig_psid, mfg_info.psid); + + _fs3ImgInfo.ext_info.guids_override_en = mfg_info.guids_override_en; + return true; + +} + +bool Fs3Operations::GetImageInfo(u_int8_t *buff) +{ + + struct cibfw_image_info image_info; + cibfw_image_info_unpack(&image_info, buff); + // cibfw_image_info_dump(&image_info, stdout); + + _fwImgInfo.ext_info.fw_ver[0] = image_info.FW_VERSION.MAJOR; + _fwImgInfo.ext_info.fw_ver[1] = image_info.FW_VERSION.MINOR; + _fwImgInfo.ext_info.fw_ver[2] = image_info.FW_VERSION.SUBMINOR; + + _fwImgInfo.ext_info.mic_ver[0] = image_info.mic_version.MAJOR; + _fwImgInfo.ext_info.mic_ver[1] = image_info.mic_version.MINOR; + _fwImgInfo.ext_info.mic_ver[2] = image_info.mic_version.SUBMINOR; + + + strcpy(_fs3ImgInfo.ext_info.image_vsd, image_info.vsd); + strcpy(_fwImgInfo.ext_info.psid, image_info.psid); + strcpy(_fwImgInfo.ext_info.product_ver, image_info.prod_ver); + return true; +} + +bool Fs3Operations::GetDevInfo(u_int8_t *buff) +{ + struct cibfw_device_info dev_info; + cibfw_device_info_unpack(&dev_info, buff); + // cibfw_device_info_dump(&dev_info, stdout); + + CHECK_UID_STRUCTS_SIZE(_fs3ImgInfo.ext_info.fs3_uids_info, dev_info.guids); + memcpy(&_fs3ImgInfo.ext_info.fs3_uids_info, &dev_info.guids, sizeof(dev_info.guids)); + strcpy(_fwImgInfo.ext_info.vsd, dev_info.vsd); + _fwImgInfo.ext_info.vsd_sect_found = true; + return true; +} + + + + +bool Fs3Operations::GetImageInfoFromSection(u_int8_t *buff, u_int8_t sect_type, u_int8_t check_support_only) +{ + #define EXEC_GET_INFO_OR_GET_SUPPORT(get_info_func, buff, check_support_only) (check_support_only) ? true : get_info_func(buff); + + switch (sect_type) { + case FS3_MFG_INFO: + return EXEC_GET_INFO_OR_GET_SUPPORT(GetMfgInfo, buff, check_support_only); + case FS3_IMAGE_INFO: + return EXEC_GET_INFO_OR_GET_SUPPORT(GetImageInfo, buff, check_support_only); + case FS3_DEV_INFO: + return EXEC_GET_INFO_OR_GET_SUPPORT(GetDevInfo, buff, check_support_only); + } + + if (check_support_only) { + return false; + } + return errmsg("Getting info from section type (%s:%d) is not supported\n", GetSectionNameByType(sect_type), sect_type); +} + +bool Fs3Operations::IsGetInfoSupported(u_int8_t sect_type) +{ + return GetImageInfoFromSection((u_int8_t*)NULL, sect_type, 1); +} + +bool Fs3Operations::IsFs3SectionReadable(u_int8_t type, QueryOptions queryOptions) +{ + //printf("-D- readSectList.size %d\n", (int) _readSectList.size()); + if (_readSectList.size()) { + for (u_int32_t i = 0; i < _readSectList.size(); i++) { + if (_readSectList.at(i) == type) { + return true; + } + } + return false; + + } else if (queryOptions.quickQuery) { + // TODO: FS3_ROM_CODE , should be part of IsGetInfoSupported .. + if ( IsGetInfoSupported(type) || type == FS3_ROM_CODE) { + return true; + } + return false; + } + return true; +} + +bool Fs3Operations::VerifyTOC(u_int32_t dtoc_addr, bool& bad_signature, VerifyCallBack verifyCallBackFunc, bool show_itoc, + struct QueryOptions queryOptions) +{ + u_int8_t buffer[TOC_HEADER_SIZE], entry_buffer[TOC_ENTRY_SIZE]; + struct cibfw_itoc_header itoc_header; + bool ret_val = true, mfg_exists = false; + u_int8_t toc_type = FS3_ITOC; + u_int32_t phys_addr; + bad_signature = false; + + + // Read the sigmature and check it + READBUF((*_ioAccess), dtoc_addr, buffer, TOC_HEADER_SIZE, "TOC Header"); + Fs3UpdateImgCache(buffer, dtoc_addr, TOC_HEADER_SIZE); + cibfw_itoc_header_unpack(&itoc_header, buffer); + memcpy(_fs3ImgInfo.itocHeader, buffer, CIBFW_ITOC_HEADER_SIZE); + // cibfw_itoc_header_dump(&itoc_header, stdout); + u_int32_t first_signature = (toc_type == FS3_ITOC) ? ITOC_ASCII : DTOC_ASCII; + if (!CheckTocSignature(&itoc_header, first_signature)) { + bad_signature = true; + return false; + } + u_int32_t toc_crc = CalcImageCRC((u_int32_t*)buffer, (TOC_HEADER_SIZE / 4) - 1); + phys_addr = _ioAccess->get_phys_from_cont(dtoc_addr, _fwImgInfo.cntxLog2ChunkSize, _fwImgInfo.imgStart != 0); + if (!DumpFs3CRCCheck(toc_type, phys_addr, TOC_HEADER_SIZE, toc_crc, itoc_header.itoc_entry_crc,false,verifyCallBackFunc)) { + ret_val = false; + } + _fs3ImgInfo.itocAddr = dtoc_addr; + + int section_index = 0; + struct cibfw_itoc_entry toc_entry; + + do { + // Uopdate the cont address + _ioAccess->set_address_convertor(_fwImgInfo.cntxLog2ChunkSize, _fwImgInfo.imgStart != 0); + u_int32_t entry_addr = dtoc_addr + TOC_HEADER_SIZE + section_index * TOC_ENTRY_SIZE; + READBUF((*_ioAccess), entry_addr , entry_buffer, TOC_ENTRY_SIZE, "TOC Entry"); + Fs3UpdateImgCache(entry_buffer, entry_addr, TOC_ENTRY_SIZE); + + cibfw_itoc_entry_unpack(&toc_entry, entry_buffer); + if (toc_entry.type == FS3_MFG_INFO) { + mfg_exists = true; + } + // printf("-D- toc = %#x, toc_entry.type = %#x\n", section_index, toc_entry.type); + if (toc_entry.type != FS3_END) { + if (section_index + 1 >= MAX_TOCS_NUM) { + return errmsg("Internal error: number of ITOCs %d is greater than allowed %d", section_index + 1, MAX_TOCS_NUM); + } + + u_int32_t entry_crc = CalcImageCRC((u_int32_t*)entry_buffer, (TOC_ENTRY_SIZE / 4) - 1); + u_int32_t entry_size_in_bytes = toc_entry.size * 4; + //printf("-D- entry_crc = %#x, toc_entry.itoc_entry_crc = %#x\n", entry_crc, toc_entry.itoc_entry_crc); + + if (toc_entry.itoc_entry_crc == entry_crc) { + // Update last image address + u_int32_t section_last_addr; + u_int32_t flash_addr = toc_entry.flash_addr << 2; + if (!toc_entry.relative_addr) { + _ioAccess->set_address_convertor(0, 0); + phys_addr = flash_addr; + _fs3ImgInfo.smallestAbsAddr = (_fs3ImgInfo.smallestAbsAddr < flash_addr && _fs3ImgInfo.smallestAbsAddr > 0) + ? _fs3ImgInfo.smallestAbsAddr : flash_addr; + } else { + phys_addr = _ioAccess->get_phys_from_cont(flash_addr, _fwImgInfo.cntxLog2ChunkSize, _fwImgInfo.imgStart != 0); + u_int32_t currSizeOfImgdata = phys_addr + entry_size_in_bytes; + _fs3ImgInfo.sizeOfImgData = (_fs3ImgInfo.sizeOfImgData > currSizeOfImgdata) ? _fs3ImgInfo.sizeOfImgData : phys_addr; + } + section_last_addr = phys_addr + entry_size_in_bytes; + _fwImgInfo.lastImageAddr = (_fwImgInfo.lastImageAddr >= phys_addr + section_last_addr) ? _fwImgInfo.lastImageAddr : section_last_addr; + + if (IsFs3SectionReadable(toc_entry.type, queryOptions)) { + + // Only when we have full verify or the info of this section should be collected for query + std::vector buffv(entry_size_in_bytes); + u_int8_t *buff = (u_int8_t*)(&(buffv[0])); + + + if (show_itoc) { + cibfw_itoc_entry_dump(&toc_entry, stdout); + DumpFs3CRCCheck(toc_entry.type, phys_addr, entry_size_in_bytes, 0, 0, true, verifyCallBackFunc); + } else { + READBUF((*_ioAccess), flash_addr, buff, entry_size_in_bytes, "Section"); + Fs3UpdateImgCache(buff, flash_addr, entry_size_in_bytes); + u_int32_t sect_crc = CalcImageCRC((u_int32_t*)buff, toc_entry.size); + + //printf("-D- flash_addr: %#x, toc_entry_size = %#x, actual sect = %#x, from itoc: %#x\n", flash_addr, toc_entry.size, sect_crc, + // toc_entry.section_crc); + if (!DumpFs3CRCCheck(toc_entry.type, phys_addr, entry_size_in_bytes, sect_crc, toc_entry.section_crc, false, verifyCallBackFunc)) { + ret_val = false; + } else { + //printf("-D- toc type : 0x%.8x\n" , toc_entry.type); + GetSectData(_fs3ImgInfo.tocArr[section_index].section_data, (u_int32_t*)buff, toc_entry.size * 4); + if (IsGetInfoSupported(toc_entry.type)) { + if (!GetImageInfoFromSection(buff, toc_entry.type)) { + return errmsg("Failed to get info from section %d", toc_entry.type); + } + } else if (toc_entry.type == FS3_DBG_LOG_MAP) { + TOCPUn(buff, toc_entry.size); + GetSectData(_fwConfSect, (u_int32_t*)buff, toc_entry.size * 4); + } else if (toc_entry.type == FS3_ROM_CODE) { + // TODO: Need to put the ROM is part of GetImageInfoFromSection function not alone + + TOCPUn(buff, toc_entry.size); + GetSectData(_romSect, (u_int32_t*)buff, toc_entry.size * 4); + RomInfo rInfo(_romSect); + rInfo.ParseInfo(); + rInfo.initRomsInfo(&_fwImgInfo.ext_info.roms_info); + + } + } + } + } + } else { + + // TODO: print crc error + /* + printf("-D- Bad ITOC CRC: toc_entry.itoc_entry_crc = %#x, actual crc: %#x, entry_size_in_bytes = %#x\n", toc_entry.itoc_entry_crc, + entry_crc, entry_size_in_bytes); + */ + ret_val = false; + } + + _fs3ImgInfo.tocArr[section_index].entry_addr = entry_addr; + _fs3ImgInfo.tocArr[section_index].toc_entry = toc_entry; + memcpy(_fs3ImgInfo.tocArr[section_index].data, entry_buffer, CIBFW_ITOC_ENTRY_SIZE); + } + section_index++; + } while (toc_entry.type != FS3_END); + _fs3ImgInfo.numOfItocs = section_index - 1; + if (!mfg_exists) { + return errmsg("No \""MFG_INFO"\" info section."); + } + return ret_val; +} + + +bool Fs3Operations::FwVerify(VerifyCallBack verifyCallBackFunc, bool isStripedImage, bool showItoc) { + //dummy assignment to avoid compiler warrning (isStripedImage is not used in fs3) + isStripedImage = true; + + struct QueryOptions queryOptions; + queryOptions.readRom = true; + queryOptions.quickQuery = false; + + return Fs3Verify(verifyCallBackFunc, showItoc, queryOptions); +} + +bool Fs3Operations::Fs3Verify(VerifyCallBack verifyCallBackFunc, bool show_itoc, struct QueryOptions queryOptions) +{ + u_int32_t cntx_image_start[CNTX_START_POS_SIZE]; + u_int32_t cntx_image_num; + u_int32_t buff[FS3_BOOT_START_IN_DW]; + u_int32_t offset; + bool bad_signature; + + // TODO: We need to check this paramater + _isFullVerify = true; + + CntxFindAllImageStart(_ioAccess, cntx_image_start, &cntx_image_num); + if (cntx_image_num == 0) { + return errmsg("No valid FS3 image found"); + } + u_int32_t image_start = cntx_image_start[0]; + offset = 0; + // TODO: Check more than one image + // Read BOOT + //f.set_address_convertor(0, 0); + // Put info + _fwImgInfo.imgStart = image_start; + _fwImgInfo.cntxLog2ChunkSize = 21; // TODO: should it be hardcoded + _fwImgInfo.ext_info.is_failsafe = true; + _fwImgInfo.actuallyFailsafe = true; + _fwImgInfo.magicPatternFound = 1; + + _ioAccess->set_address_convertor(_fwImgInfo.cntxLog2ChunkSize, _fwImgInfo.imgStart != 0); + READBUF((*_ioAccess), 0, buff, FS3_BOOT_START, "Image header"); + Fs3UpdateImgCache((u_int8_t*)buff, 0, FS3_BOOT_START); + TOCPUn(buff, FS3_BOOT_START_IN_DW); + + + + report_callback(verifyCallBackFunc, "\nFS3 failsafe image\n\n"); // TODO: Do we have non-faisafe image + // TODO: Get BOOT2 - No need to read all always + offset += FS2_BOOT_START; + FS3_CHECKB2(0, offset, true, PRE_CRC_OUTPUT, verifyCallBackFunc); + + offset += _fs3ImgInfo.bootSize; + _fs3ImgInfo.firstItocIsEmpty = false; + // printf("-D- image_start = %#x\n", image_start); + // TODO: Get info of the failsafe from the Image header - no need always failsafe + // Go over the ITOC entries + u_int32_t sector_size = (_ioAccess->is_flash()) ? _ioAccess->get_sector_size() : FS3_DEFAULT_SECTOR_SIZE; + offset = (offset % sector_size == 0) ? offset : (offset + sector_size - offset % 0x1000); + + while (offset < _ioAccess->get_size()) + { + if (VerifyTOC(offset, bad_signature, verifyCallBackFunc, show_itoc, queryOptions)) { + return true; + } else { + if (!bad_signature) { + return false; + } + _fs3ImgInfo.firstItocIsEmpty = true; + + } + offset += sector_size; + } + + return errmsg("No valid ITOC was found."); +} + + +bool Fs3Operations::Fs3IntQuery(bool readRom, bool quickQuery) +{ + struct QueryOptions queryOptions; + queryOptions.readRom = readRom; + queryOptions.quickQuery = quickQuery; + if (!Fs3Verify((VerifyCallBack)NULL, 0, queryOptions)) { + return false; + } + // works only on device + _fwImgInfo.ext_info.chip_type = getChipTypeFromHwDevid(_ioAccess->get_dev_id()); + if (_fwImgInfo.ext_info.chip_type == CT_CONNECT_IB) { + _fwImgInfo.ext_info.dev_type = CONNECT_IB_SW_ID; + } + + return true; +} + +bool Fs3Operations::FwQuery(fw_info_t *fwInfo, bool readRom, bool isStripedImage) +{ + //isStripedImage flag is not needed in FS3 image format + // Avoid warning - no striped image in FS3 + isStripedImage = false; + if (!Fs3IntQuery(readRom)) { + return false; + } + memcpy(&(fwInfo->fw_info), &(_fwImgInfo.ext_info), sizeof(fw_info_com_t)); + memcpy(&(fwInfo->fs3_info), &(_fs3ImgInfo.ext_info), sizeof(fs3_info_t)); + fwInfo->fw_type = FIT_FS3; + return true; +} + +u_int8_t Fs3Operations::FwType() +{ + return FIT_FS3; +} + + +bool Fs3Operations::FwInit() +{ + FwInitCom(); + memset(&_fs3ImgInfo, 0, sizeof(_fs3ImgInfo)); + return true; +} + + +bool Fs3Operations::UpdateDevDataITOC(u_int8_t *image_data, struct toc_info *image_toc_entry, struct toc_info *flash_toc_arr, int flash_toc_size) +{ + u_int8_t itoc_data[CIBFW_ITOC_ENTRY_SIZE]; + + for (int i = 0; i < flash_toc_size; i++) { + struct toc_info *flash_toc_info = &flash_toc_arr[i]; + struct cibfw_itoc_entry *flash_toc_entry = &flash_toc_info->toc_entry; + if (flash_toc_entry->type == image_toc_entry->toc_entry.type) { + memset(itoc_data, 0, CIBFW_ITOC_ENTRY_SIZE); + cibfw_itoc_entry_pack(flash_toc_entry, itoc_data); + memcpy(&image_data[image_toc_entry->entry_addr], itoc_data, CIBFW_ITOC_ENTRY_SIZE); + cibfw_itoc_entry_unpack(&image_toc_entry->toc_entry, &image_data[image_toc_entry->entry_addr]); + } + } + return true; +} + +#define FS3_FLASH_SIZE 0x400000 +bool Fs3Operations::CheckFs3ImgSize(Fs3Operations imageOps) +{ + u_int32_t flashSize = (_ioAccess->is_flash()) ? _ioAccess->get_size() : FS3_FLASH_SIZE; + u_int32_t maxFsImgSize = flashSize / 2; + u_int32_t maxImgDataSize = maxFsImgSize - (flashSize - _fs3ImgInfo.smallestAbsAddr); + + if (imageOps._fs3ImgInfo.sizeOfImgData > maxImgDataSize) { + return errmsg("Size of image data (0x%x) is greater than max size of image data (0x%x)", + imageOps._fs3ImgInfo.sizeOfImgData, maxImgDataSize); + } + return true; +} + +bool Fs3Operations::BurnFs3Image(Fs3Operations &imageOps, + ExtBurnParams& burnParams) +{ + u_int8_t is_curr_image_in_odd_chunks; + u_int32_t new_image_start, image_size = 0; + + Flash *f = (Flash*)(this->_ioAccess); + FImage *fim = (FImage*)(imageOps._ioAccess); + u_int8_t *data8 = (u_int8_t *) fim->getBuf(); + + + if (_fwImgInfo.imgStart != 0) { + is_curr_image_in_odd_chunks = 1; + new_image_start = 0; + } else { + is_curr_image_in_odd_chunks = 0; + new_image_start = (1 << imageOps._fwImgInfo.cntxLog2ChunkSize); + } + /*printf("-D- new_image_start = %#x, is_curr_image_in_odd_chunks = %#x\n", new_image_start, is_curr_image_in_odd_chunks); + printf("-D- num_of_itocs = %d\n", image_info->num_of_itocs); + */ + if (!CheckFs3ImgSize(imageOps)) { + return false; + } + + f->set_address_convertor(imageOps._fwImgInfo.cntxLog2ChunkSize, !is_curr_image_in_odd_chunks); + + for (int i = 0; i < imageOps._fs3ImgInfo.numOfItocs; i++) { + struct toc_info *itoc_info_p = &imageOps._fs3ImgInfo.tocArr[i]; + struct cibfw_itoc_entry *toc_entry = &itoc_info_p->toc_entry; + // printf("-D- itoc_addr = %#x\n", itoc_info_p->entry_addr); + if (toc_entry->device_data) { + // TODO: Copy the ITOC from Device + // printf("-D- toc_entry: %#x\n", toc_entry->itoc_entry_crc); + if (!UpdateDevDataITOC(data8, itoc_info_p, _fs3ImgInfo.tocArr, _fs3ImgInfo.numOfItocs)) { + return false; + } + // printf("-D- After toc_entry: %#x\n", toc_entry->itoc_entry_crc); + } else { + u_int32_t last_addr_of_itoc = (toc_entry->flash_addr + toc_entry->size) << 2; + image_size = (last_addr_of_itoc > image_size) ? last_addr_of_itoc : image_size; + } + + } + + + // TODO: Check that the dev data is not been overridden + { + + // TODO : remove these remnants of the old printing system , we use callback func now + char * pre_message = (char*)"Burning FS3 FW image without signatures"; + u_int32_t zeroes = 0; + char message[128], message1[128], buff[128]; + int allow_nofs = 0; + + if (pre_message == NULL) { + sprintf(message, "Burning FW image without signatures"); + } else { + sprintf(message, pre_message); + } + int str_len = strlen(message), restore_len = strlen(RESTORING_MSG); + str_len = (restore_len > str_len) ? restore_len : str_len; + + sprintf(buff, "%%-%ds - ", str_len); + + sprintf(message1, buff, message); + + + if (!writeImage(burnParams.progressFunc, 16 , data8 + 16, image_size - 16)) { + return false; + } + if (!f->is_flash()) { + return true; + } + // Write new signature + if (!f->write(0, data8, 16, true)) { + return false; + } + bool boot_address_was_updated = true; + // Write new image start address to crspace (for SW reset) + if (!f->update_boot_addr(new_image_start)) { + boot_address_was_updated = false; + } + + if (imageOps._fwImgInfo.ext_info.is_failsafe) { + if (allow_nofs) { + // When burning in nofs, remnant of older image with different chunk size + // may reside on the flash - + // Invalidate all images marking on flash except the one we've just burnt + + u_int32_t cntx_image_start[CNTX_START_POS_SIZE]; + u_int32_t cntx_image_num; + u_int32_t i; + + CntxFindAllImageStart(f, cntx_image_start, &cntx_image_num); + // Address convertor is disabled now - use phys addresses + for (i = 0; i < cntx_image_num; i++) { + if (cntx_image_start[i] != new_image_start) { + if (!f->write(cntx_image_start[i], &zeroes, sizeof(zeroes), true)) { + return false; + } + } + } + } else { + // invalidate previous signature + f->set_address_convertor(imageOps._fwImgInfo.cntxLog2ChunkSize, is_curr_image_in_odd_chunks); + if (!f->write(0, &zeroes, sizeof(zeroes), true)) { + return false; + } + } + } + if (boot_address_was_updated == false) { + report_warn("Failed to update FW boot address. Power cycle the device in order to load the new FW.\n"); + } + + } + // TODO: Update the signature + + return true; +} +bool Fs3Operations::Fs3Burn(Fs3Operations &imageOps, ExtBurnParams& burnParams) +{ + + if (imageOps.FwType() != FIT_FS3) { + return errmsg("FW image type is not FS3\n"); + } + if (!Fs3IntQuery()) { + return false; + } + // for image we execute full verify to bring all the information needed for ROM Patch + if (!imageOps.Fs3IntQuery(true, false)) { + return false; + } + if (!CheckPSID(imageOps, burnParams.allowPsidChange)) { + return false; + } + + // Check if the burnt FW version is OK + if (!CheckFwVersion(imageOps, burnParams.ignoreVersionCheck)) { + // special_ret_val = RC_FW_ALREADY_UPDATED; + return false; + } + + Fs3Operations *imgToBurn = &imageOps; + + // ROM patchs + if (((burnParams.burnRomOptions == ExtBurnParams::BRO_FROM_DEV_IF_EXIST) && (_fwImgInfo.ext_info.roms_info.exp_rom_found)) || // There is ROM in device and user choses to keep it + ((burnParams.burnRomOptions == ExtBurnParams::BRO_DEFAULT) && (!imageOps._fwImgInfo.ext_info.roms_info.exp_rom_found))) { // No ROM in image + // here we should take rom from device and insert into the image + // i.e if we have rom in image remove it and put the rom from the device else just put rom from device. + + // 1. use Fs3ModifySection to integrate _romSect buff with the image , newImageData contains the modified image buffer + std::vector newImageData(imageOps._fwImgInfo.lastImageAddr); + std::vector romSect = _romSect; + TOCPUn((u_int32_t*)&romSect[0], romSect.size()/4); + if (!imageOps.Fs3ReplaceSectionInDevImg(FS3_ROM_CODE, FS3_PCI_CODE, true, (u_int8_t*)&newImageData[0], imageOps._fwImgInfo.lastImageAddr, + (u_int32_t*)&romSect[0], (u_int32_t)romSect.size())) { + return errmsg("failed to update ROM in image. %s", imageOps.err()); + } + // 2. create fs3Operation Obj (handl type BUFF) + // open the image buffer + FwOperations* imageWithRomOps = FwOperationsCreate((void*)&newImageData[0], (void*)&imageOps._fwImgInfo.lastImageAddr, (char*)NULL, FHT_FW_BUFF, (char*)NULL, (int)NULL); + if (!imageWithRomOps) { + return errmsg("Internal error: The prepared image is corrupted."); + } + // 3. verify it + if (!((Fs3Operations*)imageWithRomOps)->Fs3IntQuery(true,false)) { + errmsg("Internal error: The prepared image is corrupted: %s", imageWithRomOps->err()); + imageWithRomOps->FwCleanUp(); + delete imageWithRomOps; + return false; + } + // 4. pass it to BurnFs3Image instead of imageOps + imgToBurn = (Fs3Operations*)imageWithRomOps; + } + + bool rc = BurnFs3Image(*imgToBurn, burnParams); + if (imgToBurn != &imageOps) { + imgToBurn->FwCleanUp(); + delete imgToBurn; + } + return rc; +} + +bool Fs3Operations::FwBurn(FwOperations *imageOps, u_int8_t forceVersion, ProgressCallBack progressFunc) +{ + if (imageOps == NULL) { + return errmsg("bad parameter is given to FwBurn\n"); + } + + ExtBurnParams burnParams = ExtBurnParams(); + burnParams.ignoreVersionCheck = forceVersion; + burnParams.progressFunc = progressFunc; + + return Fs3Burn((*(Fs3Operations*)imageOps), burnParams); +} + +bool Fs3Operations::FwBurnAdvanced(FwOperations *imageOps, ExtBurnParams& burnParams) +{ + if (imageOps == NULL) { + return errmsg("bad parameter is given to FwBurnAdvanced\n"); + } + return Fs3Burn((*(Fs3Operations*)imageOps), burnParams); +} + +bool Fs3Operations::FwBurnBlock(FwOperations *imageOps, ProgressCallBack progressFunc) +{ + // Avoid Warning! + imageOps = (FwOperations*)NULL; + progressFunc = (ProgressCallBack)NULL; + return errmsg("FwBurnBlock is not supported anymore in FS3 image."); +} + +bool Fs3Operations::FwReadData(void* image, u_int32_t* imageSize) +{ + struct QueryOptions queryOptions; + if (!imageSize) { + return errmsg("bad parameter is given to FwReadData\n"); + } + + queryOptions.readRom = true; + queryOptions.quickQuery = false; + if (image == NULL) { + // When we need only to get size, no need for reading entire image + queryOptions.readRom = false; + queryOptions.quickQuery = true; + } + // Avoid Warning + if (!Fs3Verify((VerifyCallBack)NULL, 0, queryOptions)) { + return false; + } + + if (image != NULL) { + memcpy(image, &_fs3ImgInfo.imageCache[0], _fwImgInfo.lastImageAddr); + } + *imageSize = _fwImgInfo.lastImageAddr; + return true; +} + + +bool Fs3Operations::FwTest(u_int32_t *data) +{ + _ioAccess->set_address_convertor(0,0); + if (!_ioAccess->read(0, data)) { + return false; + } + /* + + if (!((Flash*)_ioAccess)->write(0, 0x12345678)) { + return false; + } + + if (!_ioAccess->read(0x0, data)) { + return false; + } + */ + return true; +} + +bool Fs3Operations::FwReadRom(std::vector& romSect) +{ + if (!Fs3IntQuery()) { + return false; + } + if (_romSect.empty()) { + return errmsg("Read ROM failed: The FW does not contain a ROM section"); + } + romSect = _romSect; + // Set endianness + TOCPUn(&(romSect[0]), romSect.size()/4); + return true; +} + +bool Fs3Operations::FwGetSection (u_int32_t sectType, std::vector& sectInfo) +{ + //we treat H_FW_CONF as FS3_DBG_LOG_MAP + //FwGetSection only supports retrieving FS3_DBG_LOG_MAP section atm. + if (sectType != H_FW_CONF && sectType != FS3_DBG_LOG_MAP) { + return errmsg("Hash File section not found in the given image."); + } + //set the sector to read (need to remove it after read) + _readSectList.push_back(FS3_DBG_LOG_MAP); + if (!Fs3IntQuery()) { + _readSectList.pop_back(); + return false; + } + _readSectList.pop_back(); + sectInfo = _fwConfSect; + if (sectInfo.empty()) { + return errmsg("Hash File section not found in the given image."); + } + return true; +} + + +bool Fs3Operations::FwSetMFG(guid_t baseGuid, PrintCallBack callBackFunc) +{ + + if (!Fs3UpdateSection(&baseGuid, FS3_MFG_INFO, false, CMD_SET_MFG_GUIDS, callBackFunc)) { + return false; + } + return true; +} + +bool Fs3Operations::FwSetGuids(sg_params_t& sgParam, PrintCallBack callBackFunc, ProgressCallBack progressFunc) +{ + // Avoid Warning because there is no need for progressFunc + progressFunc = (ProgressCallBack)NULL; + if (sgParam.userGuids.empty()) { + return errmsg("Base GUID not found."); + } + if (!Fs3UpdateSection(&sgParam.userGuids[0], FS3_DEV_INFO, true, CMD_SET_GUIDS, callBackFunc)) { + return false; + } + return true; +} + +bool Fs3Operations::FwSetVPD(char* vpdFileStr, PrintCallBack callBackFunc) +{ + if (!vpdFileStr) { + return errmsg("Please specify a valid vpd file."); + } + + if (!Fs3UpdateSection(vpdFileStr, FS3_VPD_R0, false, CMD_BURN_VPD, callBackFunc)) { + return false; + } + return true; +} + +bool Fs3Operations::GetModifiedSectionInfo(fs3_section_t sectionType, fs3_section_t nextSectionType, u_int32_t &newSectAddr, + fs3_section_t &SectToPut, u_int32_t &oldSectSize) +{ + struct toc_info *curr_itoc; + if (Fs3GetItocInfo(_fs3ImgInfo.tocArr, _fs3ImgInfo.numOfItocs, sectionType, curr_itoc) || + Fs3GetItocInfo(_fs3ImgInfo.tocArr, _fs3ImgInfo.numOfItocs, nextSectionType, curr_itoc)) { + newSectAddr = curr_itoc->toc_entry.flash_addr << 2; + SectToPut = (curr_itoc->toc_entry.type == sectionType) ? sectionType : nextSectionType; + oldSectSize = curr_itoc->toc_entry.size * 4; + return true; + } + return false; +} + +bool Fs3Operations::ShiftItocAddrInEntry(struct toc_info *newItocInfo, struct toc_info *oldItocInfo, int shiftSize) +{ + u_int32_t currSectaddr; + CopyItocInfo(newItocInfo, oldItocInfo); + currSectaddr = (newItocInfo->toc_entry.flash_addr << 2) + shiftSize; + Fs3UpdateItocInfo(newItocInfo, currSectaddr); + return true; +} +bool Fs3Operations::Fs3UpdateItocInfo(struct toc_info *newItocInfo, u_int32_t newSectAddr, fs3_section_t sectionType, u_int32_t* newSectData, + u_int32_t NewSectSize) +{ + std::vector newSecVect(NewSectSize); + newItocInfo->toc_entry.type = sectionType; + memcpy(&newSecVect[0], newSectData, NewSectSize); + return Fs3UpdateItocInfo(newItocInfo, newSectAddr, NewSectSize / 4, newSecVect); +} + + +bool Fs3Operations::CopyItocInfo(struct toc_info *newTocInfo, struct toc_info *currToc) +{ + memcpy(newTocInfo->data, currToc->data, CIBFW_ITOC_ENTRY_SIZE); + newTocInfo->entry_addr = currToc->entry_addr; + newTocInfo->section_data = currToc->section_data; + newTocInfo->toc_entry = currToc->toc_entry; + return true; +} + + + + +bool Fs3Operations::UpdateItocAfterInsert(fs3_section_t sectionType, u_int32_t newSectAddr, fs3_section_t SectToPut, bool toAdd, u_int32_t* newSectData, + u_int32_t removedOrNewSectSize, struct toc_info *tocArr, u_int32_t &numOfItocs) +{ + bool isReplacement = (sectionType == SectToPut) ? true : false; + int shiftSize; + + if (toAdd) { + if (isReplacement) { + struct toc_info *curr_itoc; + u_int32_t sectSize; + Fs3GetItocInfo(_fs3ImgInfo.tocArr, _fs3ImgInfo.numOfItocs, sectionType, curr_itoc); + sectSize = curr_itoc->toc_entry.size * 4; + shiftSize = (removedOrNewSectSize > sectSize) ? removedOrNewSectSize - sectSize : 0; + } else { + shiftSize = removedOrNewSectSize; + } + if (shiftSize % FS3_DEFAULT_SECTOR_SIZE) { + shiftSize += (FS3_DEFAULT_SECTOR_SIZE - shiftSize % FS3_DEFAULT_SECTOR_SIZE); + } + } else { + shiftSize = 0; + if (removedOrNewSectSize % FS3_DEFAULT_SECTOR_SIZE) { + removedOrNewSectSize += (FS3_DEFAULT_SECTOR_SIZE - removedOrNewSectSize % FS3_DEFAULT_SECTOR_SIZE); + } + shiftSize -= removedOrNewSectSize; + } + numOfItocs = 0; + for (int i = 0; i < _fs3ImgInfo.numOfItocs; i++) { + struct toc_info *curr_itoc = &_fs3ImgInfo.tocArr[i]; + struct toc_info *newTocInfo = &tocArr[numOfItocs]; + u_int32_t currSectaddr = curr_itoc->toc_entry.flash_addr << 2; // Put it in one place + + if (currSectaddr > newSectAddr) { + if (!curr_itoc->toc_entry.relative_addr) { + + CopyItocInfo(newTocInfo, curr_itoc); + } else { + ShiftItocAddrInEntry(newTocInfo, curr_itoc, shiftSize); + } + } else if (currSectaddr == newSectAddr) { + if (!toAdd) { + continue; + } + CopyItocInfo(newTocInfo, curr_itoc); + Fs3UpdateItocInfo(newTocInfo, newSectAddr, sectionType, newSectData, removedOrNewSectSize); + + if (!isReplacement) { + // put next section + newTocInfo = &tocArr[++numOfItocs]; + ShiftItocAddrInEntry(newTocInfo, curr_itoc, shiftSize); + } + } else { + // just Copy the ITOC as is + CopyItocInfo(newTocInfo, curr_itoc); + } + numOfItocs++; + } + return true; +} + +bool Fs3Operations::UpdateImageAfterInsert(struct toc_info *tocArr, u_int32_t numOfItocs, u_int8_t* newImgData, u_int32_t newImageSize) +{ + + + // Copy data before itocAddr and ITOC header + memcpy(newImgData, &_fs3ImgInfo.imageCache[0], _fs3ImgInfo.itocAddr); + memcpy(&newImgData[_fs3ImgInfo.itocAddr], _fs3ImgInfo.itocHeader, CIBFW_ITOC_HEADER_SIZE); + for (int i = 0; i < (int)numOfItocs; i++) { + // Inits + u_int32_t itocOffset = _fs3ImgInfo.itocAddr + CIBFW_ITOC_HEADER_SIZE + i * CIBFW_ITOC_ENTRY_SIZE; + struct toc_info *currItoc = &tocArr[i]; + u_int8_t sectType = currItoc->toc_entry.type; + // TODO: What should we do with Itoc Addr + u_int32_t sectAddr = currItoc->toc_entry.flash_addr << 2; + u_int32_t sectSize = currItoc->toc_entry.size * 4; + // Some checks + if (sectAddr + sectSize > newImageSize) { + return errmsg("Internal error: Size of modified image (0x%x) is longer than size of original image (0x%x)!", sectAddr + sectSize, newImageSize); + } + if (sectSize != currItoc->section_data.size()) { + return errmsg("Internal error: Sectoion size of %s (0x%x) is not equal to allocated memory for it(0x%x)", GetSectionNameByType(sectType), + sectSize, (u_int32_t)currItoc->section_data.size()); + } + + memcpy(&newImgData[itocOffset], currItoc->data, CIBFW_ITOC_ENTRY_SIZE); + + memcpy(&newImgData[sectAddr], &currItoc->section_data[0], sectSize); + } + u_int32_t lastItocSect = _fs3ImgInfo.itocAddr + CIBFW_ITOC_HEADER_SIZE + numOfItocs * CIBFW_ITOC_ENTRY_SIZE; + memset(&newImgData[lastItocSect], FS3_END, CIBFW_ITOC_ENTRY_SIZE); + return true; +} + +bool Fs3Operations::Fs3ReplaceSectionInDevImg(fs3_section_t sectionType, fs3_section_t nextSectionType, bool toAdd, u_int8_t* newImgData, u_int32_t newImageSize, + u_int32_t* newSectData, u_int32_t NewSectSize) +{ + u_int32_t newSectAddr; + u_int32_t numOfItocs; + struct toc_info tocArr[MAX_TOCS_NUM]; + fs3_section_t sectToPut; + u_int32_t oldSectSize; + + if (!GetModifiedSectionInfo(sectionType, nextSectionType, newSectAddr, sectToPut, oldSectSize)) { + return false; + } + u_int32_t removedOrNewSectSize = (toAdd) ? NewSectSize : oldSectSize; + + if (!UpdateItocAfterInsert(sectionType, newSectAddr, sectToPut, toAdd, newSectData, removedOrNewSectSize, tocArr, numOfItocs)) { + return false; + } + if (!UpdateImageAfterInsert(tocArr, numOfItocs, newImgData, newImageSize)) { + return false; + } + return true; +} + +bool Fs3Operations::Fs3ModifySection(fs3_section_t sectionType, fs3_section_t neighbourSection, bool toAdd, u_int32_t* newSectData, u_int32_t newSectSize, + ProgressCallBack progressFunc) +{ + // Get image data and ROM data and integrate ROM data into image data + // Verify FW on device + if (!FwVerify((VerifyCallBack)NULL)) { + return errmsg("Verify FW burn on the device failed: %s", err()); + } + + std::vector newImageData(_fwImgInfo.lastImageAddr); + // u_int8_t *newImageData = new u_int8_t[_fwImgInfo.lastImageAddr]; + + if (!Fs3ReplaceSectionInDevImg(sectionType, neighbourSection, toAdd, (u_int8_t*)&newImageData[0], _fwImgInfo.lastImageAddr, + newSectData, newSectSize)) { + ///delete[] newImageData; + return false; + } + // Burn the new image into the device. + if (!FwBurnData((u_int32_t*)&newImageData[0], _fwImgInfo.lastImageAddr, progressFunc)) { + return false; + } + return true; +} + +bool Fs3Operations::Fs3AddSection(fs3_section_t sectionType, fs3_section_t neighbourSection, u_int32_t* newSectData, u_int32_t newSectSize, + ProgressCallBack progressFunc) +{ + // We need to add the new section before the neighbourSection + return Fs3ModifySection(sectionType, neighbourSection, true, newSectData, newSectSize, progressFunc); +} + +bool Fs3Operations::Fs3RemoveSection(fs3_section_t sectionType, ProgressCallBack progressFunc) +{ + return Fs3ModifySection(sectionType, sectionType, false, NULL, 0, progressFunc); +} + + +bool Fs3Operations::FwBurnRom(FImage* romImg, bool ignoreProdIdCheck, bool ignoreDevidCheck, + ProgressCallBack progressFunc) +{ + roms_info_t romsInfo; + + if (romImg == NULL) { + return errmsg("Bad ROM image is given."); + } + + if (romImg->getBufLength() == 0) { + return errmsg("Bad ROM file: Empty file."); + } + if (!FwOperations::getRomsInfo(romImg, romsInfo)) { + return errmsg("Failed to read given ROM."); + } + if (!Fs3IntQuery(false)) { + return false; + } + + if (!ignoreProdIdCheck && strcmp(_fwImgInfo.ext_info.product_ver, "") != 0) { + return errmsg("The device FW contains common FW/ROM Product Version - The ROM cannot be updated separately."); + } + + if (!ignoreDevidCheck && !FwOperations::checkMatchingExpRomDevId(_fwImgInfo.ext_info.dev_type, romsInfo)) { + return errmsg("Image file ROM: FW is for device %d, but Exp-ROM is for device %d\n", _fwImgInfo.ext_info.dev_type, + romsInfo.exp_rom_com_devid); + } + return Fs3AddSection(FS3_ROM_CODE, FS3_PCI_CODE, romImg->getBuf(), romImg->getBufLength(), progressFunc); +} + +bool Fs3Operations::FwDeleteRom(bool ignoreProdIdCheck, ProgressCallBack progressFunc) +{ + //run int query to get product ver + if (!Fs3IntQuery(true)) { + return false; + } + + if (_romSect.empty()) { + return errmsg("The FW does not contain a ROM section"); + } + + if (!ignoreProdIdCheck && strcmp(_fwImgInfo.ext_info.product_ver, "") != 0) { + return errmsg("The device FW contains common FW/ROM Product Version - The ROM cannot be updated separately."); + } + + return Fs3RemoveSection(FS3_ROM_CODE, progressFunc); +} + +bool Fs3Operations::Fs3GetItocInfo(struct toc_info *tocArr, int num_of_itocs, fs3_section_t sect_type, struct toc_info *&curr_toc) +{ + for (int i = 0; i < num_of_itocs; i++) { + struct toc_info *itoc_info = &tocArr[i]; + if (itoc_info->toc_entry.type == sect_type) { + curr_toc = itoc_info; + return true; + } + } + return errmsg("ITOC entry type: %s (%d) not found", GetSectionNameByType(sect_type), sect_type); +} + +bool Fs3Operations::Fs3UpdateMfgUidsSection(struct toc_info *curr_toc, std::vector section_data, guid_t base_uid, + std::vector &newSectionData) +{ + struct cibfw_mfg_info mfg_info; + cibfw_mfg_info_unpack(&mfg_info, (u_int8_t*)§ion_data[0]); + + Fs3ChangeUidsFromBase(base_uid, &mfg_info.guids); + newSectionData = section_data; + memset((u_int8_t*)&newSectionData[0], 0, curr_toc->toc_entry.size * 4); + cibfw_mfg_info_pack(&mfg_info, (u_int8_t*)&newSectionData[0]); + return true; +} + +bool Fs3Operations::Fs3ChangeUidsFromBase(guid_t base_uid, struct cibfw_guids *guids) +{ + u_int64_t base_uid_64 = base_uid.l | (u_int64_t)base_uid.h << 32; + // Should be put somewhere in common place + u_int64_t base_mac_64 = ((u_int64_t)base_uid.l & 0xffffff) | (((u_int64_t)base_uid.h & 0xffffff00) << 16); + + guids->guids[0].uid = base_uid_64; + guids->guids[1].uid = base_uid_64 + 8; + guids->macs[0].uid = base_mac_64; + guids->macs[1].uid = base_mac_64 + 8; + return true; +} + +bool Fs3Operations::Fs3UpdateUidsSection(struct toc_info *curr_toc, std::vector section_data, guid_t base_uid, + std::vector &newSectionData) +{ + struct cibfw_device_info dev_info; + cibfw_device_info_unpack(&dev_info, (u_int8_t*)§ion_data[0]); + Fs3ChangeUidsFromBase(base_uid, &dev_info.guids); + newSectionData = section_data; + memset((u_int8_t*)&newSectionData[0], 0, curr_toc->toc_entry.size * 4); + cibfw_device_info_pack(&dev_info, (u_int8_t*)&newSectionData[0]); + return true; +} + +bool Fs3Operations::Fs3UpdateVsdSection(struct toc_info *curr_toc, std::vector section_data, char* user_vsd, + std::vector &newSectionData) +{ + struct cibfw_device_info dev_info; + cibfw_device_info_unpack(&dev_info, (u_int8_t*)§ion_data[0]); + size_t len = strlen(user_vsd); + if (len > VSD_LEN-1) { + return errmsg("VSD too long: %d", (int)len); + } + strcpy(dev_info.vsd, user_vsd); + newSectionData = section_data; + memset((u_int8_t*)&newSectionData[0], 0, curr_toc->toc_entry.size * 4); + cibfw_device_info_pack(&dev_info, (u_int8_t*)&newSectionData[0]); + return true; +} + +bool Fs3Operations::Fs3UpdateVpdSection(struct toc_info *curr_toc, char *vpd, + std::vector &newSectionData) +{ + int vpd_size; + u_int8_t *vpd_data; + + if (!ReadImageFile(vpd, vpd_data, vpd_size)) { + return false; + } + if (vpd_size % 4) { + return errmsg("Size of VPD file: %d is not 4-byte alligned!", vpd_size); + } + GetSectData(newSectionData, (u_int32_t*)vpd_data, vpd_size); + curr_toc->toc_entry.size = vpd_size / 4; + delete[] vpd_data; + return true; +} + +bool Fs3Operations::Fs3GetNewSectionAddr(struct toc_info *tocArr, struct toc_info *curr_toc, u_int32_t &NewSectionAddr, bool failsafe_section) +{ + // printf("-D- addr = %#x\n", curr_toc->toc_entry.flash_addr); + u_int32_t sector_size = (_ioAccess->is_flash()) ? _ioAccess->get_sector_size() : FS3_DEFAULT_SECTOR_SIZE; + u_int32_t flash_addr = curr_toc->toc_entry.flash_addr << 2; + // HACK: THIS IS AN UGLY HACK, SHOULD BE REMOVED ASAP + if (failsafe_section) { + NewSectionAddr = (flash_addr == 0x3fd000) ? 0x3fe000 : 0x3fd000; + } else { + NewSectionAddr = flash_addr; + } + // HACK: Avoid warning + tocArr = NULL; + // fbase = 0; + sector_size = 0; + return true; +} + +bool Fs3Operations::CalcItocEntryCRC(struct toc_info *curr_toc) +{ + u_int8_t new_entry_data[CIBFW_ITOC_ENTRY_SIZE]; + memset(new_entry_data, 0, CIBFW_ITOC_ENTRY_SIZE); + + cibfw_itoc_entry_pack(&curr_toc->toc_entry, new_entry_data); + u_int32_t entry_crc = CalcImageCRC((u_int32_t*)new_entry_data, (TOC_ENTRY_SIZE / 4) - 1); + curr_toc->toc_entry.itoc_entry_crc = entry_crc; + return true; + +} + +bool Fs3Operations::Fs3UpdateItocData(struct toc_info *currToc) +{ + CalcItocEntryCRC(currToc); + memset(currToc->data, 0, CIBFW_ITOC_ENTRY_SIZE); + cibfw_itoc_entry_pack(&currToc->toc_entry, currToc->data); + + return true; + +} + +bool Fs3Operations::Fs3UpdateItocInfo(struct toc_info *curr_toc, u_int32_t newSectionAddr) +{ + // We assume it's absolute + curr_toc->toc_entry.flash_addr = newSectionAddr >> 2; + return Fs3UpdateItocData(curr_toc); + +} +bool Fs3Operations::Fs3UpdateItocInfo(struct toc_info *curr_toc, u_int32_t newSectionAddr, u_int32_t NewSectSize, std::vector newSectionData) +{ + curr_toc->section_data = newSectionData; + curr_toc->toc_entry.size = NewSectSize; + u_int32_t new_crc = CalcImageCRC((u_int32_t*)&newSectionData[0], curr_toc->toc_entry.size); + curr_toc->toc_entry.section_crc = new_crc; + + return Fs3UpdateItocInfo(curr_toc, newSectionAddr); + } + +bool Fs3Operations::Fs3ReburnItocSection(u_int32_t newSectionAddr, + u_int32_t newSectionSize, std::vector newSectionData, char *msg, PrintCallBack callBackFunc) +{ + + // HACK SHOULD BE REMOVED ASAP + u_int32_t sector_size = (_ioAccess->is_flash()) ? _ioAccess->get_sector_size() : FS3_DEFAULT_SECTOR_SIZE; + u_int32_t oldItocAddr = _fs3ImgInfo.itocAddr; + u_int32_t newItocAddr = (_fs3ImgInfo.firstItocIsEmpty) ? (_fs3ImgInfo.itocAddr - sector_size) : (_fs3ImgInfo.itocAddr + sector_size); + char message[127]; + + sprintf(message, "Updating %-4s section - ", msg); + // Burn new Section + // we pass a null callback and print the progress here as the writes are small (guids/mfg/vpd_str) + // in the future if we want to pass the cb prints to writeImage , need to change the signature of progressCallBack to recieve and optional string to print + if (callBackFunc) { + callBackFunc(message); + } + if (!writeImage((ProgressCallBack)NULL, newSectionAddr , (u_int8_t*)&newSectionData[0], newSectionSize, true)) { + if (callBackFunc) { + callBackFunc("FAILED\n"); + } + return false; + } + if (callBackFunc) { + callBackFunc("OK\n"); + } + // Update new ITOC + std::vector itocEntriesData; + u_int32_t itocSize = (_fs3ImgInfo.numOfItocs + 1 ) * CIBFW_ITOC_ENTRY_SIZE + CIBFW_ITOC_HEADER_SIZE; + u_int8_t *p = itocEntriesData.get_allocator().allocate(itocSize); + memcpy(p, _fs3ImgInfo.itocHeader, CIBFW_ITOC_HEADER_SIZE); + for (int i = 0; i < _fs3ImgInfo.numOfItocs; i++) { + struct toc_info *curr_itoc = &_fs3ImgInfo.tocArr[i]; + memcpy(p + CIBFW_ITOC_HEADER_SIZE + i * CIBFW_ITOC_ENTRY_SIZE, curr_itoc->data, CIBFW_ITOC_ENTRY_SIZE); + } + memset(&p[itocSize] - CIBFW_ITOC_ENTRY_SIZE, FS3_END, CIBFW_ITOC_ENTRY_SIZE); + + + if (callBackFunc) { + callBackFunc("Updating ITOC section - "); + } + if (!writeImage((ProgressCallBack)NULL, newItocAddr , p, itocSize, false)) { + if (callBackFunc) { + callBackFunc("FAILED\n"); + } + return false; + } + if (callBackFunc) { + callBackFunc("OK\n"); + } + u_int32_t zeros = 0; + + if (callBackFunc) { + callBackFunc("Restoring signature - "); + } + if (!writeImage((ProgressCallBack)NULL, oldItocAddr, (u_int8_t*)&zeros, 4, false)) { + if (callBackFunc) { + callBackFunc("FAILED\n"); + } + return false; + } + if (callBackFunc) { + callBackFunc("OK\n"); + } + return true; +} + +//add callback if we want info during section update +bool Fs3Operations::Fs3UpdateSection(void *new_info, fs3_section_t sect_type, bool is_sect_failsafe, CommandType cmd_type, PrintCallBack callBackFunc) +{ + struct toc_info *newTocArr; + struct toc_info *curr_toc; + std::vector newUidSection; + u_int32_t newSectionAddr; + char *type_msg; + // init sector to read + _readSectList.push_back(sect_type); + if (!Fs3IntQuery()) { + _readSectList.pop_back(); + return false; + } + _readSectList.pop_back(); + // _silent = curr_silent; + + // get newTocArr + newTocArr = _fs3ImgInfo.tocArr; + + if (!Fs3GetItocInfo(_fs3ImgInfo.tocArr, _fs3ImgInfo.numOfItocs, sect_type, curr_toc)) { + return false; + } + + if (sect_type == FS3_MFG_INFO) { + guid_t base_uid = *(guid_t*)new_info; + type_msg = "GUID"; + if (!Fs3UpdateMfgUidsSection(curr_toc, curr_toc->section_data, base_uid, newUidSection)) { + return false; + } + } else if (sect_type == FS3_DEV_INFO) { + if (cmd_type == CMD_SET_GUIDS) { + guid_t base_uid = *(guid_t*)new_info; + type_msg = "GUID"; + if (!Fs3UpdateUidsSection(curr_toc, curr_toc->section_data, base_uid, newUidSection)) { + return false; + } + } else if(cmd_type == CMD_SET_VSD) { + char* user_vsd = (char*)new_info; + type_msg = "VSD"; + if (!Fs3UpdateVsdSection(curr_toc, curr_toc->section_data, user_vsd, newUidSection)) { + return false; + } + } else { + // We shouldnt reach here EVER + type_msg = "Unknown"; + } + } else if (sect_type == FS3_VPD_R0) { + char *vpd_file = (char*)new_info; + type_msg = "VPD"; + if (!Fs3UpdateVpdSection(curr_toc, vpd_file, newUidSection)) { + return false; + } + } else { + return errmsg("Section type %s is not supported\n", GetSectionNameByType(sect_type)); + } + + + if (!Fs3GetNewSectionAddr(_fs3ImgInfo.tocArr, curr_toc, newSectionAddr, is_sect_failsafe)) { + return false; + } + if (!Fs3UpdateItocInfo(curr_toc, newSectionAddr, curr_toc->toc_entry.size, newUidSection)) { + return false; + } + if (!Fs3ReburnItocSection(newSectionAddr, curr_toc->toc_entry.size * 4, newUidSection, type_msg, callBackFunc)) { + return false; + } + return true; +} + + +bool Fs3Operations::FwSetVSD(char* vsdStr, ProgressCallBack progressFunc, PrintCallBack printFunc) +{ + // Avoid warning + progressFunc = (ProgressCallBack)NULL; + if (!vsdStr) { + return errmsg("Please specify a valid VSD string."); + } + if (!Fs3UpdateSection(vsdStr, FS3_DEV_INFO, true, CMD_SET_VSD, printFunc)) { + return false; + } + return true; +} + +bool Fs3Operations::FwSetAccessKey(hw_key_t userKey, ProgressCallBack progressFunc) +{ + userKey = (hw_key_t){0,0}; + progressFunc = (ProgressCallBack)NULL; + return errmsg("Set access key not supported."); +} diff --git a/mlxfwops/lib/fs3_ops.h b/mlxfwops/lib/fs3_ops.h new file mode 100644 index 0000000..1a430b3 --- /dev/null +++ b/mlxfwops/lib/fs3_ops.h @@ -0,0 +1,175 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +#ifndef FS3_OPS_ +#define FS3_OPS_ + +// #include "flint_base.h" +#include "fw_ops.h" +#include + + + +class Fs3Operations : public FwOperations { +public: + + + Fs3Operations(FBase *ioAccess) : + FwOperations(ioAccess) {}; + + virtual ~Fs3Operations() {}; + //virtual void print_type() {printf("-D- FS3 type!\n");}; + virtual bool FwVerify(VerifyCallBack verifyCallBackFunc, bool isStripedImage = false, bool showItoc = false); + virtual bool FwQuery(fw_info_t *fwInfo, bool readRom = true, bool isStripedImage = false); + virtual u_int8_t FwType(); + virtual bool FwInit(); + virtual bool FwReadData(void* image, u_int32_t* image_size); + + virtual bool FwReadRom(std::vector& romSect); + virtual bool FwBurnRom(FImage* romImg, bool ignoreProdIdCheck = false, bool ignoreDevidCheck = false, ProgressCallBack progressFunc=(ProgressCallBack)NULL); + virtual bool FwDeleteRom(bool ignoreProdIdCheck, ProgressCallBack progressFunc=(ProgressCallBack)NULL); + + virtual bool FwBurn(FwOperations *imageOps, u_int8_t forceVersion, ProgressCallBack progressFunc=(ProgressCallBack)NULL); + virtual bool FwBurnAdvanced(FwOperations *imageOps, ExtBurnParams& burnParams); + virtual bool FwBurnBlock(FwOperations* imageOps, ProgressCallBack progressFunc); + + virtual bool FwSetGuids(sg_params_t& sgParam, PrintCallBack callBack, ProgressCallBack progressFunc); + virtual bool FwSetMFG(guid_t baseGuid, PrintCallBack callBackFunc=(PrintCallBack)NULL); + virtual bool FwGetSection (u_int32_t sectType, std::vector& sectInfo); + virtual bool FwSetVSD(char* vsdStr, ProgressCallBack progressFunc=(ProgressCallBack)NULL, PrintCallBack printFunc=(PrintCallBack)NULL); + virtual bool FwSetVPD(char* vpdFileStr, PrintCallBack callBackFunc=(PrintCallBack)NULL); + virtual bool FwSetAccessKey(hw_key_t userKey, ProgressCallBack progressFunc=(ProgressCallBack)NULL); + + virtual bool FwTest(u_int32_t *data); // Add callback print + + +private: + #define CRC_CHECK_OUTPUT CRC_CHECK_OLD")" + #define FS3_CRC_CHECK_OUT CRC_CHECK_OLD":0x%x)" + #define PRE_CRC_OUTPUT " " + #define MAX_TOCS_NUM 128 + #define FS3_DEFAULT_SECTOR_SIZE 0x1000 + #define ITOC_ASCII 0x49544f43 + #define DTOC_ASCII 0x64544f43 + #define TOC_RAND1 0x04081516 + #define TOC_RAND2 0x2342cafa + #define TOC_RAND3 0xbacafe00 + #define TOC_HEADER_SIZE 0x20 + #define TOC_ENTRY_SIZE 0x20 + #define MFG_INFO "MFG_INFO" + #define UNKNOWN_SECTION "UNKNOWN" + + + + + + struct toc_info { + u_int32_t entry_addr; + struct cibfw_itoc_entry toc_entry; + u_int8_t data[CIBFW_ITOC_ENTRY_SIZE]; + std::vector section_data; + }; + + struct Fs3ImgInfo { + fs3_info_t ext_info; + std::vector imageCache; + int numOfItocs; + struct toc_info tocArr[MAX_TOCS_NUM]; + u_int8_t itocHeader[CIBFW_ITOC_HEADER_SIZE]; + u_int32_t bootSize; + u_int8_t firstItocIsEmpty; + u_int32_t itocAddr; + u_int32_t smallestAbsAddr; + u_int32_t sizeOfImgData; + + }; + + struct SectionInfo { + u_int8_t type; + const char *name; + }; + + struct QueryOptions { + bool quickQuery; + bool readRom; + }; + + bool Fs3UpdateImgCache(u_int8_t *buff, u_int32_t addr, u_int32_t size); + virtual bool UpdateImgCache(u_int8_t *buff, u_int32_t addr, u_int32_t size); + bool VerifyTOC(u_int32_t dtoc_addr, bool& bad_signature, VerifyCallBack verifyCallBackFunc, bool show_itoc, + struct QueryOptions queryOptions); + bool Fs3Verify(VerifyCallBack verifyCallBackFunc, bool show_itoc, struct QueryOptions queryOptions); + const char* GetSectionNameByType(u_int8_t section_type); + bool CheckTocSignature(struct cibfw_itoc_header *itoc_header, u_int32_t first_signature); + bool DumpFs3CRCCheck(u_int8_t sect_type, u_int32_t sect_addr, u_int32_t sect_size, u_int32_t crc_act, u_int32_t crc_exp, + bool ignore_crc = false, VerifyCallBack verifyCallBackFunc = (VerifyCallBack)NULL); + bool GetImageInfoFromSection(u_int8_t *buff, u_int8_t sect_type, u_int8_t check_support_only = 0); + bool IsGetInfoSupported(u_int8_t sect_type); + bool IsFs3SectionReadable(u_int8_t type, QueryOptions queryOptions); + bool GetMfgInfo(u_int8_t *buff); + bool GetDevInfo(u_int8_t *buff); + bool GetImageInfo(u_int8_t *buff); + bool Fs3IntQuery(bool readRom = true, bool quickQuery=true); + bool Fs3Burn(Fs3Operations &imageOps, ExtBurnParams& burnParams); + bool BurnFs3Image(Fs3Operations &imageOps, ExtBurnParams& burnParams); + bool UpdateDevDataITOC(u_int8_t *image_data, struct toc_info *image_toc_entry, struct toc_info *flash_toc_arr, int flash_toc_size); + bool Fs3UpdateSection(void *new_info, fs3_section_t sect_type=FS3_DEV_INFO, bool is_sect_failsafe=true, CommandType cmd_type=CMD_UNKNOWN, PrintCallBack callBackFunc=(PrintCallBack)NULL ); + bool Fs3GetItocInfo(struct toc_info *tocArr, int num_of_itocs, fs3_section_t sect_type, struct toc_info *&curr_toc); + bool Fs3UpdateMfgUidsSection(struct toc_info *curr_toc, std::vector section_data, guid_t base_uid, + std::vector &newSectionData); + bool Fs3ChangeUidsFromBase(guid_t base_uid, struct cibfw_guids *guids); + bool Fs3UpdateUidsSection(struct toc_info *curr_toc, std::vector section_data, guid_t base_uid, + std::vector &newSectionData); + bool Fs3UpdateVsdSection(struct toc_info *curr_toc, std::vector section_data, char* user_vsd, + std::vector &newSectionData); + bool Fs3UpdateVpdSection(struct toc_info *curr_toc, char *vpd, std::vector &newSectionData); + bool Fs3GetNewSectionAddr(struct toc_info *tocArr, struct toc_info *curr_toc, u_int32_t &NewSectionAddr, bool failsafe_section); + + bool Fs3UpdateItocInfo(struct toc_info *curr_toc, u_int32_t newSectionAddr, u_int32_t itocSize, std::vector newSectionData); + bool Fs3UpdateItocInfo(struct toc_info *curr_toc, u_int32_t newSectionAddr); + bool Fs3UpdateItocInfo(struct toc_info *newItocInfo, u_int32_t newSectionAddr, fs3_section_t sectionType, u_int32_t* newSectData, u_int32_t NewSectSize); + bool Fs3UpdateItocData(struct toc_info *currToc); + + bool Fs3ReburnItocSection(u_int32_t newSectionAddr, u_int32_t newSectionSize, std::vector newSectionData, char *msg, PrintCallBack callBackFunc=(PrintCallBack)NULL); + bool GetModifiedSectionInfo(fs3_section_t sectionType, fs3_section_t nextSectionType, u_int32_t &newSectAddr, + fs3_section_t §ToPut, u_int32_t &oldSectSize); + bool UpdateItocAfterInsert(fs3_section_t sectionType, u_int32_t newSectAddr, fs3_section_t SectToPut, bool toAdd, u_int32_t* newSectData, u_int32_t NewSectSize, + struct toc_info *tocArr, u_int32_t &numOfItocs); + bool UpdateImageAfterInsert(struct toc_info *tocArr, u_int32_t numOfItocs, u_int8_t* newImgData, u_int32_t newSectSize); + bool Fs3ReplaceSectionInDevImg(fs3_section_t sectionType, fs3_section_t nextSectionType, bool toAdd, u_int8_t* newImgData, + u_int32_t newImageSize, u_int32_t* newSectData, u_int32_t NewSectSize); + bool CalcItocEntryCRC(struct toc_info *curr_toc); + bool ShiftItocAddrInEntry(struct toc_info *newItocInfo, struct toc_info *oldItocInfo, int shiftSize); + bool CopyItocInfo(struct toc_info *newTocInfo, struct toc_info *currToc); + bool Fs3ModifySection(fs3_section_t sectionType, fs3_section_t neighbourSection, bool toAdd, u_int32_t* newSectData, + u_int32_t newImageSize, ProgressCallBack progressFunc); + bool Fs3RemoveSection(fs3_section_t sectionType, ProgressCallBack progressFunc); + bool Fs3AddSection(fs3_section_t sectionType, fs3_section_t neighbourSection, u_int32_t* newSectData, u_int32_t newSectSize, + ProgressCallBack progressFunc); + bool CheckFs3ImgSize(Fs3Operations imageOps); + + + + + // Members + static const SectionInfo _fs3SectionsInfoArr[]; + static const u_int32_t _itocSignature[4]; + Fs3ImgInfo _fs3ImgInfo; + bool _isFullVerify; + +}; + + + +#endif // FS3_OPS_ diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp new file mode 100644 index 0000000..388d3c4 --- /dev/null +++ b/mlxfwops/lib/fw_ops.cpp @@ -0,0 +1,1367 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +#include "stdlib.h" +#include "string.h" +#include "flint_base.h" +#include "flint_io.h" +#include "fw_ops.h" +#include "fs3_ops.h" +#include "fs2_ops.h" + + +#ifndef NO_MFA_SUPPORT +#include +#endif + +#define BAD_CRC_MSG "Bad CRC." +extern const char* g_sectNames[]; + +#ifndef NO_MFA_SUPPORT + +int FwOperations::getFileSignature(const char* fname) +{ + FILE* fin; + char tmpb[16]; + int res = 0; + + if (!(fin = fopen(fname, "r"))) { + // abit ugly , need to establish a correct ret val + return IMG_SIG_OPEN_FILE_FAILED; + } + if (!fgets(tmpb, sizeof(tmpb), fin)) { + goto clean_up; + } + if (strlen(tmpb) < 4) { + goto clean_up; + } + + if (!strncmp(tmpb, "MTFW", 4)) { + res = IMG_SIG_TYPE_BIN; + } + if (!strncmp(tmpb, "MFAR", 4)) { + res = IMG_SIG_TYPE_MFA; + } + +clean_up: + fclose(fin); + return res; +} + + +int FwOperations::getBufferSignature(u_int8_t* buf, u_int32_t size) +{ + int res = 0; + + if (size < 4) { + return 0; + } + if (!strncmp((char*)buf, "MTFW", 4)) { + res = IMG_SIG_TYPE_BIN; + } + if (!strncmp((char*)buf, "MFAR", 4)) { + res = IMG_SIG_TYPE_MFA; + } + + return res; +} + + +int FwOperations::getMfaImg(char* fileName, char *psid, u_int8_t **imgbuf) +{ + int res; + mfa_desc* mfa_d; + int image_type = 1; //FW image + + if (psid == NULL) { + return -1; //No psid => no image + } + if ((res = mfa_open_file(&mfa_d, fileName))) { + return -1; + } + + res = mfa_get_image(mfa_d, psid, image_type, (char*)"", imgbuf); + + mfa_close(mfa_d); + return res; +} + + +int FwOperations::getMfaImg(u_int8_t* mfa_buf, int size, char *psid, u_int8_t **imgbuf) +{ + int res; + mfa_desc* mfa_d; + int image_type = 1; //FW image + + if (psid == NULL) { + return -1; //No psid => no image + } + if ((res = mfa_open_buf(&mfa_d, mfa_buf, size))) { + return -1; + } + + res = mfa_get_image(mfa_d, psid, image_type, (char*)"", imgbuf); + + mfa_close(mfa_d); + return res; +} +#endif + + +void FwOperations::FwCleanUp() +{ + _ioAccess->close(); + delete _ioAccess; + if (_fname != NULL) { + delete[] _fname; + } +} + + +void FwOperations::FwInitCom() +{ + memset(&_fwImgInfo, 0, sizeof(_fwImgInfo)); +} + + + +bool FwOperations::checkBoot2(u_int32_t beg, u_int32_t offs, u_int32_t& next, bool fullRead, const char *pref, VerifyCallBack verifyCallBackFunc) +{ + u_int32_t size; + + // char *pr = (char *)alloca(strlen(pref) + 512); + char pr[strlen(pref) + 512]; + sprintf(pr, "%s /0x%08x/ (BOOT2)", pref, offs+beg); + // Size + READ4((*_ioAccess), offs+beg+4, &size, pr); + TOCPU1(size); + if (size > 1048576 || size < 4) { + report_callback(verifyCallBackFunc, "%s /0x%08x/ - unexpected size (0x%x)\n", pr, offs+beg+4, size); + return false; + } + _fwImgInfo.bootSize = (size + 4) * 4; + + + sprintf(pr, "%s /0x%08x-0x%08x (0x%06x)/ (BOOT2)", pref, offs+beg, + offs+beg+(size+4)*4-1, (size+4)*4); + + if ((_ioAccess->is_flash() && fullRead == true) || !_ioAccess->is_flash()) { + Crc16 crc; + // u_int32_t *buff = (u_int32_t*)alloca((size + 4)*sizeof(u_int32_t)); + u_int32_t buff[size + 4]; + READBUF((*_ioAccess), offs+beg, buff, size*4 + 16, pr); + // we hold for FS3 an image cache so we selectevely update it in UpdateImgCache() call + UpdateImgCache((u_int8_t*)buff, offs+beg, size*4 + 16); + + TOCPUn(buff, size+4); + CRC1n(crc, buff, size+4); + CRC1n(_ioAccess->get_image_crc(), buff, size+4); + + + crc.finish(); + + u_int32_t crc_act = buff[size+3]; + if (crc.get() != crc_act) { + report_callback(verifyCallBackFunc, "%s /0x%08x/ - wrong CRC (exp:0x%x, act:0x%x)\n", + pr, offs+beg, crc.get(), crc_act); + return errmsg(BAD_CRC_MSG); + } + _ioAccess->get_image_crc() << crc_act; + // TODO: Print CRC + if (0) { + report_callback(verifyCallBackFunc, "%s - OK (CRC:0x%04x)\n", pr, (crc_act & 0xffff)); + } else { + report_callback(verifyCallBackFunc, "%s - OK\n", pr); + } + } + next = offs + size*4 + 16; + return true; +} // checkBoot2 + + +bool FwOperations::CheckAndPrintCrcRes(char* pr, bool blank_crc, u_int32_t off, u_int32_t crc_act, u_int32_t crc_exp, bool ignore_crc, + VerifyCallBack verifyCallBackFunc) +{ + + if (!blank_crc && crc_exp != crc_act) { + report_callback(verifyCallBackFunc, "%s /0x%08x/ - wrong CRC (exp:0x%x, act:0x%x)\n", + pr, off, crc_exp, crc_act); + return errmsg(BAD_CRC_MSG); + } + // if (_print_crc) { + // TODO: Print CRC here. + if (0) { + report_callback(verifyCallBackFunc, "%s - OK (CRC:0x%04x)\n", pr, crc_act & 0xffff); + } else { + if (ignore_crc) { + report_callback(verifyCallBackFunc, "%s - CRC IGNORED\n", pr); + } else { + if (blank_crc) { + report_callback(verifyCallBackFunc, "%s - BLANK CRC (0xffff)\n", pr); + } else { + report_callback(verifyCallBackFunc, "%s - OK\n", pr); + } + } + } + return true; +} + +bool FwOperations::FwVerLessThan(u_int16_t r1[3], u_int16_t r2[3]) { + int i; + for (i = 0; i < 3 ; i++) + if (r1[i] < r2[i]) + return true; + else if (r1[i] > r2[i]) + return false; + + return false; // equal versions +} +const u_int32_t FwOperations::_cntx_magic_pattern[4] = { + 0x4D544657, // Ascii of "MTFW" + 0x8CDFD000, // Random data + 0xDEAD9270, + 0x4154BEEF +}; + +const u_int32_t FwOperations::_cntx_image_start_pos[FwOperations::CNTX_START_POS_SIZE] = { + 0, + 0x10000, + 0x20000, + 0x40000, + 0x80000, + 0x100000, + 0x200000 +}; + +bool FwOperations::CntxFindMagicPattern (FBase* ioAccess, u_int32_t addr) { + int i; + if (addr + 16 > ioAccess->get_size()) { + return false; + } + for (i = 0; i < 4 ; i++) { + u_int32_t w; + READ4_NOERRMSG((*ioAccess), addr + i * 4, &w); + TOCPU1(w); + if (w != _cntx_magic_pattern[i]) { + //printf("-D- Looking for magic pattern %d addr %06x: Exp=%08x Act=%08x\n", i, addr + i * 4, _cntx_magic_pattern[i], w); + return false; + } + } + + return true; +} + + + +// FindAllImageStart +// OUT: start_locations: set to the start addresses of the found image markers (in accending order) +// OUT: found_images: Number of found images (and number of valid entries in the start_locations array). +bool FwOperations::CntxFindAllImageStart (FBase* ioAccess, u_int32_t start_locations[CNTX_START_POS_SIZE], u_int32_t* found_images) { + int i; + int needed_pos_num; + + needed_pos_num = CNTX_START_POS_SIZE; + + if (ioAccess->is_flash()) { + if ( (((Flash*)ioAccess)->get_dev_id() == 400) || + (((Flash*)ioAccess)->get_dev_id() == 435) || + (((Flash*)ioAccess)->get_dev_id() == 6100)) { + needed_pos_num = OLD_CNTX_START_POS_SIZE; + } + } + + ioAccess->set_address_convertor(0,0); + *found_images = 0; + for (i = 0; i < needed_pos_num; i++) { + if (CntxFindMagicPattern(ioAccess, _cntx_image_start_pos[i])) { + start_locations[*found_images] = _cntx_image_start_pos[i]; + (*found_images)++; + } + } + + return true; +} + + + +// CAN BE IN ANOTHER MODULE +bool FwOperations::GetSectData(std::vector& file_sect, const u_int32_t *buff, const u_int32_t size) { + + file_sect.clear(); + file_sect.insert(file_sect.end(), + (u_int8_t*)buff, + (u_int8_t*)buff + size); + + + return true; +} + + +bool FwOperations::FwAccessCreate(fw_ops_params_t& fwParams, FBase **ioAccessP) +{ + // FBase *ioAccess = *ioAccessP; + + if (fwParams.hndlType == FHT_FW_FILE) { +#ifndef NO_MFA_SUPPORT + int sig = getFileSignature(fwParams.fileHndl); + if (sig == IMG_SIG_OPEN_FILE_FAILED) { //i.e we failed to open file + WriteToErrBuff(fwParams.errBuff, strerror(errno), fwParams.errBuffSize); + return false; + } + if (sig == IMG_SIG_TYPE_BIN) { + *ioAccessP = new FImage; + if (!(*ioAccessP)->open(fwParams.fileHndl, false)) { + WriteToErrBuff(fwParams.errBuff,(*ioAccessP)->err(), fwParams.errBuffSize); + delete *ioAccessP; + return false; + } + } else if (sig == IMG_SIG_TYPE_MFA) { + u_int8_t* imgbuf; + int sz; + if ((sz = getMfaImg(fwParams.fileHndl, fwParams.psid, &imgbuf)) < 0) { + WriteToErrBuff(fwParams.errBuff,"Failed to get MFA Image.", fwParams.errBuffSize); + return false; + } + *ioAccessP = new FImage; + if (!((FImage*)(*ioAccessP))->open((u_int32_t*)imgbuf, (u_int32_t)sz)) { + mfa_release_image(imgbuf); + WriteToErrBuff(fwParams.errBuff,(*ioAccessP)->err(), fwParams.errBuffSize); + delete *ioAccessP; + return false; + } + mfa_release_image(imgbuf); + } else { + WriteToErrBuff(fwParams.errBuff,"Invalid Image signature.", fwParams.errBuffSize); + return false; //Unknown signature + } +#else + *ioAccessP = new FImage; + if (!(*ioAccessP)->open(fwParams.fileHndl, false)) { + WriteToErrBuff(fwParams.errBuff,(*ioAccessP)->err(), fwParams.errBuffSize); + delete *ioAccessP; + return false; + } +#endif + } else if (fwParams.hndlType == FHT_FW_BUFF) { + u_int32_t numInfo = fwParams.buffSize; +#ifndef NO_MFA_SUPPORT + int sig = getBufferSignature((u_int8_t*)fwParams.buffHndl, numInfo); + if (sig == IMG_SIG_TYPE_BIN) { + *ioAccessP = new FImage; + if (!((FImage*)*ioAccessP)->open(fwParams.buffHndl, (u_int32_t)numInfo)) { + WriteToErrBuff(fwParams.errBuff,(*ioAccessP)->err(), fwParams.errBuffSize); + delete *ioAccessP; + return false; + } + } else if (sig == IMG_SIG_TYPE_MFA) { + u_int8_t* imgbuf; + int sz; + if ((sz = getMfaImg((u_int8_t*)fwParams.buffHndl, numInfo, fwParams.psid, &imgbuf)) < 0) { + WriteToErrBuff(fwParams.errBuff,"Failed to get MFA Image.", fwParams.errBuffSize); + return false; + } + *ioAccessP = new FImage; + if (!((FImage*)*ioAccessP)->open((u_int32_t*)imgbuf, (u_int32_t)sz)) { + mfa_release_image(imgbuf); + WriteToErrBuff(fwParams.errBuff,(*ioAccessP)->err(), fwParams.errBuffSize); + delete *ioAccessP; + return false; + } + mfa_release_image(imgbuf); + } else { + WriteToErrBuff(fwParams.errBuff,"Invalid Image signature.", fwParams.errBuffSize); + return false;//Unknown signature + } +#else + *ioAccessP = new FImage; + if (!((FImage*)*ioAccessP)->open(fwParams.buffHndl, numInfo)) { + WriteToErrBuff(fwParams.errBuff,(*ioAccessP)->err(), fwParams.errBuffSize); + delete *ioAccessP; + return false; + } +#endif + } else if (fwParams.hndlType == FHT_UEFI_DEV) { + *ioAccessP = new Flash; + if (!((Flash*)*ioAccessP)->open(fwParams.uefiHndl, fwParams.uefiExtra)) { + WriteToErrBuff(fwParams.errBuff,(*ioAccessP)->err(), fwParams.errBuffSize); + delete *ioAccessP; + return false; + } + } else if (fwParams.hndlType == FHT_MST_DEV) { + *ioAccessP = new Flash; + //set no flash verify if needed + ((Flash*)*ioAccessP)->set_no_flash_verify(fwParams.noFlashVerify); + if ( !((Flash*)*ioAccessP)->open(fwParams.mstHndl, fwParams.forceLock, fwParams.readOnly, fwParams.numOfBanks,\ + fwParams.flashParams, fwParams.ignoreCacheRep)) { + // TODO: release memory here ? + WriteToErrBuff(fwParams.errBuff,(*ioAccessP)->err(), fwParams.errBuffSize); + delete *ioAccessP; + return false; + } + } else { + WriteToErrBuff(fwParams.errBuff,"Unknown Handle Type.", fwParams.errBuffSize); + return false; + } + return true; +} + +u_int8_t FwOperations::CheckFwFormat(FBase& f, bool getFwFormatFromImg) { + if (f.is_flash() && !getFwFormatFromImg) { + if ( ( ((Flash*)&f)->get_dev_id() == 400) || + ( ((Flash*)&f)->get_dev_id() == 435) || + ( ((Flash*)&f)->get_dev_id() == CX3_HW_ID) || + ( ((Flash*)&f)->get_dev_id() == SWITCHX_HW_ID) || + ( ((Flash*)&f)->get_dev_id() == 6100) || + ( ((Flash*)&f)->get_dev_id() == CX3_PRO_HW_ID)) { + return FS_FS2_GEN; + } else if ( ((Flash*)&f)->get_dev_id() == CONNECT_IB_HW_ID) { + return FS_FS3_GEN; + } + } else { + u_int32_t found_images; + u_int32_t image_start[CNTX_START_POS_SIZE]; + + // Image - check if magic pattern is somewhere in the file: + CntxFindAllImageStart(&f, image_start, &found_images); + if (found_images) { + u_int32_t data; + u_int8_t image_version; + READ4_NOERRMSG(f, FS3_IND_ADDR, &data); + TOCPU1(data); + image_version = data >> 24; + if (image_version == IMG_VER_FS3) { + return FS_FS3_GEN; + } else { + // TODO: if the img format version is unknown we should fail instead of considering it FS2 + return FS_FS2_GEN; + } + } + } + return FS_OLD_GEN; +} + +FwOperations* FwOperations::FwOperationsCreate(void* fwHndl, void *info, char* psid, fw_hndl_type_t hndlType, char* errBuff, int buffSize) +{ + fw_ops_params_t fwParams; + fwParams.psid = psid; + fwParams.hndlType = hndlType; + fwParams.errBuff = errBuff; + fwParams.errBuffSize = buffSize; + + if (hndlType == FHT_FW_FILE) { + fwParams.fileHndl = (char*)fwHndl; + }else if (hndlType == FHT_FW_BUFF) { + fwParams.buffHndl = (u_int32_t*)fwHndl; + fwParams.buffSize = *((u_int32_t*)info); + }else if (hndlType == FHT_UEFI_DEV) { + fwParams.uefiHndl = (uefi_Dev_t*)fwHndl; + fwParams.uefiExtra = (f_fw_cmd)info; + }else if (hndlType == FHT_MST_DEV) { + fwParams.mstHndl = (char*)fwHndl; + fwParams.forceLock = false; + fwParams.readOnly = false; + fwParams.numOfBanks = 4; + fwParams.flashParams = (flash_params_t*)NULL; + fwParams.ignoreCacheRep = 0; + fwParams.noFlashVerify = false; + } + return FwOperationsCreate(fwParams); +} + +FwOperations* FwOperations::FwOperationsCreate(fw_ops_params_t& fwParams) +{ + FwOperations* fwops; + u_int8_t fwFormat; + FBase *ioAccess; + bool getFwFormatFromImg = false; + + if (!FwAccessCreate(fwParams, &ioAccess)) { + + return (FwOperations*)NULL; + } + if (fwParams.hndlType == FHT_UEFI_DEV) { + // IN UEFI we don't have an access to read devID from cr-space so we are reading it from FW image signature + getFwFormatFromImg = true; + } + fwFormat = CheckFwFormat(*ioAccess, getFwFormatFromImg); + switch (fwFormat) { + case FS_FS2_GEN: { + fwops = new Fs2Operations(ioAccess); + break; + } + case FS_FS3_GEN: { + fwops = new Fs3Operations(ioAccess); + break; + } + default: + delete ioAccess; + WriteToErrBuff(fwParams.errBuff,"invalid Firmware Format (found FS Gen 1)", fwParams.errBuffSize); + return (FwOperations*)NULL; + } + fwops->FwInit(); + if (fwParams.hndlType == FHT_FW_FILE) { + fwops->_fname = strcpy(new char[strlen(fwParams.fileHndl)+ 1], fwParams.fileHndl); + } + return fwops; +} + +u_int32_t FwOperations::CalcImageCRC(u_int32_t* buff, u_int32_t size) +{ + Crc16 crc; + TOCPUn(buff, size); + CRCn(crc, buff, size); + CPUTOn(buff, size); + crc.finish(); + u_int32_t new_crc = crc.get(); + return new_crc; +} + +bool FwOperations::writeImage(ProgressCallBack progressFunc, u_int32_t addr, void *data, int cnt, bool is_phys_addr) +{ + u_int8_t *p = (u_int8_t *)data; + u_int32_t curr_addr = addr; + u_int32_t towrite = cnt; + u_int32_t perc = 0xffffffff; + bool rc; +// if (!_ioAccess->is_flash()) { + // return errmsg("Internal error: writeImage is supported only on flash."); + // } + while (towrite) { + // Write + int trans; + if (_ioAccess->is_flash()) { + trans = (towrite > (int)Flash::TRANS) ? (int)Flash::TRANS : towrite; + if (is_phys_addr) { + rc = ((Flash*)_ioAccess)->write_phy(curr_addr, p, trans); + } else { + rc = ((Flash*)_ioAccess)->write(curr_addr, p, trans); + } + if (!rc) { + return errmsg("Flash write failed: %s", _ioAccess->err()); + } + } else { + trans = towrite; + if (!ModifyImageFile(_fname, curr_addr, p, trans)) { + return false; + } + } + p += trans; + curr_addr += trans; + towrite -= trans; + + // Report + if (progressFunc != NULL) { + u_int32_t new_perc = ((cnt - towrite) * 100) / cnt; + + if (progressFunc((int)new_perc)) { + return errmsg("Aborting... recieved interrupt signal"); + } + perc = new_perc; + } + } + + return true; +} // Flash::WriteImage + +bool FwOperations::ModifyImageFile(char *fimage, u_int32_t addr, void *data, int cnt) +{ + int file_size; + u_int8_t * file_data; + + if (!ReadImageFile(fimage, file_data, file_size, addr + cnt)) { + return false; + } + memcpy(&file_data[addr], data, cnt); + + if (!WriteImageToFile(fimage, file_data, file_size)) { + delete[] file_data; + return false; + } + delete[] file_data; + return true; +} + +bool FwOperations::WriteImageToFile(char *file_name, u_int8_t *data, u_int32_t length) +{ + FILE* fh; + if ((fh = fopen(file_name, "wb")) == NULL) { + return errmsg("Can not open %s: %s\n", file_name, strerror(errno)); + } + + // Write output + if (fwrite(data, 1, length, fh) != length) { + fclose(fh); + return errmsg("Failed to write to %s: %s\n", file_name, strerror(errno)); + } + fclose(fh); + return true; +} + +bool FwOperations::CheckMac(u_int64_t mac) { + if ((mac >> 40) & 0x1) { + return errmsg("Multicast bit (bit 40) is set"); + } + + if (mac >> 48) { + return errmsg("More than 48 bits are used"); + } + + return true; +} + +void FwOperations::recalcSectionCrc(u_int8_t *buf, u_int32_t data_size) { + Crc16 crc; + u_int32_t i; + + for (i = 0; i < data_size; i += 4) { + crc << __be32_to_cpu(*(u_int32_t*)(buf + i)); + } + crc.finish(); + *(u_int32_t*)(buf + data_size) = __cpu_to_be32(crc.get()); +} + +chip_type_t FwOperations::getChipType() { + int i = 0; + while (hwDevData[i].name != NULL) { + int j = 0; + while (hwDevData[i].swDevIds[j] != 0) { + if (hwDevData[i].swDevIds[j] == _fwImgInfo.ext_info.dev_type) { + return hwDevData[i].chipType; + } + j++; + } + i++; + } + return CT_UNKNOWN; +} + +chip_type_t FwOperations::getChipTypeFromHwDevid(u_int32_t hwDevId) { + int i = 0; + while (hwDevData[i].name != NULL) { + if (hwDevData[i].hwDevId == hwDevId) { + return hwDevData[i].chipType; + } + i++; + } + return CT_UNKNOWN; +} + +// TODO:combine both databases(hwDevData and hwDev2Str) and remove old unsupporded devices i.e tavor arbel sinai +const FwOperations::HwDevData FwOperations::hwDevData[] = { + { "InfiniHost", TAVOR_HW_ID, CT_UNKNOWN, 2, {23108, 0}}, + { "InfiniHost III Ex", ARBEL_HW_ID, CT_UNKNOWN,2 , {25208, 25218, 0}}, + { "InfiniHost III Lx", SINAI_HW_ID, CT_UNKNOWN, 1, {25204, 0}}, + { "ConnectX", CX_HW_ID, CT_CONNECTX, 2, {25408, 25418, 26418, 26438, + 26428, 25448, 26448, 26468, + 25458, 26458, 26478, 26488, + 4097, 4098, 0}}, + { "ConnectX3", CX3_HW_ID, CT_CONNECTX, 2, {4099, 4100, 4101, 4102, + 4103, 4104, 4105, 4106, + 4107, 4108, 4109, 4110, + 4111, 4112, 0}}, + { "Connect_IB", CONNECT_IB_HW_ID, CT_CONNECT_IB, 2, {CONNECT_IB_SW_ID, 4114, 4115, 4116, + 4117, 4118, 4119, 4120, + 4121, 4122, 4123, 4124, 0}}, + { "InfiniScale IV", IS4_HW_ID, CT_IS4, 0, {48436, 48437, 48438, 0}}, + { "BridgeX", BRIDGEX_HW_ID, CT_BRIDGEX, 0, {64102, 64112, 64122, 0}}, + { "SwitchX", SWITCHX_HW_ID, CT_SWITCHX, 0, {51000, 0}}, + { (char*)NULL , 0, CT_UNKNOWN, 0, {0}},// zero devid terminator +}; + +const FwOperations::HwDev2Str FwOperations::hwDev2Str[] = { + {"ConnectIB", CONNECT_IB_HW_ID, 0x00}, + {"ConnectX", CX_HW_ID, 0xA0}, + {"ConnectX-2", CX_HW_ID, 0xB0}, + {"ConnectX-3 A0", CX3_HW_ID, 0x00}, + {"ConnectX-3 A1", CX3_HW_ID, 0x01}, + {"SwitchX A0", SWITCHX_HW_ID, 0x00}, + {"SwitchX A1", SWITCHX_HW_ID, 0x01}, + {"BridgeX", BRIDGEX_HW_ID, 0xA0}, + {"InfiniScale IV A0", IS4_HW_ID, 0xA0}, + {"InfiniScale IV A1", IS4_HW_ID, 0xA1}, + {"InfiniHost A0", TAVOR_HW_ID, 0xA0}, + {"InfiniHost A1", TAVOR_HW_ID, 0xA1}, + {"InfiniHost III Lx", SINAI_HW_ID, 0xA0}, + {"InfiniHost III Ex", ARBEL_HW_ID, 0xA0}, + { (char*)NULL , 0, 0x00}, // zero device ID terminator +}; + +#define ARR_SIZE(arr) sizeof(arr)/sizeof(arr[0]) +#define MAX_HW_NAME_LEN 100 +bool FwOperations::HWIdRevToName(u_int32_t hw_id, u_int8_t rev_id, char *hw_name) +{ + int i; + + for (i = 0; hwDev2Str[i].hwDevId != 0; i++) { + const HwDev2Str *hwDev2StrMem = &(hwDev2Str[i]); + + if (hwDev2StrMem->hwDevId == hw_id && hwDev2StrMem->revId == rev_id) { + int len = strlen(hwDev2StrMem->name); + if (len >= MAX_HW_NAME_LEN) { + return errmsg("Internal error: Length of device name: %d exceeds the maximum allowed size: %d", len, MAX_HW_NAME_LEN - 1); + } + strcpy(hw_name, hwDev2StrMem->name); + return true; + } + } + // When the device or rev is unknown we use the hw ID and rev to display it. + sprintf(hw_name, "MT%d-%02X", hw_id, rev_id); + return true; +} + + +// This function gets the HW ID of the target device and the dev ID from +// the image. It then matches the 2 IDs and returns an error in case of +// missmatch. The match is not 1:1 , since the FW image contains the SW +// dev id, and a single hw dev id may match multiple SW dev IDs. +// +bool FwOperations::CheckMatchingHwDevId(u_int32_t hwDevId, u_int32_t rev_id, u_int32_t* supportedHwId, u_int32_t supportedHwIdNum) { + + u_int32_t i; + char supp_hw_id_list[MAX_NUM_SUPP_HW_LIST_STR] = {'\0'}; + char supp_hw_id_list_tmp[MAX_NUM_SUPP_HW_LIST_STR]; + char curr_hw_id_name[MAX_HW_NAME_LEN]; + + for (i = 0; i < supportedHwIdNum; i++) { + u_int32_t currSupportedHwId = supportedHwId[i]; + u_int32_t supp_hw_id = currSupportedHwId & 0xffff; + u_int32_t supp_rev_id = (currSupportedHwId >> 16) & 0xff; + u_int32_t tmp_size_of_list; + char hw_name[MAX_HW_NAME_LEN]; + + if (currSupportedHwId == 0) { + break; + } + // Check if device is supported! + if ( supp_hw_id == hwDevId && supp_rev_id == rev_id) { + return true; + } + // Append checked to list of supported device in order to print it in the error if we this device is not supported + + // Get the HW name of current supported HW ID + if (!HWIdRevToName(supp_hw_id, supp_rev_id, hw_name)) { + return false; + } + // Check if we don't exceed the array size we have + tmp_size_of_list = strlen(supp_hw_id_list) + strlen(hw_name) + 2; + if (tmp_size_of_list >= MAX_NUM_SUPP_HW_LIST_STR) { + return errmsg("Internal error: Size of supported devs list: %d exceeds the maximum allowed size: %d", + tmp_size_of_list, MAX_NUM_SUPP_HW_LIST_STR - 1); + } + + if (supp_hw_id_list[0] == '\0') { + sprintf(supp_hw_id_list, "%s", hw_name); + } else { + strcpy(supp_hw_id_list_tmp, supp_hw_id_list); + sprintf(supp_hw_id_list, "%s, %s", supp_hw_id_list_tmp, hw_name); + } + } + // If we get here, this FW cannot be burnt in the current device. + // Get the Device name + if (!HWIdRevToName(hwDevId, rev_id, curr_hw_id_name)) { + return false; + } + + return errmsg("FW image file cannot be programmed to device %s, it is intended for: %s only", + curr_hw_id_name, supp_hw_id_list); +} +bool FwOperations::CheckMatchingDevId(u_int32_t hwDevId, u_int32_t imageDevId) { + + int i, j; + const HwDevData* devData = (const HwDevData*)NULL; + const char* hwDevName = (const char*)NULL; + // HACK: InfiniHost III LX may have 2 HW device ids. - Map the second devid to the first. + if (hwDevId == 24204) { + hwDevId = 25204; + } + + // First, find the HW device that the SW id matches + for (i = 0; hwDevData[i].hwDevId != 0 ; i++) { + if (hwDevData[i].hwDevId == hwDevId) { + hwDevName = hwDevData[i].name; // TODO: Check bug if device not found + } + + if (devData == NULL) { + for (j = 0; hwDevData[i].swDevIds[j]; j++) { + if (hwDevData[i].swDevIds[j] == imageDevId) { + devData = &hwDevData[i]; + break; + } + } + } + } + + if (devData == NULL) { + report_warn("Unknown device id (%d) in the given FW image. Skipping HW match check.\n", + imageDevId); + return true; + } else if (devData->hwDevId != hwDevId) { + return errmsg("Trying to burn a \"%s\" image on a \"%s\" device.", + devData->name, + hwDevName); + } + + return true; +} + +void FwOperations::FwDebugPrint(char *str) +{ + if (_printFunc != NULL) { + _printFunc(str); + } +} + +bool FwOperations::FwSetPrint(PrintCallBack PrintFunc) +{ + _printFunc = PrintFunc; + return true; +} + +bool FwOperations::CheckPSID(FwOperations &imageOps, u_int8_t allow_psid_change) +{ + if (!allow_psid_change) { + if (strncmp( _fwImgInfo.ext_info.psid, imageOps._fwImgInfo.ext_info.psid, PSID_LEN)) { + return errmsg("Image PSID is %s, it cannot be burnt into current device (PSID: %s)", + imageOps._fwImgInfo.ext_info.psid, _fwImgInfo.ext_info.psid); + } + } + return true; +} + +bool FwOperations::CheckFwVersion(FwOperations &imageOps, u_int8_t forceVersion) +{ + bool updateRequired = true; + if (!forceVersion) { + updateRequired = FwVerLessThan(_fwImgInfo.ext_info.fw_ver, imageOps._fwImgInfo.ext_info.fw_ver); + if (!updateRequired) { + return errmsg("FW is already updated."); + } + } + return true; +} + +bool FwOperations::FwSwReset() { + if (!_ioAccess->is_flash()) { + return errmsg("operation supported only for switch devices InfiniScaleIV and SwitchX over an IB interface"); + } + if (!((Flash*)_ioAccess)->sw_reset()) { + return errmsg(_ioAccess->err()); + } + return true; +} + + +void FwOperations::WriteToErrBuff(char* errBuff, const char* errStr, int size) +{ + if (size>0) { + if (size-4 > (int) strlen(errStr)) { + strncpy(errBuff, errStr, size); + } else { + strncpy(errBuff, errStr, size-4); + strcpy(&errBuff[size-4], "..."); + } + } + return; +} + +bool FwOperations::UpdateImgCache(u_int8_t *buff, u_int32_t addr, u_int32_t size) +{ + //avoid compiler warrnings + buff = NULL; + addr = 0; + size = 0; + //in FS2 we dont have ImgCache, just in FS3 so we define a defult behaviour. + return true; +} + +bool FwOperations::CntxEthOnly(u_int32_t devid) +{ + return(devid == 25448) || // ETH + (devid == 26448) || // ETH + (devid == 25458) || // + (devid == 26458) || // + (devid == 26468) || + (devid == 26478); +} + +// RomInfo implementation + +FwOperations::RomInfo::RomInfo(const std::vector& romSector, bool resEndi) +{ + expRomFound = !romSector.empty(); + romSect = romSector; + if (resEndi) { + TOCPUn(&romSect[0], romSect.size()/4); + } + numOfExpRom = 0; + expRomComDevid = 0; + expRomWarning = false; + expRomErrMsgValid = false; + noRomChecksum = false; +} + + +bool FwOperations::RomInfo::initRomsInfo(roms_info_t *info) +{ + if (info == NULL) { + return errmsg("invalid roms_info_t pointer."); + } + info->exp_rom_found = expRomFound; + info->num_of_exp_rom = numOfExpRom; + info->no_rom_checksum = noRomChecksum; + info->exp_rom_com_devid = expRomComDevid; + info->exp_rom_warning = expRomWarning; + info->exp_rom_err_msg_valid = expRomErrMsgValid; + //copy strings and rom_info + for (int i=0; i< MAX_ROM_ERR_MSG_LEN; i++) { + info->exp_rom_warning_msg[i] = expRomWarningMsg[i]; + info->exp_rom_err_msg[i] = expRomErrMsg[i]; + } + for (int i=0; i< MAX_ROMS_NUM; i++) { + //copy rom_info struct + info->rom_info[i].exp_rom_product_id = romsInfo[i].exp_rom_product_id; // 0 - invalid. + info->rom_info[i].exp_rom_dev_id = romsInfo[i].exp_rom_dev_id; + info->rom_info[i].exp_rom_port = romsInfo[i].exp_rom_port; + info->rom_info[i].exp_rom_proto = romsInfo[i].exp_rom_proto; + info->rom_info[i].exp_rom_num_ver_fields = romsInfo[i].exp_rom_num_ver_fields; + for (int j=0; j< 3 ; j++) { + info->rom_info[i].exp_rom_ver[j] = romsInfo[i].exp_rom_ver[j]; + } + } + + return true; +} + +bool FwOperations::RomInfo::ParseInfo() +{ + if (!GetExpRomVersion()) { + snprintf(expRomErrMsg, MAX_ROM_ERR_MSG_LEN, err()); + expRomErrMsgValid = true; + //printf("-D-expRomErrMsg: %s \n", expRomErrMsg); + } + //printf("-D- expRomFound: %d \n",expRomFound); + //printf("-D- numOfExpRom: %d \n",numOfExpRom); + //printf("-D- noRomChecksum: %d \n",noRomChecksum); + //printf("-D- expRomComDevid: %d \n",expRomComDevid); + //printf("-D- expRomWarning: %d \n",expRomWarning); + //printf("-D- expRomErrMsgValid: %d \n",expRomErrMsgValid); + return true; +} + +#define MAGIC_LEN 32 + +bool FwOperations::RomInfo::GetExpRomVersion() +{ + char magicString[MAGIC_LEN] = {"mlxsignX"}; + u_int32_t magicLen = strlen(magicString); + u_int32_t i; + bool magicFound = false; + u_int32_t verOffset; + u_int32_t romChecksumRange; + + // We do this HACK in order not to have mlxsign: word in our code so if mlxfwops will be part + // of rom, no mlxsign: string will appear + magicString[magicLen - 1] = ':'; + + if (romSect.empty()) { + return errmsg("Expansion Rom section not found."); + } + // When checking the version of the expansion rom, only the first image has + // to be checked. This is because the second image the uefi image does not + // have to comply with checksumming to 0. To do this you have to read byte + // 2 (third) of the image and multiply by 512 to get the size of the x86 + // image. + + // Checksum: + if (romSect.size() < 4) { + return errmsg("ROM size (0x%x) is too small", + (u_int32_t) romSect.size()); + } + + // restore endianess is done in the constructor if needed. + /* // FOR WE DON'T CHECKSUM UNTIL WE DECIDED REGARDING THE NEW FORMAT. + */ + // We will look for the magic string in whole ROM instead of the first part of it. + romChecksumRange = romSect.size(); + + for (i = 0; i < romChecksumRange; i++) { + for (u_int32_t j = 0; j < magicLen; j++) { + if (romSect[i + j] != magicString[j]) { + break; + } else if (j == magicLen - 1) { + magicFound = true; + } + } + + + if (magicFound) { + // Get the ROM info after the mlxsign + bool rc; + rom_info_t *currRom; + + if (numOfExpRom == MAX_ROMS_NUM) { + expRomWarning = true; + snprintf(expRomWarningMsg, + MAX_ROM_ERR_MSG_LEN, + "Number of exp ROMs exceeds the maximum allowed number (%d)", + MAX_ROMS_NUM); + // Here we want to warn regarding this issue without checksum. + return true; + } + + currRom = &(romsInfo[numOfExpRom]); + verOffset = i + magicLen; + rc = GetExpRomVerForOneRom(verOffset); + if (rc != true) { + return rc; + } + + // Get the device ID and check if it mismatches with other ROMs + if (expRomComDevid != MISS_MATCH_DEV_ID) { // When the DevId is already mismatched, no end to any check + if (currRom->exp_rom_dev_id != EXP_ROM_GEN_DEVID) { // When we have a device ID on the ROM + if (expRomComDevid == EXP_ROM_GEN_DEVID) { // Update the common DevId at the first time we find ID + expRomComDevid = currRom->exp_rom_dev_id; + } else { // Check if we have the same IDs, if yes, continue + if (currRom->exp_rom_dev_id != expRomComDevid) { // There is a mismatch between ROMs + expRomComDevid = MISS_MATCH_DEV_ID; + expRomWarning = true; + snprintf(expRomWarningMsg, + MAX_ROM_ERR_MSG_LEN, + "The device IDs of the ROMs mismatched."); + } + } + } + } + + magicFound = false; // Clean the magic_found to start search for another magic string + i += (ROM_INFO_SIZE - 1); // Increase the index to point to the end of the ROM info. + numOfExpRom++; + } + } + + // TODO: ADD CHECKSUM CHECK + if (!numOfExpRom) { + return errmsg("Cannot get ROM version. Signature not found."); + + } + + if (noRomChecksum == 0) { // No need for checksum on some ROMs like uEFI + u_int8_t romChecksum = 0; + romChecksumRange = romSect[2] * 512; + if (romChecksumRange > romSect.size()) { + return errmsg( + "ROM size field (0x%2x) is larger than actual ROM size (0x%x)", + romChecksumRange, (u_int32_t) romSect.size()); + } else if (romChecksumRange == 0) { + return errmsg( + "ROM size field is 0. Unknown ROM format or corrupted ROM."); + } + + for (i = 0; i < romChecksumRange; i++) { + romChecksum += romSect[i]; + } + + if (romChecksum != 0) { + expRomWarning = true; + snprintf( + expRomWarningMsg, + MAX_ROM_ERR_MSG_LEN, + "Bad ROM Checksum (0x%02x), ROM info may not be displayed correctly.", + romChecksum); + } + } + + return true; +} + +bool FwOperations::RomInfo::GetExpRomVerForOneRom(u_int32_t verOffset) +{ + + u_int32_t tmp; + rom_info_t *romInfo; + + if (numOfExpRom == MAX_ROMS_NUM) { + expRomWarning = true; + snprintf(expRomWarningMsg, + MAX_ROM_ERR_MSG_LEN, + "Number of exp ROMs exceeds the maximum allowed number: %d", + MAX_ROMS_NUM); + return true; + } + romInfo = &(romsInfo[numOfExpRom]); + + // Following mlxsign: + // 31:24 0 Compatible with UEFI + // 23:16 ProductID Product ID: + // 1 - CLP implementation for Sinai (MT25408) + // 2 - CLP implementation for Hermon DDR (MT25418) + // 0X10 - PXE + // 15:0 Major version If ProductID < 0x10 this field is subversion + // number, otherwise It's product major version. + // + // 31:16 Minor version Product minor version*. Not valid if + // roductID < 0x10. + // 15:0 SubMinor version Product sub minor version*. Not valid if + // ProductID < 0x10. + // + // 31:16 Device ID The PCI Device ID (ex. 0x634A for Hermon + // DDR). Not valid if ProductID < 0x10. + // 15:12 Port Number Port number: 0 - Port independent, 1 - Port 1, 2 - Port 2 + // 8:11 Reserved + // 0:7 Protocol type: 0=IB 1=ETH 2=VPI + + // Get expansion rom product ID + tmp = __le32_to_cpu(*((u_int32_t*) &romSect[verOffset])); + romInfo->exp_rom_product_id = tmp >> 16; + romInfo->exp_rom_ver[0] = tmp & 0xffff; + + if (romInfo->exp_rom_product_id < 0xF) { + romInfo->exp_rom_num_ver_fields = 1;//For CLPs + } else if (romInfo->exp_rom_product_id == 0xF) { + romInfo->exp_rom_num_ver_fields = 0; + } else { // >= 0x10 + romInfo->exp_rom_num_ver_fields = 3; + } + + if (romInfo->exp_rom_product_id == 0x11 || romInfo->exp_rom_product_id == 0x21) { + noRomChecksum = true; + } + + if (romInfo->exp_rom_product_id >= 0x10) { + tmp = __le32_to_cpu(*((u_int32_t*) &romSect[verOffset + 4])); + romInfo->exp_rom_ver[1] = tmp >> 16; + romInfo->exp_rom_ver[2] = tmp & 0xffff; + + tmp = __le32_to_cpu(*((u_int32_t*) &romSect[verOffset + 8])); + romInfo->exp_rom_dev_id = tmp >> 16; + romInfo->exp_rom_port = (tmp >> 12) & 0xf; + romInfo->exp_rom_proto = tmp & 0xff; + } else if (romInfo->exp_rom_product_id == 0xf) { + // get string length + u_int32_ba tmp_ba = *((u_int32_t*) &romSect[verOffset + 0xc]); + u_int32_t str_len = u_int32_t(tmp_ba.range(15, 8)); + u_int32_t sign_length = u_int32_t(tmp_ba.range(7, 0)); + u_int32_t dws_num = ((str_len + 3) / 4) + 4; + + if (sign_length < dws_num) { + return errmsg( + "The Signature length (%d) and the ROM version string length (%d) are not coordinated", + sign_length, str_len); + } + + int svnv; + char free_str[FREE_STR_MAX_LEN]; + strncpy(free_str,(char*) &romSect[verOffset + 0x10], str_len); + free_str[str_len] = '\0'; + if (sscanf((char*) free_str, "%d", &svnv) == 1) { + romInfo->exp_rom_ver[0] = svnv; + } + + tmp_ba = __le32_to_cpu(*((u_int32_t*) &romSect[0x18])); + u_int32_t dev_id_off = u_int32_t(tmp_ba.range(15, 0)) + 4; + + if (dev_id_off >= romSect.size()) { + return errmsg( + "The device ID offset %#x is out of range. ROM size: %#x", + dev_id_off, (u_int32_t) romSect.size()); + } + + // get devid + tmp_ba = __le32_to_cpu(*((u_int32_t*) &romSect[dev_id_off])); + romInfo->exp_rom_dev_id = u_int32_t(tmp_ba.range(31, 16)); + u_int32_t vendor_id = u_int32_t(tmp_ba.range(15, 0)); + + if (vendor_id != MELLANOX_VENDOR_ID) { + expRomWarning = true; + snprintf(expRomWarningMsg, + MAX_ROM_ERR_MSG_LEN, + "The Exp-ROM PCI vendor ID: %#x does not match the expected value: %#x.", + vendor_id, MELLANOX_VENDOR_ID); + } + + } + return true; +} + +bool FwOperations::ReadImageFile(char *fimage, u_int8_t *&file_data, int &file_size, int min_size) +{ + FILE* fh; + + if ((fh = fopen(fimage, "rb")) == NULL) { + return errmsg("Can not open %s: %s\n", fimage, strerror(errno)); + } + + if (fseek(fh, 0, SEEK_END) < 0) { + fclose(fh); + return errmsg("Failed to get size of the file \"%s\": %s\n", fimage, strerror(errno)); + } + + int read_file_size = ftell(fh); + if (read_file_size < 0) { + fclose(fh); + return errmsg("Failed to get size of the file \"%s\": %s\n", fimage, strerror(errno)); + } + rewind(fh); + + if (min_size > read_file_size) { + file_size = min_size; + } else { + file_size = read_file_size; + } + + file_data = new u_int8_t[file_size]; + if (fread(file_data, 1, read_file_size, fh) != (size_t)read_file_size) { + delete[] file_data; + fclose(fh); + return errmsg("Failed to read from %s: %s\n", fimage, strerror(errno)); + } + fclose(fh); + return true; +} + +void FwOperations::SetDevFlags(chip_type_t chipType, u_int32_t devType, fw_img_type_t fwType, bool &ibDev, bool ðDev) { + + if (chipType == CT_IS4) { + ibDev = true; + ethDev = false; + } else if (chipType == CT_SWITCHX) { + ibDev = true; + ethDev = true; + } else { + ibDev = (fwType == FIT_FS3) || !CntxEthOnly(devType); + ethDev = (fwType == FIT_FS2) && chipType == CT_CONNECTX; + } + + if ((!ibDev && !ethDev) || chipType == CT_UNKNOWN) { + // Unknown device id - for forward compat - assume that ConnectX is MP and + // prev HCAs are IB only (these flags are for printing only - no real harm can be done). + // TODO: FS2 does not mean ConnectX now. + ibDev = true; + if (fwType == FIT_FS2) { + ethDev = true; + } else { + ethDev = false; + } + } +} + +bool FwOperations::IsFwSupportingRomModify(u_int16_t fw_ver[3]) +{ + u_int16_t supported_fw[3] = {MAJOR_MOD_ROM_FW, MINOR_MOD_ROM_FW, SUBMINOR_MOD_ROM_FW}; + return !FwVerLessThan(fw_ver, supported_fw); +} + +bool FwOperations::checkMatchingExpRomDevId(const fw_info_t& info) +{ + /* + if ((info.fw_info.roms_info.num_of_exp_rom > 0) && (info.fw_info.dev_type) + && (info.fw_info.roms_info.exp_rom_com_devid != EXP_ROM_GEN_DEVID) \ + && (info.fw_info.roms_info.exp_rom_com_devid != MISS_MATCH_DEV_ID) + && (info.fw_info.dev_type != info.fw_info.roms_info.exp_rom_com_devid)) { + return false; + } + return true; */ + return checkMatchingExpRomDevId(info.fw_info.dev_type, info.fw_info.roms_info); +} + + +bool FwOperations::checkMatchingExpRomDevId(u_int16_t dev_type, roms_info_t roms_info) +{ + if ((roms_info.num_of_exp_rom > 0) && (dev_type) + && (roms_info.exp_rom_com_devid != EXP_ROM_GEN_DEVID) \ + && (roms_info.exp_rom_com_devid != MISS_MATCH_DEV_ID) + && (dev_type != roms_info.exp_rom_com_devid)) { + return false; + } + return true; +} + + +bool FwOperations::FwWriteBlock(u_int32_t addr, std::vector dataVec, ProgressCallBack progressFunc) +{ + if (dataVec.empty()) { + return errmsg("no data to write."); + } + // make sure we work on device + if (!_ioAccess->is_flash()) { + return errmsg("no flash detected.(command is only supported on flash)"); + } + + //check if flash is big enough + if ((addr + dataVec.size()) > ((Flash*)_ioAccess)->get_size()) { + return errmsg("Writing %#x bytes from address %#x is out of flash limits (%#x bytes)\n", + (unsigned int)(dataVec.size()), (unsigned int)addr, (unsigned int)_ioAccess->get_size()); + } + + if (!writeImage(progressFunc, addr, &dataVec[0], (int)dataVec.size())) { + return false; + } + return true; +}; + + +bool FwOperations::FwBurnData(u_int32_t *data, u_int32_t dataSize, ProgressCallBack progressFunc) { + FwOperations* newImgOps; + fwOpsParams imgOpsParams; + char errBuff[1024] = {0}; + + imgOpsParams.psid = NULL; + imgOpsParams.buffHndl = data; + imgOpsParams.buffSize = dataSize; + imgOpsParams.errBuff = errBuff; + imgOpsParams.errBuffSize = 1024; + imgOpsParams.hndlType = FHT_FW_BUFF; + + newImgOps = FwOperationsCreate(imgOpsParams); + if (newImgOps == NULL) { + return errmsg("FwOperationsCreate: %s", errBuff); // TODO: fix error message + } + if (!newImgOps->FwVerify(NULL)) { + newImgOps->FwCleanUp(); + delete newImgOps; + return errmsg("Internal error: Modifed image failed in verify"); + } + + ExtBurnParams burnParams = ExtBurnParams(); + burnParams.ignoreVersionCheck = true; + burnParams.progressFunc = progressFunc; + burnParams.useImagePs = true; + burnParams.useImageGuids = true; + burnParams.burnRomOptions = ExtBurnParams::BRO_ONLY_FROM_IMG; + + if (!FwBurnAdvanced(newImgOps, burnParams)) { + newImgOps->FwCleanUp(); + delete newImgOps; + return errmsg("Failed to re-burn image after modify: %s", err()); + } + newImgOps->FwCleanUp(); + delete newImgOps; + return true; +} + + +bool FwOperations::getRomsInfo(FBase* io, roms_info_t& romsInfo) +{ + std::vector romSector; + romSector.clear(); + romSector.resize(io->get_size()); + if (!io->read(0, &romSector[0], io->get_size())) { + return false; + } + RomInfo info(romSector, false); + info.ParseInfo(); + info.initRomsInfo(&romsInfo); + return true; +} + diff --git a/mlxfwops/lib/fw_ops.h b/mlxfwops/lib/fw_ops.h new file mode 100644 index 0000000..b437cbc --- /dev/null +++ b/mlxfwops/lib/fw_ops.h @@ -0,0 +1,347 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +#ifndef FW_OPS_H +#define FW_OPS_H + +#include "flint_base.h" +#include "flint_io.h" +#include "mlxfwops_com.h" + +typedef f_prog_func_str VerifyCallBack; +typedef f_prog_func ProgressCallBack; +typedef f_prog_func_str PrintCallBack; + +typedef int (*PrintCallBackAdv) (int completion, char* str); + +class MLXFWOP_API FwOperations : public ErrMsg { + + +public: + #define EXP_ROM_GEN_DEVID 0 + #define MISS_MATCH_DEV_ID 0xffff + class ExtBurnParams; + struct fwOpsParams; + struct sgParams; + typedef fwOpsParams fw_ops_params_t; + typedef sgParams sg_params_t; + // typedef std::tr1::function VerifyCallback; + + FwOperations(FBase *ioAccess) : + _ioAccess(ioAccess), _isCached(false), _wasVerified(false), + _quickQuery(false), _printFunc((PrintCallBack)NULL), _fname(NULL) {}; + + + virtual ~FwOperations() {}; + //virtual void print_type() {}; + virtual u_int8_t FwType() = 0; + static bool FwVerLessThan(u_int16_t r1[3], u_int16_t r2[3]); + static bool IsFwSupportingRomModify(u_int16_t fw_ver[3]); + static bool CntxEthOnly(u_int32_t devid); + static void SetDevFlags(chip_type_t chipType, u_int32_t devType, fw_img_type_t fwType, bool &ibDev, bool ðDev); + static bool checkMatchingExpRomDevId(const fw_info_t& info); + static bool checkMatchingExpRomDevId(u_int16_t dev_type, roms_info_t roms_info); + + + virtual bool FwQuery(fw_info_t *fwInfo, bool readRom = true, bool isStripedImage = false) = 0; + virtual bool FwVerify(VerifyCallBack verifyCallBackFunc, bool isStripedImage = false, bool showItoc = false) = 0; // Add callback print + virtual bool FwTest(u_int32_t *data) {data = (u_int32_t*)NULL; return false;}; // Add callback print + //on call of FwReadData with Null image we get image_size + virtual bool FwReadData(void* image, u_int32_t* image_size) = 0; + + virtual bool FwReadRom(std::vector& romSect) = 0; + virtual bool FwBurnRom(FImage* romImg, bool ignoreProdIdCheck = false, bool ignoreDevidCheck = false, ProgressCallBack progressFunc=(ProgressCallBack)NULL) = 0; // can also read the rom from flint and give a vector of u_int8_t + virtual bool FwDeleteRom(bool ignoreProdIdCheck, ProgressCallBack progressFunc=(ProgressCallBack)NULL) = 0; + + virtual bool FwBurn(FwOperations *imageOps, u_int8_t forceVersion, ProgressCallBack progressFunc=(ProgressCallBack)NULL) = 0; + virtual bool FwBurnAdvanced(FwOperations *imageOps, ExtBurnParams& burnParams) = 0; + virtual bool FwBurnBlock(FwOperations* imageOps, ProgressCallBack progressFunc) = 0; //Add: callback progress, question arr, callback question, configurations + bool FwWriteBlock(u_int32_t addr, std::vector dataVec, ProgressCallBack progressFunc=(ProgressCallBack)NULL); + + virtual bool FwSetGuids(sg_params_t& sgParam, PrintCallBack callBackFunc=(PrintCallBack)NULL, ProgressCallBack progressFunc=(ProgressCallBack)NULL) = 0; + + virtual bool FwSetMFG(guid_t baseGuid, PrintCallBack callBackFunc=(PrintCallBack)NULL) = 0; + // use progressFunc when dealing with FS2 image and printFunc when dealing with FS3 image. + virtual bool FwSetVSD(char* vsdStr, ProgressCallBack progressFunc=(ProgressCallBack)NULL, PrintCallBack printFunc=(PrintCallBack)NULL) = 0; + virtual bool FwSetVPD(char* vpdFileStr, PrintCallBack callBackFunc=(PrintCallBack)NULL) = 0; + virtual bool FwSetAccessKey(hw_key_t userKey, ProgressCallBack progressFunc=(ProgressCallBack)NULL) = 0; + virtual bool FwGetSection (u_int32_t sectType, std::vector& sectInfo)= 0; + + void FwCleanUp(); + virtual bool FwInit() = 0; + bool FwSetPrint(PrintCallBack PrintFunc); + + //needed for flint low level operations + bool FwSwReset(); + + + + //virtual bool FwBurnBlock(FwOperations &FwImageAccess); // Add call back + static FwOperations* FwOperationsCreate(void* fwHndl, void *info, char* psid, fw_hndl_type_t hndlType, char* errBuff=(char*)NULL, int buffSize=0); + static FwOperations* FwOperationsCreate(fw_ops_params_t& fwParams); + + //bool GetExpRomVersionWrapper(); + + + class MLXFWOP_API RomInfo : ErrMsg { + public: + RomInfo(const std::vector& romSector, bool resEndi=true); + ~RomInfo() {}; + bool initRomsInfo(roms_info_t* info); + bool ParseInfo(); + private: + //Rom Information + bool expRomFound; + u_int8_t numOfExpRom; + u_int8_t noRomChecksum; + u_int16_t expRomComDevid; + u_int8_t expRomWarning; + char expRomWarningMsg[MAX_ROM_ERR_MSG_LEN]; + u_int8_t expRomErrMsgValid; + char expRomErrMsg[MAX_ROM_ERR_MSG_LEN]; + rom_info_t romsInfo[MAX_ROMS_NUM]; + + std::vector romSect; + + bool GetExpRomVerForOneRom(u_int32_t verOffset); + bool GetExpRomVersion(); + }; + + // virtual bool FwBurn(FwOperations &FwImageAccess); + /* + FwAcessRom(); + FwReadImage(); + FwSwReset(); + FwDumpConf(); + FwSetGuid(); + FwSetVsd(); + FwHwAccessChangeMode(); + FwHwaccessSetKey(); + FwGetHwInfo(); + FwSetHWParam(); + FwQueryROM(); + FwClearSemaphore(); +*/ + class ExtBurnParams { + + public: + typedef enum BurnRomOption { + BRO_DEFAULT, + BRO_ONLY_FROM_IMG, + BRO_FROM_DEV_IF_EXIST, + } BurnRomOption; + //burn params + bool userGuidsSpecified; + bool userMacsSpecified; + bool userUidsSpecified; + bool vsdSpecified; + bool blankGuids; + bool burnFailsafe; + bool allowPsidChange; + bool useImagePs; + bool useImageGuids; + bool singleImageBurn; + bool noDevidCheck; + bool ignoreVersionCheck; + BurnRomOption burnRomOptions; + + //callback fun + ProgressCallBack progressFunc; + //data + char* userVsd; + std::vector userUids; //contains eiter guids or uids + + + ExtBurnParams():userGuidsSpecified(false), userMacsSpecified(false), userUidsSpecified(false), + vsdSpecified(false),blankGuids(false), burnFailsafe(true), allowPsidChange(false), + useImagePs(false), useImageGuids(false), singleImageBurn(true), noDevidCheck(false), + ignoreVersionCheck(false), burnRomOptions(BRO_DEFAULT), progressFunc(NULL), + userVsd(NULL){} + }; + + struct fwOpsParams{ + // COMMON + char* psid; // can be NULL + fw_hndl_type_t hndlType; + char* errBuff; // can be NULL + int errBuffSize; // can be zero if above NULL + // FHT_FW_FILE + char* fileHndl; + // FHT_FW_BUFF + u_int32_t *buffHndl; + u_int32_t buffSize; + // FHT_UEFI_DEV + uefi_Dev_t* uefiHndl; + f_fw_cmd uefiExtra; + // FHT_MST_DEV + char* mstHndl; + bool forceLock; + bool readOnly; + int numOfBanks; + flash_params_t* flashParams; // can be NULL + int ignoreCacheRep; + bool noFlashVerify; + }; + + struct sgParams { + bool updateCrc; //default should be set to true + bool stripedImage; // default shuold be set to false unless working on striped image file + bool macsSpecified; + bool guidsSpecified; + bool uidsSpecified; + std::vector userGuids; + }; + +protected: + #define FS3_IND_ADDR 0x24 + #define ARR_SIZE(arr) sizeof(arr)/sizeof(arr[0]) + #define RESTORING_MSG "Restoring signature" + + struct FwImgInfo { + fw_info_com_t ext_info; + u_int32_t imgStart; + bool actuallyFailsafe; + u_int32_t cntxLog2ChunkSize; + u_int32_t bootSize; + bool isGa; + u_int32_t supportedHwId[MAX_NUM_SUPP_HW_IDS]; + int supportedHwIdNum; + bool magicPatternFound; + bool imageOk; + bool wasQueried; + u_int32_t lastImageAddr; + }; + enum { + OLD_CNTX_START_POS_SIZE = 6, + CNTX_START_POS_SIZE = 7 + }; + enum { + MAX_SW_DEVICES_PER_HW=32 + }; + enum { + IMG_SIG_TYPE_UNKNOWN = 0, + IMG_SIG_TYPE_BIN = 1, + IMG_SIG_TYPE_MFA = 2, + IMG_SIG_OPEN_FILE_FAILED = 3 + }; + + enum { + IMG_VER_FS2 = 0, + IMG_VER_FS3 = 3, + }; + enum { + FS_OLD_GEN = 0, + FS_FS2_GEN, + FS_FS3_GEN, + }; + + struct HwDevData { + const char* name; + u_int32_t hwDevId; + chip_type_t chipType; + int portNum; + // Zero terminated list of SW device ids + const u_int32_t swDevIds[MAX_SW_DEVICES_PER_HW]; + }; + + struct HwDev2Str { + const char* name; + u_int32_t hwDevId; + u_int8_t revId; + }; + + typedef int (*print2log_func) (const char* format, ...); + + // Protected Methods + + virtual bool UpdateImgCache(u_int8_t *buff, u_int32_t addr, u_int32_t size); + bool CheckAndPrintCrcRes(char* pr, bool blank_crc, u_int32_t off, u_int32_t crc_act, u_int32_t crc_exp, bool ignore_crc = false, + VerifyCallBack verifyCallBackFunc = (VerifyCallBack)NULL); + bool checkBoot2(u_int32_t beg, u_int32_t offs, u_int32_t& next, bool fullRead, const char *pref, + VerifyCallBack verifyCallBackFunc = (VerifyCallBack)NULL); + u_int32_t CalcImageCRC(u_int32_t* buff, u_int32_t size); + bool writeImage(ProgressCallBack progressFunc, u_int32_t addr, void *data, int cnt, bool is_phys_addr = false); + ////////////////////////////////////////////////////////////////// + bool GetSectData(std::vector& file_sect, const u_int32_t *buff, const u_int32_t size); + //////////////////////////////////////////////////////////////////// + bool CheckMatchingDevId(u_int32_t hwDevId, u_int32_t imageDevId); + bool CheckMatchingHwDevId(u_int32_t hwDevId, u_int32_t rev_id, u_int32_t* supportedHwId, u_int32_t supportedHwIdNum); + bool HWIdRevToName(u_int32_t hw_id, u_int8_t rev_id, char *hw_name); + bool CheckMac(u_int64_t mac); + void recalcSectionCrc(u_int8_t *buf, u_int32_t data_size); + void FwInitCom(); + void FwDebugPrint(char *str); + + static bool CntxFindAllImageStart (FBase *ioAccess, u_int32_t start_locations[CNTX_START_POS_SIZE], u_int32_t* found_images); + static bool getRomsInfo(FBase* io, roms_info_t& romsInfo); + + bool GetQuickQuery() {return _quickQuery;} + bool CheckFwVersion(FwOperations &imgFwOps, u_int8_t forceVersion); + bool CheckPSID(FwOperations &imageOps, u_int8_t allow_psid_change = false); + chip_type_t getChipType(); + chip_type_t getChipTypeFromHwDevid(u_int32_t hwDevId); + + bool ReadImageFile(char *fimage, u_int8_t *&file_data, int &file_size, int min_size=-1); // min_size=-1 like int flint_ops needed for fs3updateSection + bool ModifyImageFile(char *fimage, u_int32_t addr, void *data, int cnt); + bool WriteImageToFile(char *file_name, u_int8_t *data, u_int32_t length); + bool FwBurnData(u_int32_t *data, u_int32_t dataSize, ProgressCallBack progressFunc); + + + // Protected Members + FBase* _ioAccess; + bool _isCached; + FwImgInfo _fwImgInfo; + std::vector _romSect; + std::vector _fwConfSect; + std::vector _hashFileSect; + std::vector _readSectList; + + bool _sectionsToRead[H_LAST]; + bool _wasVerified; + bool _quickQuery; + + PrintCallBack _printFunc; + char* _fname; + + + + +private: + + // Static Methods +#ifndef NO_MFA_SUPPORT + static int getMfaImg(char* fileName, char *psid, u_int8_t **imgbuf); + static int getMfaImg(u_int8_t* mfa_buf, int size, char *psid, u_int8_t **imgbuf); +#endif + static int getFileSignature(const char* fname); + static int getBufferSignature(u_int8_t* buf, u_int32_t size); + static bool FwAccessCreate(fw_ops_params_t& fwParams, FBase **ioAccessP); + static u_int8_t CheckFwFormat(FBase& f, bool getFwFormatFromImg = false); + static bool CntxFindMagicPattern (FBase* ioAccess, u_int32_t addr); + static void WriteToErrBuff(char* errBuff, const char* errStr, int size); + + // Methods + + // Static Members + static const u_int32_t _cntx_image_start_pos[CNTX_START_POS_SIZE]; + static const u_int32_t _cntx_magic_pattern[4]; + + // Members + static const HwDevData hwDevData[]; + static const HwDev2Str hwDev2Str[]; + fw_hndl_type_t _hndlType; + +}; + +#endif // FW_ACCESS_H diff --git a/mlxfwops/lib/mlxconfig.cpp b/mlxfwops/lib/mlxconfig.cpp new file mode 100644 index 0000000..43ae4a3 --- /dev/null +++ b/mlxfwops/lib/mlxconfig.cpp @@ -0,0 +1,1826 @@ +/* + * + * flint.cpp - FLash INTerface + * + * Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Version: $Id$ + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "mlxconfig.h" +#include "flint_ops.h" +/**************************** Globals *************************/ +static const char static_profiles [] = { +#include "profiles.json.dat" +}; + +#undef PRINT_DEBUG +#define PRINT_DEBUG(fmt, ...) + +/************************************ + * Function: int2string + ************************************/ +string int2string(long int number) +{ + stringstream ss;//create a stringstream + ss << number;//add number to the stream + return ss.str();//return a string with the contents of the stream +} + +/************************************ + * Function: print + ************************************/ +void Pair::print() +{ + cout << "\t\t(" << key << ", " << value + ")"; +} + +/************************************ + * Function: print + ************************************/ +void Tlv::print() +{ + cout << "\n\tTlv: " << name << ", fields: \n"; + for (size_t i = 0; i < fields.size(); i++) + { + fields[i].print(); + cout << ",\n"; + } +} + +/************************************ + * Function: print + ************************************/ +void Profile::print() +{ + cout << " Version: " << version << ", id: " << id; + for (size_t i = 0; i < tlvs.size(); i++) + { + tlvs[i].print(); + cout << ",\n"; + } +} + +/************************************ + * Function: parseCmdLine + ************************************/ +bool MlxConfig::parseCmdLine(int argc, const char** argv) +{ + this->_cmd = CMD_UNKNOWN; + +#define SET_CMD(cmd)\ + do {\ + if (this->_cmd != CMD_UNKNOWN) {\ + printf("config doesn't support multiple commands\n");\ + return false;\ + }\ + else {\ + this->_cmd = cmd;\ + }\ + }\ + while(0) + + for (int i = 0; i < argc; i++) + { + if (!strcmp(argv[i], "query") || !strcmp(argv[i], "q")) + { + SET_CMD(CMD_QUERY); + } + else if (!strcmp(argv[i], "set") || !strcmp(argv[i],"s")) + { + SET_CMD(CMD_SET); + if (i >= argc - 1) + { + printf("Missing for \"set\" option\n"); + return false; + } + this->_cmdProfile = argv[i+1]; + i++; + } + else if (!strcmp(argv[i], "restore") || !strcmp(argv[i], "r")) + { + SET_CMD(CMD_RESTORE); + } + else if (!strcmp(argv[i], "lp") || !strcmp(argv[i], "l")) + { + SET_CMD(CMD_LIST_PROFILES); + } + else if (!strcmp(argv[i], "h") || !strcmp(argv[i], "help")) + { + SET_CMD(CMD_HELP); + return true; + } + else if (!strcmp(argv[i], "-pf")) + { + if (i >= argc - 1) + { + printf("Missing profiles file for \"pf\" option\n"); + return false; + } + this->_profilesFile = argv[i+1]; + i++; + } + else if (!strcmp(argv[i], "-verbose")) + { + this->_verbose = true; + } + else if (!strcmp(argv[i], "reconfig")) // For debug + { + SET_CMD(CMD_RECONFIG); + } + else if (!strcmp(argv[i], "config_info")) + { + SET_CMD(CMD_CONFIG_INFO); + } + else if (!strcmp(argv[i], "verify") || !strcmp(argv[i], "v")) + { + SET_CMD(CMT_VERIFY); + } + else + { + printf("Unknown config sub-command: %s\n", argv[i]); + return false; + } + } + + return true; +} + +/************************************ + * Function: getHelpMessage + ************************************/ +const char* MlxConfig::getHelpMessage() +{ + return + " config sub-commands:\n" + " s[et] - Burn the given profile and set as the active configuration profile\n" + " q[uery] - Query the current profile\n" + " r[estore] - Restore to defaults (Erase all configurations)\n" + " l[p] - List available and supported profiles\n" + " v[erify] - Verify configuration section\n\n" + " config options:\n" + " -verbose - Print more details"; +} + +/************************************ + * Function: getRunExamples + ************************************/ +const char* MlxConfig::getRunExamples() +{ + return + "* Query/Set/Restore mellanox device's nonvolatile configuration section\n" + " Command:\n" + " config\n" + " Parameters:\n" + " s[et] - to set the reaquired profile\n" + " q[uery] - to query the current profile\n" + " r[estore] - to restore to defaults\n" + " l[p] - to list supported profiles\n" + " v[erify] - Verify configuration section\n\n" + " config options:\n" + " -verbose - Print more details\n" + " Example:\n" + " flint -d /dev/mst/mt4099_pci_cr0 config set 8PF_ETH\n" + " flint -d /dev/mst/mt4099_pci_cr0 config query\n" + " flint -d /dev/mst/mt4099_pci_cr0 config restore\n" + " flint -d /dev/mst/mt4099_pci_cr0 config lp\n"; +} + +/************************************ + * Function: MlxConfig + ************************************/ +MlxConfig::MlxConfig(): + _lastMsg("None"), _cmd(CMD_UNKNOWN), _verbose(false), _adbDB(0), _adbRoot(0) +{ +} + +/************************************ + * Function: ~MlxConfig + ************************************/ +MlxConfig::~MlxConfig() +{ + +} + +/************************************ + * Function: loadImageData + ************************************/ +bool MlxConfig::loadImageData(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo) +{ + assert(flash); + assert(op); + + if (!flashImageInfo.imageOk) + { + _lastMsg = "FW image is empty or corrupted"; + return false; + } + + // get cfg section info + _cfgSize = flashImageInfo.configSize; + _cfgAddress[0] = flashImageInfo.configAddr1; + _cfgAddress[1] = flashImageInfo.configAddr2; + + _isFailSafe = flashImageInfo.isFailsafe; + if (!_isFailSafe) + { + _cfgAddress[0] = _cfgAddress[1]; + } + + // check current burnt configuration version + int activeCfgIdx; + if (!getActiveCfgIdx(flash, activeCfgIdx)) + return false; + + if (activeCfgIdx != -1) + { + u_int32_t dword; + if (!flash->read_phy(_cfgAddress[activeCfgIdx] + 4, &dword, 4)) + { + _lastMsg = flash->err(); + return false; + } + + // Parse the cfg header + u_int32_t version = htonl(dword) & 0xff; + + if (version != MLX_CFG_VERSION) + { + _lastMsg = "Unsupported configuration section version \"" + int2string(version) + "\" was found" + "\nThe only supported configuration version by this tools is \"" + + int2string(MLX_CFG_VERSION) + "\""+ + "\nConsider erasing the configuration section with: \"config r\" flint's command "; + return false; + } + } + + // Get json + vector jsonData; + if (!op->GetProfileList(&flashImageInfo, jsonData)) + { + _lastMsg = op->err(); + return false; + } + + string jsonTxt = string((char*)&jsonData[0]); + // Load profiles mapping + if (jsonTxt.empty()) + { + _lastMsg = "Image doesn't contain any profiles info"; + return false; + } + + if (!parseProfileDb(jsonTxt)) + return false; + + // Get Adabe + vector adabeData; + if (!op->GetTlvFormatXML(&flashImageInfo, adabeData)) + { + _lastMsg = op->err(); + return false; + } + + string adabeTxt = string((char*)&adabeData[0]); + if (adabeTxt.empty()) + { + _lastMsg = op->err(); + return false; + } + + if (_adbDB) + { + delete _adbDB; + _adbDB = 0; + } + if (_adbRoot) + { + delete _adbRoot; + _adbDB = 0; + } + + _adbDB = new Adb; + if (!_adbDB->loadFromString(adabeTxt.c_str())) + { + _lastMsg = _adbDB->getLastError(); + return false; + } + + // get Root, TlvHeader and CfgHeader nodes + _adbRoot = _adbDB->createLayout(_adbDB->rootNode); + if (!_adbRoot) + { + _lastMsg = "Can't get root node of TLVs: " + _adbDB->getLastError(); + return false; + } + _adbTlvHeader = _adbRoot->getChildByPath("tlv_header"); + _adbCfgHeader = _adbRoot->getChildByPath("cfg_section_header"); + if (!_adbTlvHeader || !_adbCfgHeader) + { + _lastMsg = "Can't find one of the tlv_header/cfg_section_header definition in TLVs adabe"; + return false; + } + + return true; +} + +/************************************ + * Function: execute + ************************************/ +bool MlxConfig::execute(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo, int argc, const char** argv) +{ + if (!parseCmdLine(argc, argv)) + { + _lastMsg = "Failed to parse command line arguments"; + return false; + } + + // This if handles the ugly old FW that configured using old mlxconfig tool + bool cfgPresent; + u_int32_t cfgVer; + if (!isConfigPresent(flash, op, flashImageInfo, cfgPresent, cfgVer)) + return false; + + if (_cmd != CMD_RESTORE && cfgPresent && cfgVer == OLD_MLXCONFIG_VERSION) + { + _lastMsg = "Found old version of FW configuration, please use \"mlxconfig\""; + return false; + } + + switch (_cmd) + { + case CMD_SET: + return setCfg(flash, op, flashImageInfo, _cmdProfile); + case CMD_QUERY: + return queryCfg(flash, op, flashImageInfo); + case CMD_RESTORE: + return eraseCfg(flash, op, flashImageInfo); + case CMD_LIST_PROFILES: + return listProfilesCfg(flash, op, flashImageInfo); + case CMD_RECONFIG: + return reconfigureCfg(flash, op, flashImageInfo); + case CMD_HELP: + printf("%s\n", getHelpMessage()); + return true; + case CMD_CONFIG_INFO: + return configInfo(flash, op, flashImageInfo); + case CMT_VERIFY: + return verifyCfg(flash, op, flashImageInfo); + default: + _lastMsg = "No command given. See help for details."; + return false; + } +} + +/************************************ + * Function: setCfg + ************************************/ +bool MlxConfig::setCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo, string profileName, bool silent) +{ + // Pack all tlvs + u_int8_t *tlvHeaderBuf, *tlvDataBuf; + u_int32_t totalCfgSize = 0; + Profile profile; + u_int32_t crc16; + + if (!flashImageInfo.isConfigurable) + { + _lastMsg = "Current FW image isn't configurable"; + return false; + } + + if (!loadImageData(flash, op, flashImageInfo)) + return false; + + if (!_isFailSafe) + { + if (!silent) + { + printf("Burning new configuration in non-fail-safe mode"); + if (!op->ask_user()) + { + _lastMsg = "Set FW configuration was skipped by user"; + return false; + } + } + } + + int nextActiveCfgIdx; + if (!getActiveCfgIdx(flash, nextActiveCfgIdx)) + { + _lastMsg = "Failed to get the current active configuration: " + _lastMsg; + return false; + } + nextActiveCfgIdx = nextActiveCfgIdx == -1 ? 0 : nextActiveCfgIdx; + PRINT_DEBUG("Current active image: %d", nextActiveCfgIdx); + nextActiveCfgIdx = 1 - nextActiveCfgIdx; + PRINT_DEBUG("Next active image: %d", nextActiveCfgIdx); + + if (!silent) + { + printf("Burning new Configuration"); + fflush(stdout); + } + + // Check if profile exists + if (!_profilesMap.count(profileName)) + { + _lastMsg = "Can't find definition of the given profile: " + profileName; + goto failed; + } + profile = _profilesMap[profileName]; + + // Check if profile is supported + for (size_t i = 0; i < flashImageInfo.supportedProfList.size(); i++) + { + if (flashImageInfo.supportedProfList[i] == profile.id) + break; + + if (i == flashImageInfo.supportedProfList.size() - 1) + { + _lastMsg = "Profile " + profileName + " isn't supported"; + return false; + } + } + + // Calculate the total required buffer len (in bytes) + totalCfgSize = _adbCfgHeader->size/8 + _adbTlvHeader->size/8; + for (size_t i = 0; i < profile.tlvs.size(); i++) + { + AdbInstance* node = _adbRoot->getChildByPath(profile.tlvs[i].name); + if (!node) + { + _lastMsg = "Can't find definition (" + profile.tlvs[i].name + ") - Report a bug"; + goto failed; + } + + totalCfgSize += node->size/8 + _adbTlvHeader->size/8; + } + + if (totalCfgSize > _cfgSize) + { + _lastMsg = "The profile: " + profileName + " size is greater than the configuration section size"; + goto failed; + } + + if (!op->IsConfigAreaAvialable(flash, &flashImageInfo)) + { + _lastMsg = "Configuration area overlaps with FW image, maybe you have too large FW image"; + goto failed; + } + + // Allocate the required amount of memory + u_int8_t buf[totalCfgSize]; + memset(buf, 0, totalCfgSize); // zerofy all reserved fields + + // Pack the configuration section header (TEMPORARY VALID SIGNATURE WITH CRC16) + setCfgSectionHeader(buf, CFG_HEADER_SIGNATURE, CFG_SIGNATURE); + setCfgSectionHeader(buf, CFG_HEADER_MAX_LEN, _cfgSize/4); + setCfgSectionHeader(buf, CFG_HEADER_VERSION, MLX_CFG_VERSION); + setCfgSectionHeader(buf, CFG_HEADER_PROFILE_ID, profile.id); + setCfgSectionHeader(buf, CFG_HEADER_PROFILE_VER, profile.version); + setCfgSectionHeader(buf, CFG_HEADER_CRC, 0xffff); + crc16 = calcBECrc16((u_int32_t*)buf, _adbCfgHeader->size/32); + // set invalid signature with and the calculated crc + setCfgSectionHeader(buf, CFG_HEADER_SIGNATURE, CFG_INVALID_SIGNATURE); + setCfgSectionHeader(buf, CFG_HEADER_CRC, crc16); + + // Pack all tlvs + tlvHeaderBuf = buf + _adbCfgHeader->size/8; + tlvDataBuf = tlvHeaderBuf + _adbTlvHeader->size/8; + for (size_t i = 0; i < profile.tlvs.size(); i++) + { + // Find the node definition + string tlvName = profile.tlvs[i].name; + AdbInstance* node = _adbRoot->getChildByPath(tlvName); + if (!node) + { + _lastMsg = "Can't find node definition for: " + tlvName; + goto failed; + } + + int nodeId; + if (!getTlvNodeId(node, nodeId)) + { + goto failed; + } + + int tlvVer; + if (!getTlvVersion(node, tlvVer)) + { + goto failed; + } + + // First fill the tlv content and then the tlv header + // Go over fields and set their value + for (size_t j = 0; j < profile.tlvs[i].fields.size(); j++) + { + AdbInstance* f; + f = node->getChildByPath(profile.tlvs[i].fields[j].key); + if (!f) + { + _lastMsg = "Can't find the field: " + profile.tlvs[i].fields[j].key + " in node: " + tlvName; + goto failed; + } + + u_int64_t value; + if (!getFieldIntValue(profile.tlvs[i].fields[j].value, f, value)) + { + goto failed; + } + + f->pushBuf(tlvDataBuf, value); + } + + // Set header with invalid crc16 + setTlvHeader(tlvHeaderBuf, TLV_HEADER_LENGTH, node->size/32); + setTlvHeader(tlvHeaderBuf, TLV_HEADER_ID, nodeId); + setTlvHeader(tlvHeaderBuf, TLV_HEADER_CRC, 0xffff); + setTlvHeader(tlvHeaderBuf, TLV_HEADER_VERSION, tlvVer); + // Calc crc16 + u_int16_t crc16 = calcBECrc16((u_int32_t*)tlvHeaderBuf, _adbTlvHeader->size/32 + node->size/32); + + // Set the header crc16 + setTlvHeader(tlvHeaderBuf, TLV_HEADER_CRC, crc16); + + // Update next tlvHeader & tlvData buffer pointers + tlvHeaderBuf += _adbTlvHeader->size/8 + node->size/8; + tlvDataBuf = tlvHeaderBuf + _adbTlvHeader->size/8; + } + + // Add last tlv header + // CRC16 on all section except of the signature (first dwrod) and last dword (the CRC itself) + setTlvHeader(tlvHeaderBuf, TLV_HEADER_LENGTH, 0); + setTlvHeader(tlvHeaderBuf, TLV_HEADER_ID, LAST_TLV_ID); + setTlvHeader(tlvHeaderBuf, TLV_HEADER_CRC, calcBECrc16(((u_int32_t*)buf)+1, (totalCfgSize-4)/4)); + + PRINT_DEBUG("Erasing section: 0x%x", _cfgAddress[nextActiveCfgIdx]); + if (!flash->erase_sector_phy(_cfgAddress[nextActiveCfgIdx])) + { + _lastMsg = flash->err(); + goto failed; + } + + PRINT_DEBUG("Writing %d bytes to cfg section", totalCfgSize); + if (!flash->write_phy(_cfgAddress[nextActiveCfgIdx]+4, buf+4, totalCfgSize-4, true)) + { + _lastMsg = flash->err(); + goto failed; + } + + // ACTIVATE IT BY WRITING VALID SIGNATURE + // write the signature + PRINT_DEBUG("Activating image: %d", nextActiveCfgIdx); + setCfgSectionHeader(buf, CFG_HEADER_SIGNATURE, CFG_SIGNATURE); + if (!flash->write_phy(_cfgAddress[nextActiveCfgIdx], buf, 4, true)) + { + _lastMsg = flash->err(); + goto failed; + } + + if (_isFailSafe) + { + // Invalidate current active cfg + PRINT_DEBUG("Inactivating image: %d", 1- nextActiveCfgIdx); + setCfgSectionHeader(buf, CFG_HEADER_SIGNATURE, CFG_INVALID_SIGNATURE); + if (!flash->write_phy(_cfgAddress[1-nextActiveCfgIdx], buf, 4, true)) + { + _lastMsg = string() + "Failed to invalidate configuration: " + flash->err(); + goto failed; + } + } + + if (!silent) + printf(" - OK\n"); + return true; + +failed: + if (!silent) + printf(" - FAILED\n"); + return false; +} + +/************************************ + * Function: queryCfg + ************************************/ +bool MlxConfig::queryCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo) +{ + if (!flashImageInfo.isConfigurable) + { + _lastMsg = "Current FW image isn't configurable"; + return false; + } + + if (!loadImageData(flash, op, flashImageInfo)) + return false; + + // Todo - need optimization - verify will call loadImageData again + if (!verifyCfg(flash, op, flashImageInfo, true)) + { + return false; + } + + int activeCfgIdx; + if (!getActiveCfgIdx(flash, activeCfgIdx)) + { + _lastMsg = "Failed to get the current active configuration: " + _lastMsg; + return false; + } + + if (activeCfgIdx == -1) + { + printf("There is no valid configuration\n"); + string profileName = findProfileById(flashImageInfo.defPorfile); + printf("Default profile is: %s (0x%x)\n", profileName.empty() ? "Unknown" : profileName.c_str(), + flashImageInfo.defPorfile); + return true; + } + + if (_verbose) + printf("Active configuration image at address: %#x\n", _cfgAddress[activeCfgIdx]); + + u_int8_t buf[_adbCfgHeader->size/8]; + if (!flash->read_phy(_cfgAddress[activeCfgIdx], buf, _adbCfgHeader->size/8)) + { + _lastMsg = flash->err(); + return false; + } + + // Parse the cfg header + u_int32_t signature, crc16, maxLen, version, profileID, profileVer; + signature = getCfgSectionHeader(buf, CFG_HEADER_SIGNATURE); + maxLen = getCfgSectionHeader(buf, CFG_HEADER_MAX_LEN); + version = getCfgSectionHeader(buf, CFG_HEADER_VERSION); + profileID = getCfgSectionHeader(buf, CFG_HEADER_PROFILE_ID); + profileVer = getCfgSectionHeader(buf, CFG_HEADER_PROFILE_VER); + crc16 = getCfgSectionHeader(buf, CFG_HEADER_CRC); + + // Find the appropriate profile + string profileName = findProfileById(profileID); + if (profileName.empty()) + { + _lastMsg = "Burnt profile ID is: " + int2string(profileID) + ", But can't find it in DB"; + return false; + } + + printf("Active Profile: %s, Profile Version: 0x%x\n", profileName.c_str(), profileVer); + + // Print TLV contents + if (_verbose) + { + printf("Configuration Section Version: 0x%x\n", version); + printf("Crc16: 0x%x\n", crc16); + printf("Tlv contents:\n"); + u_int32_t tlvAddr = _cfgAddress[activeCfgIdx] + _adbCfgHeader->size/8; + while(1) + { + u_int8_t tlvHeaderBuf[_adbTlvHeader->size/8]; + if (!flash->read_phy(tlvAddr, &tlvHeaderBuf, _adbTlvHeader->size/8)) + { + _lastMsg = flash->err(); + return false; + } + + u_int16_t len, id, tlvVer, crc; + len = getTlvHeader(tlvHeaderBuf, TLV_HEADER_LENGTH); + id = getTlvHeader(tlvHeaderBuf, TLV_HEADER_ID); + crc = getTlvHeader(tlvHeaderBuf, TLV_HEADER_CRC); + tlvVer = getTlvHeader(tlvHeaderBuf, TLV_HEADER_VERSION); + if ((u_int32_t)id == LAST_TLV_ID) + { + printf("\tTlv: LAST\n"); + break; + } + + tlvAddr += _adbTlvHeader->size/8; + len *= 4; + u_int8_t buf[len]; + if (!flash->read_phy(tlvAddr, buf, len)) + { + _lastMsg = flash->err(); + return false; + } + + // Find the layout for this tlv id + AdbInstance* node = getTlvById(id); + if (!node) + { + _lastMsg = "Can't find TLV definition for TLV ID: " + int2string(id); + return false; + } + + printf("\tTlv: %s (0x%x), version(%d), crc16(0x%x)\n", node->name.c_str(), id, tlvVer, crc); + vector fields = node->getLeafFields(); + for (size_t i = 0; i < fields.size(); i++) + { + AdbInstance* f = fields[i]; + string name = f->fullName(2); + u_int32_t value = f->popBuf(buf); + + string enumName; + if (f->intToEnum(value, enumName)) + { + printf("\t\t%-20s : %s (0x%x)\n", name.c_str(), enumName.c_str(), value); + } + else + { + printf("\t\t%-20s : 0x%x\n", name.c_str(), value); + } + } + tlvAddr += len; + } + } + + return true; +} + +/************************************ + * Function: eraseCfg + ************************************/ +bool MlxConfig::eraseCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo) +{ + // This method must be minimalist, it's shouldn't depend on any image info or old/new fw image. + // It should always work + /*if (!flashImageInfo.isConfigurable) + { + _lastMsg = "Current FW image isn't configurable"; + return false; + }*/ + + if (!flashImageInfo.imageOk) + { + _lastMsg = "FW image is empty or corrupted"; + return false; + } + + // get cfg section info + _cfgSize = flashImageInfo.configSize; + _cfgAddress[0] = flashImageInfo.configAddr1; + _cfgAddress[1] = flashImageInfo.configAddr2; + + _isFailSafe = flashImageInfo.isFailsafe; + if (!_isFailSafe) + { + _cfgAddress[0] = _cfgAddress[1]; + } + + if (!op->ask_user("You are trying to restore default configuration, do you want to continue")) + { + return true; + } + + printf("Restoring FW configurations to defaults"); + fflush(stdout); + + if (!flash->erase_sector_phy(_cfgAddress[0]) || + (_isFailSafe && !flash->erase_sector_phy(_cfgAddress[1]))) + { + _lastMsg = flash->err(); + printf(" - FAILED\n"); + return false; + } + + printf(" - OK\n"); + return true; +} + +/************************************ + * Function: listProfilesCfg + ************************************/ +bool MlxConfig::listProfilesCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo) +{ + if (!flashImageInfo.isConfigurable) + { + _lastMsg = "Current FW image isn't configurable"; + return false; + } + + if (!loadImageData(flash, op, flashImageInfo)) + return false; + + // Todo - need optimization - verify will call loadImageData again + if (!verifyCfg(flash, op, flashImageInfo, true)) + { + return false; + } + + printf("Supported profiles by the current FW image:\n"); + for (size_t i = 0; i < flashImageInfo.supportedProfList.size(); i++) + { + string profileName = findProfileById(flashImageInfo.supportedProfList[i]); + if (profileName.empty()) + { + _lastMsg = "Can't find profile (" + int2string(flashImageInfo.supportedProfList[i]) + + ") definition in current Fw image"; + return false; + } + PRINT_COLOR(COLOR_GREEN, "\t%u) %s\n", (unsigned)i, profileName.c_str()); + } + + return true; +} + +/************************************ + * Function: reconfigureCfg + ************************************/ +bool MlxConfig::reconfigureCfg(Flash* flash, Operations* op, Operations::ImageInfo &newImageInfo) +{ + if (!newImageInfo.isConfigurable) + { + return true; + } + if (!loadImageData(flash, op, newImageInfo)) + return false; + + // Todo - need optimization - verify will call loadImageData again + if (!verifyCfg(flash, op, newImageInfo, true)) + { + return false; + } + + // get the burnt profile + int activeCfgIdx; + if (!getActiveCfgIdx(flash, activeCfgIdx)) + { + _lastMsg = "Failed to get the current active configuration: " + _lastMsg; + return false; + } + + if (activeCfgIdx == -1) + { + return true; + } + + u_int8_t buf[_adbCfgHeader->size/8]; + if (!flash->read_phy(_cfgAddress[activeCfgIdx], buf, _adbCfgHeader->size/8)) + { + _lastMsg = flash->err(); + return false; + } + + // Parse the cfg header + u_int32_t profileID, profileVer; + profileID = getCfgSectionHeader(buf, CFG_HEADER_PROFILE_ID); + profileVer = getCfgSectionHeader(buf, CFG_HEADER_PROFILE_VER); + + if (profileID == CUSTOM_PROFILE_ID) // No need to reconfigure + { + return true; + } + + // find definition for this profile in the current Fw Image json + // Find the appropriate profile + string profileName = findProfileById(profileID); + if (profileName.empty()) + { + _lastMsg = "Burnt profile ID is: " + int2string(profileID) + ", But can't find it in current Fw Image Profiles"; + return false; + } + + if (_profilesMap[profileName].version == profileVer) // No need to reconfigure + { + return true; + } + + printf("Reconfiguring FW configuration section"); + fflush(stdout); + bool rc = setCfg(flash, op, newImageInfo, profileName, true); + if (rc) + printf(" - OK\n"); + else + printf(" - FAILED\n"); + + return rc; +} + +/************************************ + * Function: verifyCfg + ************************************/ +bool MlxConfig::verifyCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo, bool silent) +{ + if (!flashImageInfo.isConfigurable) + { + _lastMsg = "Current FW image isn't configurable"; + return false; + } + + if (!loadImageData(flash, op, flashImageInfo)) + return false; + + int activeCfgIdx; + if (!getActiveCfgIdx(flash, activeCfgIdx)) + { + _lastMsg = "Failed to get the current active configuration: " + _lastMsg; + return false; + } + + if (activeCfgIdx == -1) + return true; + + // verify the configuration header + u_int8_t buf[flashImageInfo.configSize]; + if (!flash->read_phy(_cfgAddress[activeCfgIdx], buf, _adbCfgHeader->size/8)) + { + _lastMsg = flash->err(); + return false; + } + + // Parse the cfg header + u_int32_t cfgCrc, expCfgCrc; + cfgCrc = getCfgSectionHeader(buf, CFG_HEADER_CRC); + + // calc expected crc16 + setCfgSectionHeader(buf, CFG_HEADER_CRC, 0xffff); + expCfgCrc = calcBECrc16((u_int32_t*)buf, _adbCfgHeader->size/32); + if (!crcVerify(_cfgAddress[activeCfgIdx], _adbCfgHeader->size/8, "FW Configurations Header", cfgCrc, expCfgCrc, silent)) + { + _lastMsg = "Configuration Section Header Data Integrity Error - CRC check failed"; + return false; + } + + u_int32_t tlvAddr = _cfgAddress[activeCfgIdx] + _adbCfgHeader->size/8; + int tlvIdx = 0; + while(1) + { + if (!flash->read_phy(tlvAddr, buf, _adbTlvHeader->size/8)) + { + _lastMsg = flash->err(); + return false; + } + + u_int32_t tlvCrc, expTlvCrc, id, len; + id = getTlvHeader(buf, TLV_HEADER_ID); + tlvCrc = getTlvHeader(buf, TLV_HEADER_CRC); + len = getTlvHeader(buf, TLV_HEADER_LENGTH); + + if ((u_int32_t)id == LAST_TLV_ID) + { + break; + } + + if (!flash->read_phy(tlvAddr + _adbTlvHeader->size/8, buf + _adbTlvHeader->size/8, len*4)) + { + _lastMsg = flash->err(); + return false; + } + + setTlvHeader(buf, TLV_HEADER_CRC, 0xffff); + expTlvCrc = calcBECrc16((u_int32_t*)buf, len + _adbTlvHeader->size/32); + if (!crcVerify(tlvAddr, len*4 + _adbTlvHeader->size/8, + "Tlv[" + int2string(tlvIdx) + "]", + tlvCrc, expTlvCrc, silent)) + { + _lastMsg = "Tlv[" + int2string(tlvIdx) + "] Data Integrity Error - CRC check failed"; + return false; + } + + tlvAddr += _adbTlvHeader->size/8 + len*4; + tlvIdx++; + } + + return true; +} + +/************************************ + * Function: configInfo + ************************************/ +bool MlxConfig::configInfo(Flash* /*flash*/, Operations* op, Operations::ImageInfo &flashImageInfo) +{ + printf("FW image configuration info:\n"); + printf("============================\n"); + + if (!flashImageInfo.isConfigurable) + { + printf("Image isn't configurable\n"); + return false; + } + + // Todo - need optimization - verify will call loadImageData again + /*if (!verifyCfg(flash, op, flashImageInfo, true)) + { + return false; + }*/ + + if (!flashImageInfo.isFailsafe) + { + printf("Configuration Section Address: %#x\n", flashImageInfo.configAddr1); + } + else + { + printf("Configuration Section 1 Address: %#x\n", flashImageInfo.configAddr1); + printf("Configuration Section 2 Address: %#x\n", flashImageInfo.configAddr2); + } + + printf("Configuration Section Size: %#x\n", flashImageInfo.configSize); + printf("Default Profile: %#x\n", flashImageInfo.defPorfile); + + printf("Profiles Json Contents:\n"); + vector jsonData; + if (!op->GetProfileList(&flashImageInfo, jsonData)) + { + _lastMsg = op->err(); + return false; + } + + string jsonStr = string((char*)&jsonData[0]); + if (jsonStr.empty()) + { + _lastMsg = "Image doesn't contain any profiles info"; + return false; + } + printf("%s\n", jsonStr.c_str()); + + + printf("Tlv Format Adabe Contents:\n"); + vector adbData; + if (!op->GetTlvFormatXML(&flashImageInfo, adbData)) + { + _lastMsg = op->err(); + return false; + } + + string adbStr = string((char*)&adbData[0]); + if (adbStr.empty()) + { + _lastMsg = "Image doesn't contain any TLVs format info"; + return false; + } + printf("%s\n", adbStr.c_str()); + + return true; +} + +/************************************ + * Function: isConfigPresent + ************************************/ +bool MlxConfig::isConfigPresent(Flash* flash, Operations* /*op*/, + Operations::ImageInfo &flashImageInfo, + bool &presents, u_int32_t &configVer) +{ + if (!flashImageInfo.imageOk) + { + _lastMsg = "FW image is empty or corrupted"; + return false; + } + + // get cfg section info + _cfgSize = flashImageInfo.configSize; + _cfgAddress[0] = flashImageInfo.configAddr1; + _cfgAddress[1] = flashImageInfo.configAddr2; + + _isFailSafe = flashImageInfo.isFailsafe; + if (!_isFailSafe) + { + _cfgAddress[0] = _cfgAddress[1]; + } + + int activeIdx; + if (!getActiveCfgIdx(flash, activeIdx)) + { + return false; + } + + presents = activeIdx != -1; + // get config version + if (presents) + { + u_int32_t dword; + if (!flash->read_phy(_cfgAddress[activeIdx] + 4, &dword, 4)) + { + _lastMsg = flash->err(); + return false; + } + + // Parse the cfg header + configVer = htonl(dword) & 0xff; + } + return true; +} + +/************************************ + * Function: setNonFailSafeCfg + ************************************/ +bool MlxConfig::setNonFailSafeCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo) +{ + u_int32_t zeros = 0; + + if (!flashImageInfo.isConfigurable) + { + PRINT_DEBUG("Fw image isn't configurable"); + return true; + } + + if (!loadImageData(flash, op, flashImageInfo)) + return false; + + // Todo - need optimization - verify will call loadImageData again + if (!verifyCfg(flash, op, flashImageInfo, true)) + { + return false; + } + + // get active section index + int activeCfgIdx; + if (!getActiveCfgIdx(flash, activeCfgIdx)) + { + _lastMsg = "Failed to get the current active configuration: " + _lastMsg; + return false; + } + + if (activeCfgIdx == -1 || activeCfgIdx == 1) + { + PRINT_DEBUG("no need to move cfg section"); + return true; + } + + printf("Moving current FW configuration to Non-Fail-Safe sections"); + fflush(stdout); + u_int8_t buf[_cfgSize]; + // read cfg from section 0 + PRINT_DEBUG("Reading section: 0x%x", _cfgAddress[0]); + if (!flash->read_phy(_cfgAddress[0], buf, _cfgSize)) + { + goto failed; + } + + // erase section 1 + PRINT_DEBUG("Erasing section: 0x%x", _cfgAddress[1]); + if (!flash->erase_sector_phy(_cfgAddress[1])) + { + goto failed; + + } + + // write section 1 + PRINT_DEBUG("Writing %d bytes to cfg section 1", _cfgSize); + if (!flash->write_phy(_cfgAddress[1]+4, buf+4, _cfgSize-4, true)) + { + goto failed; + } + + // activate section 1 - write valid signature to first dword + if (!flash->write_phy(_cfgAddress[1], buf, 4, true)) + { + goto failed; + } + + // invalidate first cfg section + if (!flash->write_phy(_cfgAddress[0], &zeros, 4, true)) + { + goto failed; + } + + printf(" - OK\n"); + return true; + +failed: + _lastMsg = flash->err(); + printf(" - FAILED\n"); + return false; +} + +/************************************ + * Function: queryProfile + ************************************/ +bool MlxConfig::queryProfile(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo, + u_int32_t &profileID, string &profileName) +{ + profileName = "NONE"; + + if (!flashImageInfo.isConfigurable) + { + PRINT_DEBUG("Fw image isn't configurable"); + return false; + } + + if (!loadImageData(flash, op, flashImageInfo)) + return false; + + // Todo - need optimization - verify will call loadImageData again + if (!verifyCfg(flash, op, flashImageInfo, true)) + { + return false; + } + + // get active section index + int activeCfgIdx; + if (!getActiveCfgIdx(flash, activeCfgIdx)) + { + _lastMsg = "Failed to get the current active configuration: " + _lastMsg; + return false; + } + + if (activeCfgIdx == -1) + { + PRINT_DEBUG("There are no configurations"); + profileID = 0; + profileName = "Unknown"; + return true; + } + + // read the current burnt profile + u_int8_t buf[_adbCfgHeader->size/8]; + if (!flash->read_phy(_cfgAddress[activeCfgIdx], buf, _adbCfgHeader->size/8)) + { + _lastMsg = flash->err(); + return false; + } + + // Parse the cfg header + profileID = getCfgSectionHeader(buf, CFG_HEADER_PROFILE_ID); + + if (profileID == CUSTOM_PROFILE_ID) // No need to reconfigure + { + PRINT_DEBUG("Current profile is custom"); + profileName = "Custom"; + } + else + { + profileName = findProfileById(profileID); + } + + if (profileName.empty()) + { + _lastMsg = "Can't find profile " + int2string(profileID) + " name"; + return false; + } + return true; +} +/************************************ + * Function: checkExistProfileCompat + ************************************/ +bool MlxConfig::checkExistProfileCompat(Flash* flash, Operations* op, + Operations::ImageInfo &flashImageInfo, + Operations::ImageInfo &newImageInfo, + bool& compat) +{ + string profileName = "NONE"; + u_int32_t profileID = 0; + + if (!flashImageInfo.isConfigurable) + { + PRINT_DEBUG("Old Fw image isn't configurable"); + goto compatible; + } + + if (!loadImageData(flash, op, flashImageInfo)) + return false; + + // Todo - need optimization - verify will call loadImageData again + if (!verifyCfg(flash, op, flashImageInfo, true)) + { + return false; + } + + PRINT_DEBUG("Checking new FW image compatibility with existing configurations..."); + // get active section index + int activeCfgIdx; + if (!getActiveCfgIdx(flash, activeCfgIdx)) + { + _lastMsg = "Failed to get the current active configuration: " + _lastMsg; + return false; + } + + if (activeCfgIdx == -1) + { + PRINT_DEBUG("There are no configurations"); + goto compatible; + } + + // read the current burnt profile + u_int8_t buf[_adbCfgHeader->size/8]; + if (!flash->read_phy(_cfgAddress[activeCfgIdx], buf, _adbCfgHeader->size/8)) + { + _lastMsg = flash->err(); + return false; + } + + // Parse the cfg header + profileID = getCfgSectionHeader(buf, CFG_HEADER_PROFILE_ID); + if (profileID == CUSTOM_PROFILE_ID) // No need to reconfigure + { + PRINT_DEBUG("Current profile is custom - it's always compatible"); + goto compatible; + } + + // find definition for this profile in the current Fw Image json + // Find the appropriate profile + profileName = findProfileById(profileID); + + // if new image isn't configurable then it's not compatible (implicitly) + if (!newImageInfo.isConfigurable) + goto incompatible; + + // Check whether this profile is supported by new image or not + for (size_t i = 0; i < newImageInfo.supportedProfList.size(); i++) + { + if (newImageInfo.supportedProfList[i] == (u_int32_t)profileID) + goto compatible; + } + +incompatible: + PRINT_DEBUG("New FW image is incompatible with existing FW configurations: profile %s (0x%x)!!!", + profileName.c_str(), profileID); + compat = false; + return true; + +compatible: + PRINT_DEBUG("New FW image is compatible with existing FW configurations"); + compat = true; + return true; +} + +/************************************ + * Function: parseProfileDb + ************************************/ +bool MlxConfig::parseProfileDb(const string &jsonTxt) +{ + Json::Value root; + Json::Reader reader; + bool res = reader.parse(jsonTxt, root); + if (!res) + { + _lastMsg = "Failed to parse profiles: " + reader.getFormatedErrorMessages(); + return false; + } + + Json::Value::Members profileNames = root.getMemberNames(); + for (size_t i = 0; i < profileNames.size(); i++) + { + Profile profile; + string profileName = profileNames[i]; + + // Get profile info object + Json::Value profileObj = root.get(profileName, Json::nullValue); + if (!profileObj.isObject()) + { + _lastMsg = "Expected object value in profile: " + profileName + ", not: " + int2string(profileObj.type()); + return false; + } + + // Get profile version + int version = profileObj.get("version", -1).asInt(); + if (version == -1) + { + _lastMsg = "Missing version for profile: " + profileName; + return false; + } + + // Get profile id + int id = profileObj.get("profile_id", -1).asInt(); + if (id == -1) + { + _lastMsg = "Missing profile_id for profile: " + profileName; + return false; + } + + // Get tlvs list + Json::Value tlvsObj = profileObj.get("tlvs", Json::nullValue); + if (!tlvsObj.isArray()) + { + _lastMsg = "Expected object tlv to be array in profile: " + profileName + ", not: " + int2string(tlvsObj.type()); + return false; + } + + // Go over all tlvs + for (size_t j = 0; j < tlvsObj.size(); j++) + { + Tlv tlv; + + Json::Value tlvObj = tlvsObj.get(j, Json::nullValue); + if (!tlvObj.isObject()) + { + _lastMsg = "expected object value for tlv[: " + int2string(j) + "] profile: " + profileName + ", not: " + int2string(tlvObj.type()); + return false; + } + + if (!tlvObj.isMember("TLV_NAME")) + { + _lastMsg = "Missing TLV_NAME in value object for tlv[: " + int2string(j) + "] profile: " + profileName; + return false; + } + tlv.name = tlvObj.get("TLV_NAME", Json::nullValue).asString(); + + // Get tlv fields/value object + Json::Value::Members fieldsNames = tlvObj.getMemberNames(); + for (size_t k = 0; k < fieldsNames.size(); k++) + { + Pair pair; + pair.key = fieldsNames[k]; + if (fieldsNames[k] == "TLV_NAME") + continue; + + Json::Value val = tlvObj.get(fieldsNames[k], Json::nullValue); + if (val.isIntegral()) + { + pair.value = int2string(val.asInt()); + } + else if (val.isString()) + { + pair.value = val.asString(); + } + else + { + _lastMsg = "expected int/string value for field: " + fieldsNames[k] + " tlv[: " + + int2string(j) + "] profile: " + profileName + ", not: " + int2string(tlvObj.type()); + return false; + } + tlv.fields.push_back(pair); + } + + profile.tlvs.push_back(tlv); + } + + // add the new Profile to the profiles map + profile.id = id; + profile.version = version; + + _profilesMap[profileName] = profile; + } + + return true; +} + +/************************************ + * Function: checkOldFW + ************************************/ +bool MlxConfig::checkOldFW(Operations::ImageInfo &flashImageInfo) +{ + // If this the FW that was sent to HP then we need exit and let user run the old mlxconfig tool + // This is because tof he major changes in mlxconfig definitions. + Operations::ImageInfo info; + if (flashImageInfo.fwVer[0] == 2 && + flashImageInfo.fwVer[1] == 10 && + (flashImageInfo.fwVer[2] == 0 || flashImageInfo.fwVer[2] == 1000)) + { + _lastMsg = "You're FW version: " + int2string(flashImageInfo.fwVer[0]) + "." +\ + int2string(flashImageInfo.fwVer[1]) + "." +\ + int2string(flashImageInfo.fwVer[2]) + + " is too old for this tool, consider updating to newer FW or use the old \"mlxconfig\" instead"; + return false; + } + + return true; +} + +/************************************ + * Function: getActiveCfgIdx + ************************************/ +bool MlxConfig::getActiveCfgIdx(Flash* flash, int& idx) // -1 means no active configuration +{ + u_int32_t data0, data1; + // Read first dword from cfg0 + PRINT_DEBUG("Reading first dword from : 0x%x and 0x%x", _cfgAddress[0], _cfgAddress[1]); + if (!flash->read_phy(_cfgAddress[0], &data0) || + !flash->read_phy(_cfgAddress[1], &data1)) + { + _lastMsg = flash->err(); + return false; + } + PRINT_DEBUG("0x%x - 0x%x", data0, data1); + + if (ntohl(data0) == CFG_SIGNATURE) + idx = 0; + else if (ntohl(data1) == CFG_SIGNATURE) + idx = 1; + else + idx = -1; + return true; +} + +/************************************ + * Function: setTlvHeader + ************************************/ +void MlxConfig::setTlvHeader(u_int8_t* buf, enum TlvHeaderField field, u_int32_t value) +{ + AdbInstance* f; + + switch (field) + { + case TLV_HEADER_LENGTH: + f = _adbTlvHeader->getChildByPath("length"); + break; + case TLV_HEADER_ID: + f = _adbTlvHeader->getChildByPath("id"); + break; + case TLV_HEADER_CRC: + f = _adbTlvHeader->getChildByPath("crc16"); + break; + case TLV_HEADER_VERSION: + f = _adbTlvHeader->getChildByPath("version"); + break; + default: + assert(0); + } + + f->pushBuf(buf, value); +} + +/************************************ + * Function: getTlvHeader + ************************************/ +u_int32_t MlxConfig::getTlvHeader(u_int8_t* buf, enum TlvHeaderField field) +{ + AdbInstance* f; + + switch (field) + { + case TLV_HEADER_LENGTH: + f = _adbTlvHeader->getChildByPath("length"); + break; + case TLV_HEADER_ID: + f = _adbTlvHeader->getChildByPath("id"); + break; + case TLV_HEADER_CRC: + f = _adbTlvHeader->getChildByPath("crc16"); + break; + case TLV_HEADER_VERSION: + f = _adbTlvHeader->getChildByPath("version"); + break; + default: + assert(0); + } + + return f->popBuf(buf); +} + +/************************************ + * Function: setCfgSectionHeader + ************************************/ +void MlxConfig::setCfgSectionHeader(u_int8_t* buf, enum CfgHeaderField field, u_int32_t value) +{ + AdbInstance* f; + + switch (field) + { + case CFG_HEADER_SIGNATURE: + f = _adbCfgHeader->getChildByPath("signature"); + break; + case CFG_HEADER_MAX_LEN: + f = _adbCfgHeader->getChildByPath("max_len"); + break; + case CFG_HEADER_VERSION: + f = _adbCfgHeader->getChildByPath("version"); + break; + case CFG_HEADER_PROFILE_ID: + f = _adbCfgHeader->getChildByPath("profile_id"); + break; + case CFG_HEADER_PROFILE_VER: + f = _adbCfgHeader->getChildByPath("profile_ver"); + break; + case CFG_HEADER_CRC: + f = _adbCfgHeader->getChildByPath("crc16"); + break; + default: + assert(0); + } + + f->pushBuf(buf, value); +} + +/************************************ + * Function: getCfgSectionHeader + ************************************/ +u_int32_t MlxConfig::getCfgSectionHeader(u_int8_t* buf, enum CfgHeaderField field) +{ + AdbInstance* f; + + switch (field) + { + case CFG_HEADER_SIGNATURE: + f = _adbCfgHeader->getChildByPath("signature"); + break; + case CFG_HEADER_MAX_LEN: + f = _adbCfgHeader->getChildByPath("max_len"); + break; + case CFG_HEADER_VERSION: + f = _adbCfgHeader->getChildByPath("version"); + break; + case CFG_HEADER_PROFILE_ID: + f = _adbCfgHeader->getChildByPath("profile_id"); + break; + case CFG_HEADER_PROFILE_VER: + f = _adbCfgHeader->getChildByPath("profile_ver"); + break; + case CFG_HEADER_CRC: + f = _adbCfgHeader->getChildByPath("crc16"); + break; + default: + assert(0); + } + + return f->popBuf(buf); +} + +/************************************ + * Function: calcBECrc16 + ************************************/ +u_int16_t MlxConfig::calcBECrc16(const u_int32_t* buf, int num_of_dwords) +{ + Crc16 crc; + for (int i = 0; i < num_of_dwords; i++) + { + crc << ntohl(buf[i]); + } + crc.finish(); + + return crc.get(); +} + +/************************************ + * Function: MlxConfig::getTlvById + ************************************/ +AdbInstance* MlxConfig::getTlvById(int id) +{ + for (size_t i = 0; i < _adbRoot->subItems.size(); i++) + { + int tlvId; + if (!getTlvNodeId(_adbRoot->subItems[i], tlvId)) + return NULL; + + if (tlvId == id) + return _adbRoot->subItems[i]; + } + + return NULL; +} + +/************************************ + * Function: getTlvNodeId + ************************************/ +bool MlxConfig::getTlvNodeId(AdbInstance* node, int &tlvId) +{ + string tlvIdAttr = node->getAttr("tlv_id"); + assert(!tlvIdAttr.empty()); + + errno = 0; + tlvId = strtoul(tlvIdAttr.c_str(), 0, 0); + if (tlvId == 0 && errno == ERANGE) + { + _lastMsg = string("The given tlv id for: ") + node->name + " is invalid"; + return false; + } + + if (tlvId < 0 || tlvId > (int)LAST_TLV_ID) + { + _lastMsg = string("The given tlv id:") + tlvIdAttr + " for: " + node->name + " is out of range"; + return false; + } + + return true; +} + +/************************************ + * Function: getTlvVersion + ************************************/ +bool MlxConfig::getTlvVersion(AdbInstance* node, int &version) +{ + version = 0; + + // Go over all fields + for (size_t i = 0; i < node->subItems.size(); i++) + { + AdbInstance* field = node->subItems[i]; + string minVerAttr = field->getAttr("min_ver"); + int fieldMinVer = 0; + + if (minVerAttr.empty()) + { + fieldMinVer = 0; + } + else + { + errno = 0; + fieldMinVer = strtoul(minVerAttr.c_str(), 0, 0); + if (fieldMinVer == 0 && errno == ERANGE) + { + _lastMsg = string("The given min_ver for field: ") + field->fullName() + + " within node: " + node->name + " is invalid"; + return false; + } + } + + // set version to the maximum between current version and current field + version = version > fieldMinVer ? version : fieldMinVer; + } + + return true; +} + +/************************************ + * Function: getFieldIntValue + ************************************/ +bool MlxConfig::getFieldIntValue(string strVal, AdbInstance* field, u_int64_t &intVal) +{ + char* p; + intVal = strtoul(strVal.c_str(), &p, 0); + + if (*p != 0) // Enum + { + if (!field->enumToInt(strVal, intVal)) + { + _lastMsg = "Can't find enum (" + strVal + ") value for field: " + field->fullName(); + return false; + } + } + + return true; +} + +/************************************ + * Function: findProfileById + ************************************/ +string MlxConfig::findProfileById(u_int32_t profileID) +{ + map::iterator it; + + for (it = _profilesMap.begin(); it != _profilesMap.end(); it++) + { + if (it->second.id == profileID) + { + return it->first; + } + } + return string(); +} + +/************************************ + * Function: printProfileDB + ************************************/ +void MlxConfig::printProfileDB() +{ + map::iterator iter; + + for (iter = _profilesMap.begin(); iter != _profilesMap.end(); iter++) + { + cout << "Profile: " << iter->first << ", "; + iter->second.print(); + cout << endl; + } +} + +/************************************ + * Function: getLastError + ************************************/ +std::string MlxConfig::getLastError() const +{ + return _lastMsg; +} + +/************************************ + * Function: crcVerify + ************************************/ +bool MlxConfig::crcVerify(u_int32_t startAddr, u_int32_t size, string title, + u_int32_t crc, u_int32_t expectedCrc, bool silent) +{ + if (!silent) + printf(CRC_CHECK_OUTPUT, PRE_CRC_OUTPUT, startAddr, startAddr + size - 1, size, title.c_str()); + if (crc == expectedCrc) + { + if (!silent) + printf(" - OK\n"); + return true; + } + else + { + if (!silent) + printf(" - wrong CRC (exp:0x%x, act:0x%x)\n", expectedCrc, crc); + return false; + } +} diff --git a/mlxfwops/lib/mlxconfig.h b/mlxfwops/lib/mlxconfig.h new file mode 100755 index 0000000..8b0d95c --- /dev/null +++ b/mlxfwops/lib/mlxconfig.h @@ -0,0 +1,185 @@ +/* + * + * flint.cpp - FLash INTerface + * + * Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Version: $Id$ + * + */ + +#ifndef MLXCONFIG_H +#define MLXCONFIG_H +#include +#include +#include "flint_ops.h" + +using namespace std; + +/**************************** Forward Declarations *************************/ +class Flash; +class Operations; +struct node_format; +struct field_format; + +#define OLD_MLXCONFIG_VERSION 1 +#define ERASE_CMD "r" +/**************************** Tlv/Profile private helper structs *************************/ +typedef struct +{ + string key; + string value; + + // For debug only + void print(); +} Pair; + +typedef struct +{ + string name; + vector fields; + + // For debug only + void print(); + +} Tlv; + +typedef struct +{ + u_int32_t version; + u_int32_t id; + vector tlvs; + + // For debug only + void print(); +} Profile; + +/**************************** MlxConfig Class *************************/ +class AdbInstance; +class Adb; + +class MlxConfig +{ +public: + enum {CMD_SET = 0, CMD_QUERY, CMD_RESTORE, CMD_LIST_PROFILES, + CMD_RECONFIG, CMD_HELP, CMD_CONFIG_INFO, CMT_VERIFY, CMD_UNKNOWN}; + static const u_int32_t CFG_SIGNATURE = 0x4d544346; + static const u_int32_t CFG_INVALID_SIGNATURE = 0; + static const u_int32_t MLX_CFG_VERSION = 2; + static const u_int32_t LAST_TLV_ID = 0xffff; + static const u_int16_t CUSTOM_PROFILE_ID = 0xffff; + + MlxConfig(); + ~MlxConfig(); + + bool checkFwCfgCompat(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo); + bool setCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo, string profileName, bool silent = false); + bool queryCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo); + bool eraseCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo); + bool listProfilesCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo); + bool reconfigureCfg(Flash* flash, Operations* op, Operations::ImageInfo &newImageInfo); // For flint use post-burn + bool verifyCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo, bool silent = false); + bool setNonFailSafeCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo); // For flint use pre-burn + bool queryProfile(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo, + u_int32_t &profileID, string &profileName); // For flint use + bool configInfo(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo); + bool isConfigPresent(Flash* flash, Operations* op, + Operations::ImageInfo &flashImageInfo, + bool &presents, u_int32_t &configVer); // For flint use + bool checkExistProfileCompat(Flash* flash, Operations* op, + Operations::ImageInfo &flashImageInfo, + Operations::ImageInfo &newImageInfo, + bool &compat); // For flint use + + // run one of the "setCfg" "queryCfg" "eraseCfg" "listProfilesCfg" using cmdline API + bool execute(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo, int argc, const char** argv); + + string getLastError() const; + static const char* getHelpMessage(); + static const char* getRunExamples(); + +private: + bool parseCmdLine(int argc, const char** argv); + bool loadImageData(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo); + bool parseProfileDb(const string &jsonTxt); + bool checkOldFW(Operations::ImageInfo &flashImageInfo); + + // Helpers + bool getActiveCfgIdx(Flash* flash, int& idx); // -1 means no active configuration + + enum TlvHeaderField + { + TLV_HEADER_LENGTH, TLV_HEADER_ID, + TLV_HEADER_CRC, TLV_HEADER_VERSION + }; + void setTlvHeader(u_int8_t* buf, enum TlvHeaderField field, u_int32_t value); + u_int32_t getTlvHeader(u_int8_t* buf, enum TlvHeaderField field); + + enum CfgHeaderField + { + CFG_HEADER_SIGNATURE, CFG_HEADER_MAX_LEN, + CFG_HEADER_VERSION, CFG_HEADER_PROFILE_ID, + CFG_HEADER_PROFILE_VER, CFG_HEADER_CRC + }; + void setCfgSectionHeader(u_int8_t* buf, enum CfgHeaderField field, u_int32_t value); + u_int32_t getCfgSectionHeader(u_int8_t* buf, enum CfgHeaderField); + + u_int16_t calcBECrc16(const u_int32_t* buf, int num_of_dwords); + AdbInstance* getTlvById(int id); + bool getTlvNodeId(AdbInstance* tlvNode, int &tlvId); + bool getTlvVersion(AdbInstance* tlvNode, int &version); + bool getFieldIntValue(string strVal, AdbInstance* field, u_int64_t &intVal); + string findProfileById(u_int32_t profileID); + bool crcVerify(u_int32_t startAddr, u_int32_t size, string title, + u_int32_t crc, u_int32_t expectedCrc, bool silent = false); + // For debug only + void printProfileDB(); + +private: + string _lastMsg; + int _cmd; + string _cmdProfile; + string _cfgFile; + string _profilesFile; + bool _verbose; + + u_int32_t _cfgAddress[2]; // index is image index + u_int32_t _cfgSize; // Cfg section size + bool _isFailSafe; + string _profilesJson; // Contents + Adb* _adbDB; + AdbInstance* _adbRoot; + AdbInstance* _adbTlvHeader; + AdbInstance* _adbCfgHeader; + map _profilesMap; +}; + +#endif // MLXCONFIG_H diff --git a/mlxfwops/lib/mlxconfig_empty.h b/mlxfwops/lib/mlxconfig_empty.h new file mode 100755 index 0000000..3c1ae2c --- /dev/null +++ b/mlxfwops/lib/mlxconfig_empty.h @@ -0,0 +1,53 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + + +#ifndef MLXCONFIG_EMPTY_H +#define MLXCONFIG_EMPTY_H + +// #include +#include "flint_ops.h" + +#define OLD_MLXCONFIG_VERSION 1 +#define ERASE_CMD "r" + +class string +{ +public: + string(); + ~string(); + const char* c_str ( ) const {return (const char*)NULL;} +}; + +class MlxConfig +{ +public: + + MlxConfig(); + ~MlxConfig(); + bool setNonFailSafeCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo); // For flint use pre-burn + string getLastError() const; + bool eraseCfg(Flash* flash, Operations* op, Operations::ImageInfo &flashImageInfo); + bool checkExistProfileCompat(Flash* flash, Operations* op, + Operations::ImageInfo &flashImageInfo, + Operations::ImageInfo &newImageInfo, + bool &compat); // For flint use + bool isConfigPresent(Flash* flash, Operations* op, + Operations::ImageInfo &flashImageInfo, + bool &presents, u_int32_t &configVer); // For flint use + bool reconfigureCfg(Flash* flash, Operations* op, Operations::ImageInfo &newImageInfo); // For flint use post-burn + +}; + +#endif // MLXCONFIG_EMPTY_H diff --git a/mlxfwops/lib/mlxfwops.cpp b/mlxfwops/lib/mlxfwops.cpp new file mode 100755 index 0000000..10b8393 --- /dev/null +++ b/mlxfwops/lib/mlxfwops.cpp @@ -0,0 +1,141 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +// #include + +#include "mlxfwops.h" +#include "fw_ops.h" +#ifdef UEFI_BUILD + #include "uefi_c.h" +#endif + +int mlxfw_open_int(mlxfwops_t** mlxfwops_p, void* fw_hndl, void* extra, char* psid, fw_hndl_type_t hndl_type) +{ + *mlxfwops_p = (mlxfwops_t*) FwOperations::FwOperationsCreate((void*)fw_hndl, extra, psid, hndl_type); + if (*mlxfwops_p == NULL) { + return MLXFW_MEM_ERR; + } + return MLXFW_OK; +} + +MLXFWOP_API int MLXFWOPCALL mlxfw_fw_ver_less_than(u_int16_t ver_a[3], u_int16_t ver_b[3]) +{ + return FwOperations::FwVerLessThan(ver_a, ver_b); +} + +MLXFWOP_API int MLXFWOPCALL mlxfw_open_device(mlxfwops_t** mlxfwops_p, char *handle_name) +{ + return mlxfw_open_int(mlxfwops_p, handle_name, NULL, (char*)NULL, FHT_MST_DEV); +} + +MLXFWOP_API int MLXFWOPCALL mlxfw_open_image(mlxfwops_t** mlxfwops_p, char *file_name, char *psid) +{ + return mlxfw_open_int(mlxfwops_p, file_name, NULL, psid, FHT_FW_FILE); +} + +MLXFWOP_API int MLXFWOPCALL mlxfw_open_buffer(mlxfwops_t** mlxfwops_p, void* buffer, u_int32_t size, char *psid) +{ + return mlxfw_open_int(mlxfwops_p, buffer, &size, psid, FHT_FW_BUFF); +} + +#ifdef UEFI_BUILD +MLXFWOP_API int MLXFWOPCALL mlxfw_open_uefi(mlxfwops_t** mlxfwops_p, uefi_Dev_t* dev, f_fw_cmd fw_cmd_func) +{ + return mlxfw_open_int(mlxfwops_p, dev, (void*)fw_cmd_func, (char*)NULL, FHT_UEFI_DEV); + +} + +MLXFWOP_API int MLXFWOPCALL mlxfw_set_print(mlxfwops_t* mlxfwops, f_prog_func_str print_func) +{ + return !static_cast((void*)mlxfwops)->FwSetPrint(print_func); +} + +#endif +/* +int mlxfw_burn(mlxfwops_t* mlxfwops, char *image_file, u_int8_t force_version) +{ + return 0; +} +*/ + +MLXFWOP_API int MLXFWOPCALL mlxfw_burn(mlxfwops_t* dev_mlxfwops, mlxfwops_t* img_mlxfwops, u_int8_t force_version, f_prog_func prog_func) +{ + return !static_cast((void*)dev_mlxfwops)->FwBurn(static_cast((void*)img_mlxfwops),force_version, prog_func); +} + +MLXFWOP_API int MLXFWOPCALL mlxfw_query(mlxfwops_t* mlxfwops, fw_info_t* fw_info) +{ + return (static_cast((void*)mlxfwops)->FwQuery(fw_info, true) == true) ? MLXFW_OK : MLXFW_ERR_IN_STR; +} + +MLXFWOP_API const char* MLXFWOPCALL mlxfw_exp_rom_type_to_str(u_int16_t type) +{ + if (type == 0xf) { + return "CLP"; + } else { + switch (type) { + case 1: + case 2: + case 3: + case 4: + return "CLP"; + break; + case 0x10: + return "PXE"; + break; + case 0x11: + return "UEFI"; + break; + case 0x21: + return "FCODE"; + break; + + default: + return (const char*)NULL; + } + } + return (const char*)NULL; +} + +MLXFWOP_API int MLXFWOPCALL mlxfw_verify(mlxfwops_t* mlxfwops) +{ + return !static_cast((void*)mlxfwops)->FwVerify((f_prog_func_str)NULL); +} + + +MLXFWOP_API int MLXFWOPCALL mlxfw_test(mlxfwops_t* mlxfwops, u_int32_t *read_data) +{ + return !(static_cast((void*)mlxfwops)->FwTest(read_data)); + +} + +MLXFWOP_API int MLXFWOPCALL mlxfw_read_image(mlxfwops_t* mlxfwops, void* image, u_int32_t* image_size) +{ + return !(static_cast((void*)mlxfwops)->FwReadData(image, image_size)); +} + +MLXFWOP_API void MLXFWOPCALL mlxfw_close(mlxfwops_t* mlxfwops) +{ + static_cast((void*)mlxfwops)->FwCleanUp(); + delete static_cast((void*)mlxfwops); + return; +} + +MLXFWOP_API const char* MLXFWOPCALL mlxfw_get_last_error(mlxfwops_t* mlxfwops) +{ + if (mlxfwops == NULL) { + return "Cannot get last error - No mlxfwops handle"; + } + return (static_cast((void*)mlxfwops)->err()); +} diff --git a/mlxfwops/lib/mlxfwops.h b/mlxfwops/lib/mlxfwops.h new file mode 100755 index 0000000..af856da --- /dev/null +++ b/mlxfwops/lib/mlxfwops.h @@ -0,0 +1,79 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +#ifndef MLXFWOP_H +#define MLXFWOP_H + +#include +#include "mlxfwops_com.h" + +//#include ".h" +// struct FwOperations; +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct mlxfwops mlxfwops_t; + +enum { + MLXFW_OK = 0, + MLXFW_ERR, + MLXFW_MEM_ERR, + MLXFW_ERR_IN_STR, +}; + +struct image_context { + void * data; + u_int32_t size; +}; + +MLXFWOP_API int MLXFWOPCALL mlxfw_open_device(mlxfwops_t** mlxfwops_p, char *device_name); + +MLXFWOP_API int MLXFWOPCALL mlxfw_open_image(mlxfwops_t** mlxfwops_p, char *file_name, char *psid); + +MLXFWOP_API int MLXFWOPCALL mlxfw_open_buffer(mlxfwops_t** mlxfwops_p, void* buffer, u_int32_t size, char *psid); + + +#ifdef UEFI_BUILD + +MLXFWOP_API int MLXFWOPCALL mlxfw_open_uefi(mlxfwops_t** mlxfwops_p, uefi_Dev_t* dev, f_fw_cmd fw_cmd_func); +MLXFWOP_API int MLXFWOPCALL mlxfw_set_print(mlxfwops_t* mlxfwops, f_prog_func_str print_func); + +#endif + +MLXFWOP_API const char* MLXFWOPCALL mlxfw_get_last_error(mlxfwops_t* mlxfwops); + +MLXFWOP_API int MLXFWOPCALL mlxfw_burn(mlxfwops_t* dev_mlxfwops, mlxfwops_t* img_mlxfwops, u_int8_t force_version, f_prog_func prog_func); + +MLXFWOP_API int MLXFWOPCALL mlxfw_read_image(mlxfwops_t* mlxfwops, void* image, u_int32_t* image_size); + +MLXFWOP_API int MLXFWOPCALL mlxfw_verify(mlxfwops_t* mlxfwops); + +MLXFWOP_API int MLXFWOPCALL mlxfw_query(mlxfwops_t* mlxfwops, fw_info_t* fw_query); + +MLXFWOP_API int MLXFWOPCALL mlxfw_type_match(mlxfwops_t* dev_mlxfwops, mlxfwops_t* img_mlxfwops); + +MLXFWOP_API int MLXFWOPCALL mlxfw_fw_ver_less_than(u_int16_t ver_a[3], u_int16_t ver_b[3]); + +MLXFWOP_API const char* MLXFWOPCALL mlxfw_exp_rom_type_to_str(u_int16_t type); + +MLXFWOP_API void MLXFWOPCALL mlxfw_close(mlxfwops_t* mlxfwops); + +MLXFWOP_API int MLXFWOPCALL mlxfw_test(mlxfwops_t* mlxfwops, u_int32_t *read_data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mlxfwops/lib/mlxfwops_com.h b/mlxfwops/lib/mlxfwops_com.h new file mode 100644 index 0000000..c17e9fe --- /dev/null +++ b/mlxfwops/lib/mlxfwops_com.h @@ -0,0 +1,209 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) Jan 2013, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + +#ifndef MLXFWOP_COM_H +#define MLXFWOP_COM_H + +#include +#include + +#ifdef __WIN__ + +#ifdef MLXFWOP_EXPORTS +#define MLXFWOP_API __declspec(dllexport) +#else +#define MLXFWOP_API __declspec(dllimport) +#endif +#define MLXFWOPCALL __cdecl + +#else +#define MLXFWOP_API +#define MLXFWOPCALL +#endif + +#ifndef UEFI_BUILD + #define EFIAPI +#endif + +typedef int EFIAPI (*f_prog_func) (int completion); +typedef int (*f_prog_func_str) (char* str); + +#define VSD_LEN 128 // orenk: BUG - correct val is 208. Fro where did this come from ? +#define PSID_LEN 16 +#define PRODUCT_VER_LEN 16 + +#define FREE_STR_MAX_LEN 256 + +#define MAX_ROMS_NUM 5 +#define MAX_ROM_ERR_MSG_LEN 256 +#define ROM_INFO_SIZE 12 + +//min version that supports Rom Modify +#define MAJOR_MOD_ROM_FW 2 +#define MINOR_MOD_ROM_FW 6 +#define SUBMINOR_MOD_ROM_FW 1410 + +enum { + GUIDS = 4, + MACS = 2, + MAX_GUIDS = 32 +}; + +// needed for flint query +enum { + BX_NP_GUIDS = 2, + BX_SYS_GUIDS = 1, + BX_GUIDS = BX_NP_GUIDS + BX_SYS_GUIDS, + BX_IMACS = 3, + BX_EMACS = 4, + BX_MACS = BX_EMACS + BX_IMACS, + BX_WWPNS = 4, + BX_WWNNS = 1, + BX_SLICE_GUIDS = BX_WWNNS + BX_WWPNS + BX_MACS + BX_NP_GUIDS, + + BX_ALL_GUIDS = (2 * BX_SLICE_GUIDS) + BX_SYS_GUIDS, + BX_SLICES_NUM = 2, +}; + +enum { + BI_IMACS = 0, + BI_EMACS = BI_IMACS + BX_IMACS, + BI_WWPNS = BI_EMACS + BX_EMACS, + BI_GUIDS = BI_WWPNS + BX_WWPNS, + BI_WWNNS = BI_GUIDS + BX_NP_GUIDS, + BI_SYS_GUID = BX_ALL_GUIDS - 1, +}; + +typedef enum chip_type { + CT_UNKNOWN = 0, + CT_CONNECTX, + CT_SWITCHX, + CT_BRIDGEX, + CT_IS4, + CT_CONNECT_IB +}chip_type_t; + +typedef struct guid { + u_int32_t h; + u_int32_t l; +} guid_t; +typedef guid_t hw_key_t; + + +typedef struct rom_info { + u_int16_t exp_rom_product_id; // 0 - invalid. + u_int16_t exp_rom_ver[3]; + u_int16_t exp_rom_dev_id; + u_int8_t exp_rom_port; + u_int8_t exp_rom_proto; + u_int8_t exp_rom_num_ver_fields; + //char expRomFreestr[FREE_STR_MAX_LEN]; +} rom_info_t; + + +struct cib_uid_entry { + u_int8_t num_allocated; + u_int8_t step; + u_int64_t uid; +}; +typedef struct cibfw_uids { + struct cib_uid_entry guids[2]; + struct cib_uid_entry macs[2]; +} uids_t; + + +typedef struct fs3_info_ext { + u_int8_t guids_override_en; + uids_t fs3_uids_info; + uids_t orig_fs3_uids_info; + char image_vsd[VSD_LEN+1]; + char orig_psid[PSID_LEN+1]; + +} fs3_info_t; + + +typedef struct fs2_info_ext { + guid_t guids[MAX_GUIDS]; + u_int32_t guid_num; + u_int32_t config_sectors; + u_int32_t config_pad; + u_int8_t access_key_exists; + guid_t access_key_value; + u_int8_t blank_guids; +} fs2_info_t; + +typedef struct roms_info { + u_int8_t exp_rom_found; + u_int8_t num_of_exp_rom; + u_int8_t no_rom_checksum; + u_int16_t exp_rom_com_devid; + u_int8_t exp_rom_warning; + char exp_rom_warning_msg[MAX_ROM_ERR_MSG_LEN]; + u_int8_t exp_rom_err_msg_valid; + char exp_rom_err_msg[MAX_ROM_ERR_MSG_LEN]; + rom_info_t rom_info[MAX_ROMS_NUM]; +} roms_info_t; + +typedef struct fw_info_com { + char psid[PSID_LEN + 1]; + u_int8_t vsd_sect_found; // relevant to FS2 image only + char vsd[VSD_LEN + 1]; + char product_ver[PRODUCT_VER_LEN + 1]; + u_int16_t fw_ver[3]; + u_int16_t min_fit_ver[4]; + u_int16_t mic_ver[3]; + u_int32_t image_size; + u_int16_t dev_type; + u_int8_t dev_rev; + u_int16_t vsd_vendor_id; + u_int8_t is_failsafe; + chip_type_t chip_type; + roms_info_t roms_info; +} fw_info_com_t; + + +typedef struct fw_info_ext { + u_int8_t fw_type; + fw_info_com_t fw_info; + fs2_info_t fs2_info; + fs3_info_t fs3_info; +} fw_info_t; + +typedef enum fw_hndl_type { + FHT_MST_DEV, + FHT_FW_FILE, + FHT_UEFI_DEV, + FHT_FW_BUFF, +} fw_hndl_type_t; + + +typedef enum fw_img_type { + FIT_FS2, + FIT_FS3, +} fw_img_type_t; + + +enum ExpRomProto { + ER_IB = 0, + ER_ETH = 1, + ER_VPI = 2 +}; + + +typedef struct _MLX4_DEV uefi_Dev_t; +typedef int (*f_fw_cmd) (uefi_Dev_t* dev, void* buffer, int* size); + + + +#endif diff --git a/mstdump/crd_lib/Makefile.am b/mstdump/crd_lib/Makefile.am index d3b466e..28da9b2 100755 --- a/mstdump/crd_lib/Makefile.am +++ b/mstdump/crd_lib/Makefile.am @@ -32,12 +32,21 @@ # Makefile.am -- Process this file with automake to produce Makefile.in -INCLUDES = -I. -I$(top_srcdir)/include/mtcr_ul -AM_CFLAGS = -Wall -W -g -MP -MD -pipe -Wno-unused-function $(COMPILER_FPIC) -DMTCR_EXPORT -DDATA_PATH=\"$(pkgdatadir)\" -noinst_LTLIBRARIES = libcrdump.la +USER_DIR=../.. +MTCR_DIR = $(USER_DIR)/mtcr_ul +INCLUDES = -I. \ + -I$(MTCR_DIR) -I$(USER_DIR)/ -libcrdump_la_SOURCES = crdump.c crdump.h +AM_CFLAGS = -Wall -W -g -MP -MD -pipe -Wno-unused-function $(COMPILER_FPIC) -DDATA_PATH=\"$(pkgdatadir)\" + + +libraryincludedir=$(includedir)/mft/mstdump/ +libraryinclude_HEADERS = crdump.h +lib_LTLIBRARIES = libcrdump.la + + +libcrdump_la_SOURCES = crdump.c libcrdump_la_CFLAGS = $(AM_CFLAGS) diff --git a/mstdump/crd_lib/crdump.c b/mstdump/crd_lib/crdump.c index 2854548..359c142 100755 --- a/mstdump/crd_lib/crdump.c +++ b/mstdump/crd_lib/crdump.c @@ -39,24 +39,24 @@ #include #include #include - -#define CRD_SELECT_CSV_PATH(dev_name) \ - do { \ - strcat(csv_file_path, dev_name); \ - strcat(csv_file_path, ".csv");\ - } while (0) +#include +#define CRD_SELECT_CSV_PATH(dev_name) \ + do { \ + strcat(csv_file_path, dev_name);\ + strcat(csv_file_path, ".csv");\ + } while (0) #define CRD_CHECK_NULL(var)\ - if (var == NULL) \ - do{ \ - CRD_DEBUG("Sent %s is null!\n", #var); \ - return CRD_INVALID_PARM; \ - } while(0) + if (var == NULL) \ + do { \ + CRD_DEBUG("Sent %s is null!\n", #var);\ + return CRD_INVALID_PARM; \ + } while(0) #if defined(__WIN__) - #define strcasecmp _stricmp +#define strcasecmp _stricmp #endif @@ -75,57 +75,57 @@ #define CRD_MAXFLDSIZE 32 /* longest possible field + 1 = 31 byte field */ #define CRD_CSV_PATH_SIZE 300 - +#define CRD_MTCR_DLL_NAME "libmtcr-1.dll" typedef struct crd_parsed_csv { - u_int32_t addr; - u_int32_t len; - char enable_addr[100]; + u_int32_t addr; + u_int32_t len; + char enable_addr[100]; -}crd_parsed_csv_t; +} crd_parsed_csv_t; struct crd_ctxt { - mfile *mf; - u_int32_t dev_type; - u_int32_t number_of_dwords; - int is_full; - int cause_addr; - int cause_off; - char csv_path[300]; - u_int32_t block_count; - crd_parsed_csv_t * blocks; + mfile *mf; + u_int32_t dev_type; + u_int32_t number_of_dwords; + int is_full; + int cause_addr; + int cause_off; + char csv_path[300]; + u_int32_t block_count; + crd_parsed_csv_t * blocks; }; static char crd_error[256]; /* Store the csv file path at csv_file_path. -*/ + */ static int crd_get_csv_path(IN dm_dev_id_t dev_type, OUT char *csv_file_path); /* count number of dwords, and store all needed data from csv file at parsed_csv -*/ + */ static int crd_count_double_word(IN char *csv_file_path, OUT u_int32_t *number_of_dwords, OUT crd_parsed_csv_t blocks[], IN int is_full); /* Fill addresses at dword_arr -*/ + */ static int crd_fill_address(IN crd_ctxt_t *context, OUT crd_dword_t * dword_arr); /* Read a line from csv file -*/ + */ static int crd_read_line(IN FILE *fd, OUT char *tmp); /* Tokenize line for address, len, and enable_adder -*/ + */ static void crd_parse(IN char *record, IN char *delim, OUT char arr[][CRD_MAXFLDSIZE], OUT int *field_count); -static void crd_update_csv_path(IN OUT char *csv_file_path); +static int crd_update_csv_path(IN OUT char *csv_file_path); static int crd_count_blocks(IN char *csv_file_path, OUT u_int32_t *block_count); @@ -133,348 +133,355 @@ static int crd_replace(INOUT char *st, IN char *orig, IN char *repl); static int crd_get_exec_name_from_path(IN char *str, OUT char *exec_name); -int crd_init(OUT crd_ctxt_t **context, IN mfile *mf, IN int is_full, IN int cause_addr, IN int cause_off){ - - dm_dev_id_t dev_type; - u_int32_t dev_id; - u_int32_t chip_rev; - u_int32_t number_of_dwords = 0; - u_int32_t block_count; - char csv_file_path [CRD_CSV_PATH_SIZE] = {0x0}; - - - int rc = CRD_OK; - - CRD_CHECK_NULL(mf); - CRD_CHECK_NULL(context); - - if (cause_addr >= 0 && cause_off < 0){ - CRD_DEBUG("cause_off is negative : %d ", cause_off); - return CRD_INVALID_PARM; - } - CRD_DEBUG("getting device id\n"); - if (dm_get_device_id(mf, &dev_type, &dev_id, &chip_rev)) { - CRD_DEBUG("Failed to identify device."); - return CRD_UNKOWN_DEVICE; - } - - CRD_DEBUG("Device type : 0x%x, device id : 0x%x, chip rev : 0x%x\n", dev_type, dev_id, chip_rev); - if (crd_get_csv_path(dev_type, csv_file_path)){ - return CRD_UNKOWN_DEVICE; - } - - - CRD_DEBUG("allocating struct\n"); - *context = (crd_ctxt_t*)malloc(sizeof(crd_ctxt_t)); - if (*context == NULL){ - CRD_DEBUG("Failed to allocate memmory for context \n"); - return CRD_MEM_ALLOCATION_ERR; - } - - rc = crd_count_blocks(csv_file_path, &block_count); - if (rc){ - goto Cleanup; - } - CRD_DEBUG("Block count : %d\n", block_count); - - (*context)->blocks = (crd_parsed_csv_t *) malloc(sizeof(crd_parsed_csv_t) * block_count); - if ((*context)->blocks == NULL){ - CRD_DEBUG("Failed to allocate memmory for csv blocks\n"); - return CRD_MEM_ALLOCATION_ERR; - } - - - rc = crd_count_double_word(csv_file_path, &number_of_dwords, (*context)->blocks, is_full); - if (rc){ - goto Cleanup; - } - - CRD_DEBUG("Number of found dwords are : %d \n", number_of_dwords); - (*context)->mf = mf; - (*context)->dev_type = dev_type; - (*context)->number_of_dwords = number_of_dwords; - (*context)->is_full = is_full; - (*context)->block_count = block_count; - (*context)->cause_addr = cause_addr; - (*context)->cause_off = cause_off; - strcpy((*context)->csv_path, csv_file_path); - return rc; - - Cleanup: - crd_free(*context); - return rc; -} +static char *crd_trim(char *s); +static char *crd_rtrim(char *s); -int crd_get_addr_list(IN crd_ctxt_t *context, OUT crd_dword_t* dword_arr){ +static char *crd_ltrim(char *s); - int rc; +int crd_init(OUT crd_ctxt_t **context, IN mfile *mf, IN int is_full, IN int cause_addr, IN int cause_off) { - CRD_CHECK_NULL(context); - CRD_CHECK_NULL(dword_arr); - - rc = crd_fill_address(context, dword_arr); - if (rc){ - return rc; - } + dm_dev_id_t dev_type; + u_int32_t dev_id; + u_int32_t chip_rev; + u_int32_t number_of_dwords = 0; + u_int32_t block_count; + char csv_file_path [CRD_CSV_PATH_SIZE] = {0x0}; - return CRD_OK; -} -int crd_dump_data(IN crd_ctxt_t *context, OUT crd_dword_t* dword_arr, IN crd_callback_t func){ + int rc = CRD_OK; + + CRD_CHECK_NULL(mf); + CRD_CHECK_NULL(context); + + if (cause_addr >= 0 && cause_off < 0) { + CRD_DEBUG("cause_off is negative : %d ", cause_off); + return CRD_INVALID_PARM; + } + CRD_DEBUG("getting device id\n"); + if (dm_get_device_id(mf, &dev_type, &dev_id, &chip_rev)) { + CRD_DEBUG("Failed to identify device."); + return CRD_UNKOWN_DEVICE; + } - u_int32_t i = 0; - u_int32_t j = 0; - u_int32_t rc; - u_int32_t addr; - u_int32_t cause_reg; + CRD_DEBUG("Device type : 0x%x, device id : 0x%x, chip rev : 0x%x\n", dev_type, dev_id, chip_rev); + if ((rc = crd_get_csv_path(dev_type, csv_file_path)) != CRD_OK) { + return rc; + } - int total = 0; - char *data; - crd_dword_t tmp_dword; - - CRD_CHECK_NULL(context); - if (dword_arr == NULL && func == NULL){ - CRD_DEBUG("Nothing to do\n"); - return CRD_INVALID_PARM; - } + CRD_DEBUG("allocating struct\n"); + *context = (crd_ctxt_t*)malloc(sizeof(crd_ctxt_t)); + if (*context == NULL) { + CRD_DEBUG("Failed to allocate memmory for context \n"); + return CRD_MEM_ALLOCATION_ERR; + } - for(i = 0; i< context->block_count; i++){ - if(!context->is_full && strcmp(context->blocks[i].enable_addr, CRD_EMPTY)){ - continue; + rc = crd_count_blocks(csv_file_path, &block_count); + if (rc) { + free(*context); + return rc; } - - data = (char*) malloc (context->blocks[i].len * sizeof(u_int32_t)); - if (data == NULL){ - return CRD_MEM_ALLOCATION_ERR; + CRD_DEBUG("Block count : %d\n", block_count); + + (*context)->blocks = (crd_parsed_csv_t *) malloc(sizeof(crd_parsed_csv_t) * block_count); + if ((*context)->blocks == NULL) { + CRD_DEBUG("Failed to allocate memmory for csv blocks\n"); + free(*context); + return CRD_MEM_ALLOCATION_ERR; } - rc = mread4_block (context->mf, context->blocks[i].addr, (u_int32_t *)data, context->blocks[i].len * sizeof(u_int32_t)); - if (context->blocks[i].len * sizeof(u_int32_t) != rc){ - sprintf(crd_error, "Cr read (0x%08x) failed: %s(%d)", context->blocks[i].addr, strerror(errno), (u_int32_t)errno); - free(data); - return CRD_CR_READ_ERR; + + rc = crd_count_double_word(csv_file_path, &number_of_dwords, (*context)->blocks, is_full); + if (rc) { + goto Cleanup; } - for (j = 0; j< context->blocks[i].len; j++){ - - if ((u_int32_t)total >= context->number_of_dwords){ // dummy check tadah! - CRD_DEBUG("value exceeded, something wrong in calculation!"); - return CRD_EXCEED_VALUE; - } - - addr = context->blocks[i].addr + (j * sizeof(u_int32_t)); - - - if (context->cause_addr >= 0) { /* if we want to check cause bit - read it and verify it hasn't been raised */ - if (mread4(context->mf, context->cause_addr, &cause_reg) != sizeof(u_int32_t)){ - CRD_DEBUG("Cr read (0x%08x) failed: %s(%d)\n", context->cause_addr, strerror(errno), (u_int32_t)errno); - sprintf(crd_error, "Cr read (0x%08x) failed: %s(%d)", context->cause_addr, strerror(errno), (u_int32_t)errno); - free(data); - return CRD_CR_READ_ERR; - } - cause_reg = EXTRACT(cause_reg, context->cause_off, 1); - if (cause_reg) { - CRD_DEBUG("Cause bit set by read from address 0x%x\n", addr); - sprintf(crd_error, "Cause bit set by read from address 0x%x", addr); - free(data); - return CRD_CAUSE_BIT; - } - } - - if(dword_arr != NULL){ - dword_arr[total].addr = addr; - dword_arr[total].data = ((u_int32_t*)data)[j]; - } - if (func != NULL){ - tmp_dword.addr = addr; - tmp_dword.data = ((u_int32_t*)data)[j]; - func(&tmp_dword); - } - total += 1; + CRD_DEBUG("Number of found dwords are : %d \n", number_of_dwords); + (*context)->mf = mf; + (*context)->dev_type = dev_type; + (*context)->number_of_dwords = number_of_dwords; + (*context)->is_full = is_full; + (*context)->block_count = block_count; + (*context)->cause_addr = cause_addr; + (*context)->cause_off = cause_off; + strcpy((*context)->csv_path, csv_file_path); + return rc; + + Cleanup: + crd_free(*context); + return rc; +} + + +int crd_get_addr_list(IN crd_ctxt_t *context, OUT crd_dword_t* dword_arr) { + + int rc; + + CRD_CHECK_NULL(context); + CRD_CHECK_NULL(dword_arr); + + rc = crd_fill_address(context, dword_arr); + if (rc) { + return rc; } - free(data); - } - return CRD_OK; + return CRD_OK; } -int crd_get_dword_num(IN crd_ctxt_t *context, OUT u_int32_t *arr_size){ +int crd_dump_data(IN crd_ctxt_t *context, OUT crd_dword_t* dword_arr, IN crd_callback_t func) { + + u_int32_t i = 0; + u_int32_t j = 0; + u_int32_t rc; + u_int32_t addr; + u_int32_t cause_reg; - CRD_CHECK_NULL(context); + int total = 0; + char *data; + crd_dword_t tmp_dword; - *arr_size = context->number_of_dwords; + CRD_CHECK_NULL(context); - return CRD_OK; + if (dword_arr == NULL && func == NULL) { + CRD_DEBUG("Nothing to do\n"); + return CRD_INVALID_PARM; + } + + for(i = 0; i< context->block_count; i++) { + if(!context->is_full && strcmp(context->blocks[i].enable_addr, CRD_EMPTY)) { + continue; + } + + data = (char*) malloc (context->blocks[i].len * sizeof(u_int32_t)); + if (data == NULL) { + return CRD_MEM_ALLOCATION_ERR; + } + + rc = mread4_block (context->mf, context->blocks[i].addr, (u_int32_t *)data, context->blocks[i].len * sizeof(u_int32_t)); + if (context->blocks[i].len * sizeof(u_int32_t) != rc) { + sprintf(crd_error, "Cr read (0x%08x) failed: %s(%d)", context->blocks[i].addr, strerror(errno), (u_int32_t)errno); + free(data); + return CRD_CR_READ_ERR; + } + + for (j = 0; j< context->blocks[i].len; j++) { + if ((u_int32_t)total >= context->number_of_dwords) { // dummy check tadah! + CRD_DEBUG("value exceeded, something wrong in calculation!"); + return CRD_EXCEED_VALUE; + } + addr = context->blocks[i].addr + (j * sizeof(u_int32_t)); + + if (context->cause_addr >= 0) { /* if we want to check cause bit - read it and verify it hasn't been raised */ + if (mread4(context->mf, context->cause_addr, &cause_reg) != sizeof(u_int32_t)) { + CRD_DEBUG("Cr read (0x%08x) failed: %s(%d)\n", context->cause_addr, strerror(errno), (u_int32_t)errno); + sprintf(crd_error, "Cr read (0x%08x) failed: %s(%d)", context->cause_addr, strerror(errno), (u_int32_t)errno); + free(data); + return CRD_CR_READ_ERR; + } + cause_reg = EXTRACT(cause_reg, context->cause_off, 1); + if (cause_reg) { + CRD_DEBUG("Cause bit set by read from address 0x%x\n", addr); + sprintf(crd_error, "Cause bit set by read from address 0x%x", addr); + free(data); + return CRD_CAUSE_BIT; + } + } + + if(dword_arr != NULL) { + dword_arr[total].addr = addr; + dword_arr[total].data = ((u_int32_t*)data)[j]; + } + if (func != NULL) { + tmp_dword.addr = addr; + tmp_dword.data = ((u_int32_t*)data)[j]; + func(&tmp_dword); + } + total += 1; + } + free(data); + } + return CRD_OK; } +int crd_get_dword_num(IN crd_ctxt_t *context, OUT u_int32_t *arr_size) { -static int crd_get_csv_path(IN dm_dev_id_t dev_type, OUT char *csv_file_path){ - - char dev_name[100]; - - switch (dev_type) { - case DeviceArbel: - case DeviceArbelMF: - case DeviceTavor: - case DeviceAnafa: - return CRD_NOT_SUPPORTED; - default: - strcpy(dev_name, dm_dev_type2str_ext(dev_type)); - } - if (!strcmp(dev_name, "Unknown Device")){ - return CRD_UNKOWN_DEVICE; - } - - crd_update_csv_path(csv_file_path); - CRD_SELECT_CSV_PATH(dev_name); - return CRD_OK; + CRD_CHECK_NULL(context); + *arr_size = context->number_of_dwords; + return CRD_OK; } -static void crd_parse(IN char *record, IN char *delim, OUT char arr[][CRD_MAXFLDSIZE], OUT int *field_count){ - - char *p = strtok(record, delim); - int field = 0; - strcpy(arr[0],"\0"); - strcpy(arr[1],"\0"); - strcpy(arr[2],"\0"); - while(p) - { - strcpy(arr[field], p); - field++; - p = strtok('\0', delim); + +static int crd_get_csv_path(IN dm_dev_id_t dev_type, OUT char *csv_file_path) { + + char dev_name[100]; + int rc; + switch (dev_type) { + case DeviceArbel: + case DeviceArbelMF: + case DeviceTavor: + case DeviceAnafa: + case DeviceSinai: + return CRD_NOT_SUPPORTED; + default: + strcpy(dev_name, dm_dev_type2str_ext(dev_type)); } - *field_count = field; + if (!strcmp(dev_name, "Unknown Device")) { + return CRD_UNKOWN_DEVICE; + } + + rc = crd_update_csv_path(csv_file_path); + if (rc != CRD_OK) { + return rc; + } + CRD_SELECT_CSV_PATH(dev_name); + return CRD_OK; } -static int crd_count_blocks(IN char *csv_file_path, OUT u_int32_t *block_count){ - - char tmp[1024] = {0x0}; - *block_count = 0; - - CRD_DEBUG("CSV file path : %s\n", csv_file_path); - FILE * fd = fopen(csv_file_path, "r"); - if (fd == NULL){ - CRD_DEBUG("Failed to open csv file : %s\n", csv_file_path); - sprintf(crd_error, "Failed to open csv file : %s", csv_file_path); - return CRD_OPEN_FILE_ERROR; - } - while(!feof(fd)){ - if (crd_read_line(fd, tmp) == CRD_SKIP){ - continue; +static void crd_parse(IN char *record, IN char *delim, OUT char arr[][CRD_MAXFLDSIZE], + OUT int *field_count) { + + char *p = strtok(record, delim); + int field = 0; + strcpy(arr[0],"\0"); + strcpy(arr[1],"\0"); + strcpy(arr[2],"\0"); + while(p) { + strcpy(arr[field], p); + field++; + p = strtok('\0', delim); } - *block_count += 1; - } - return CRD_OK; + *field_count = field; } -static int crd_count_double_word(IN char *csv_file_path, OUT u_int32_t *number_of_dwords, OUT crd_parsed_csv_t blocks[], IN int is_full){ - - int field_count = 0; - int block_count = 0; - char tmp[1024] = {0x0}; - char arr[CRD_MAXFLDS][CRD_MAXFLDSIZE] ; - - *number_of_dwords = 0; - - CRD_DEBUG("CSV file path : %s\n", csv_file_path); - FILE * fd = fopen(csv_file_path, "r"); - if (fd == NULL){ - CRD_DEBUG("Failed to open csv file : %s\n", csv_file_path); - sprintf(crd_error, "Failed to open csv file : %s", csv_file_path); - return CRD_OPEN_FILE_ERROR; - } - - while(!feof(fd)){ - if (crd_read_line(fd, tmp) == CRD_SKIP){ - continue; +static int crd_count_blocks(IN char *csv_file_path, OUT u_int32_t *block_count) { + + char tmp[1024] = {0x0}; + *block_count = 0; + + CRD_DEBUG("CSV file path : %s\n", csv_file_path); + FILE * fd = fopen(csv_file_path, "r"); + if (fd == NULL) { + CRD_DEBUG("Failed to open csv file : '%s'\n", csv_file_path); + sprintf(crd_error, "Failed to open csv file : '%s'", csv_file_path); + return CRD_OPEN_FILE_ERROR; } - crd_parse(tmp, ",", arr, &field_count); /* whack record into fields */ - if (field_count < 2 ){ - CRD_DEBUG("CSV File has bad format, line : %s\n", tmp); - sprintf(crd_error, "CSV File has bad format, line : %s", tmp); - fclose(fd); - return CRD_CSV_BAD_FORMAT; + while(!feof(fd)) { + if (crd_read_line(fd, tmp) == CRD_SKIP) { + continue; + } + *block_count += 1; } + return CRD_OK; +} + +static int crd_count_double_word(IN char *csv_file_path, OUT u_int32_t *number_of_dwords, + OUT crd_parsed_csv_t blocks[], IN int is_full) { + + int field_count = 0; + int block_count = 0; + char tmp[1024] = {0x0}; + char arr[CRD_MAXFLDS][CRD_MAXFLDSIZE] ; - blocks[block_count].addr = (u_int32_t)strtol(arr[0], NULL, 0); - blocks[block_count].len = atoi(arr[1]); - if (field_count > 2) { - strcpy(blocks[block_count].enable_addr, arr[2]); - if(is_full || (!is_full && !strcmp(blocks[block_count].enable_addr, CRD_EMPTY))) { - *number_of_dwords += atoi(arr[1]); - } + *number_of_dwords = 0; + + CRD_DEBUG("CSV file path : %s\n", csv_file_path); + FILE * fd = fopen(csv_file_path, "r"); + if (fd == NULL) { + CRD_DEBUG("Failed to open csv file : '%s'\n", csv_file_path); + sprintf(crd_error, "Failed to open csv file : '%s'", csv_file_path); + return CRD_OPEN_FILE_ERROR; } - else { - strcpy(blocks[block_count].enable_addr, CRD_EMPTY); - *number_of_dwords += atoi(arr[1]); + + while(!feof(fd)) { + if (crd_read_line(fd, tmp) == CRD_SKIP) { + continue; + } + crd_parse(tmp, ",", arr, &field_count); /* whack record into fields */ + if (field_count < 2 ) { + CRD_DEBUG("CSV File has bad format, line : %s\n", tmp); + sprintf(crd_error, "CSV File has bad format, line : %s", tmp); + fclose(fd); + return CRD_CSV_BAD_FORMAT; + } + + blocks[block_count].addr = (u_int32_t)strtol(arr[0], NULL, 0); + blocks[block_count].len = atoi(arr[1]); + if (field_count > 2) { + strcpy(blocks[block_count].enable_addr, arr[2]); + if(is_full || (!is_full && !strcmp(blocks[block_count].enable_addr, CRD_EMPTY))) { + *number_of_dwords += atoi(arr[1]); + } + } + else { + strcpy(blocks[block_count].enable_addr, CRD_EMPTY); + *number_of_dwords += atoi(arr[1]); + } + block_count += 1; } - block_count += 1; - } - fclose(fd); - return CRD_OK; + fclose(fd); + return CRD_OK; } -static int crd_fill_address(IN crd_ctxt_t *context, OUT crd_dword_t * dword_arr){ - u_int32_t i = 0; - u_int32_t j = 0; - int total = 0; - - for(i = 0; i< context->block_count; i++){ - for(j = 0; j< context->blocks[i].len; j++){ - - //CRD_UNKOWN, CRD_EMPTY - if(!context->is_full && strcmp(context->blocks[i].enable_addr, CRD_EMPTY)){ - break; - } - if ((u_int32_t)total >= context->number_of_dwords){ - CRD_DEBUG("value exceeded, something wrong in calculation!"); - return CRD_EXCEED_VALUE; - } - dword_arr[total].addr = context->blocks[i].addr + (j * 4); - total += 1; +static int crd_fill_address(IN crd_ctxt_t *context, OUT crd_dword_t * dword_arr) { + u_int32_t i = 0; + u_int32_t j = 0; + int total = 0; + + for(i = 0; i< context->block_count; i++) { + for(j = 0; j< context->blocks[i].len; j++) { + + //CRD_UNKOWN, CRD_EMPTY + if(!context->is_full && strcmp(context->blocks[i].enable_addr, CRD_EMPTY)) { + break; + } + if ((u_int32_t)total >= context->number_of_dwords) { + CRD_DEBUG("value exceeded, something wrong in calculation!"); + return CRD_EXCEED_VALUE; + } + dword_arr[total].addr = context->blocks[i].addr + (j * 4); + total += 1; + } } - } - return CRD_OK; + return CRD_OK; } -static int crd_read_line(IN FILE *fd, OUT char *tmp){ - - int i = 0; - int j = 0; - for (i = 0; i < CRD_MAXLINESIZE;) { // This loop to read line by line no matter the length of the line. - if (!feof(fd)){ - int c = fgetc(fd); - if (c == '#'){ - fgets (tmp, 300, fd); - tmp[0] = 0; - continue; - } - else if (c == '\r'){ - break; - } - else if (c == '\n'){ - break; - } - else if (c == ' '){ - continue; - } - else{ - j++; - tmp[i] = c; - i++; - } +static int crd_read_line(IN FILE *fd, OUT char *tmp) { + + int i = 0; + int j = 0; + for (i = 0; i < CRD_MAXLINESIZE;) { // This loop to read line by line no matter the length of the line. + if (!feof(fd)) { + int c = fgetc(fd); + if (c == '#') { + fgets (tmp, 300, fd); + tmp[0] = 0; + continue; + } + else if (c == '\r') { + break; + } + else if (c == '\n') { + break; + } + else if (c == ' ') { + continue; + } + else { + j++; + tmp[i] = c; + i++; + } + } + else { + return CRD_SKIP; + } } - else { - return CRD_SKIP; + if (!j) { + return CRD_SKIP; } - } - if (!j){ - return CRD_SKIP; - } - tmp[i] = 0; - return CRD_OK; + tmp[i] = 0; + return CRD_OK; } static int crd_replace(INOUT char *st, IN char *orig, IN char *repl) { @@ -492,76 +499,119 @@ static int crd_replace(INOUT char *st, IN char *orig, IN char *repl) { return CRD_OK; } -static int crd_get_exec_name_from_path(IN char *str, OUT char *exec_name) -{ +static int crd_get_exec_name_from_path(IN char *str, OUT char *exec_name) { char tmp_str[strlen(str) + 1]; char * pch; - strcpy(tmp_str, str); pch = strtok (tmp_str,"\\"); - while (pch != NULL) - { + while (pch != NULL) { strcpy(exec_name, pch); pch = strtok (NULL, "\\"); } return CRD_OK; } -#define MTCR_DLL_NAME "libmtcr-1.dll" - -static void crd_update_csv_path(IN OUT char *csv_file_path){ - #ifdef __WIN__ - char exec_name[CRD_CSV_PATH_SIZE]; - GetModuleFileName(GetModuleHandle(MTCR_DLL_NAME), csv_file_path, CRD_CSV_PATH_SIZE); - crd_get_exec_name_from_path(csv_file_path, exec_name); - crd_replace(csv_file_path, exec_name, "mstdump_dbs\\"); - #else - strcat(csv_file_path, DATA_PATH "/"); - #endif -} - -void crd_free(IN crd_ctxt_t *context){ - free(context->blocks); - free(context); +static char *crd_ltrim(char *s) { + while(isspace(*s)){ + s++; + } + return s; } +static char *crd_rtrim(char *s) { + char* back; + int len = strlen(s); -const char* crd_err_str(int rc) -{ - switch (rc) - { - case CRD_OK: - return "Ok"; - case CRD_MEM_ALLOCATION_ERR: - return "Memory allocation error"; - - case CRD_CR_READ_ERR: - return crd_error; + if(len == 0) { + return(s); + } + back = s + len; + while(isspace(*--back)); + *(back+1) = '\0'; + return s; +} - case CRD_INVALID_PARM: - return "Invalid parameter"; +static char *crd_trim(char *s){ + return crd_rtrim(crd_ltrim(s)); +} - case CRD_UNKOWN_DEVICE: - return "Unknown/Unsupported device"; - case CRD_CSV_BAD_FORMAT: - return crd_error; +static int crd_update_csv_path(IN OUT char *csv_file_path) { - case CRD_OPEN_FILE_ERROR: - return crd_error; + int found = 0; +#ifdef __WIN__ + char exec_name[CRD_CSV_PATH_SIZE]; + GetModuleFileName(GetModuleHandle(CRD_MTCR_DLL_NAME), csv_file_path, CRD_CSV_PATH_SIZE); + crd_get_exec_name_from_path(csv_file_path, exec_name); + crd_replace(csv_file_path, exec_name, "mstdump_dbs\\"); + found = 1; +#else + char conf_path[256] = "/etc/mft/mft.conf"; + char *data_path; + char * line = NULL; + size_t len = 0; + FILE *fd = fopen(conf_path, "r"); + if (fd == NULL) { + CRD_DEBUG("Failed to open conf file : %s\n", conf_path); + sprintf(crd_error, "Failed to open conf file : %s", conf_path); + return CRD_OPEN_FILE_ERROR; + } - case CRD_SKIP: - return "Skip"; + while ((getline(&line, &len, fd)) != -1) { + if(strstr(line, "mstdump_dbs") != NULL) { + data_path = strtok(line, "="); + if (data_path != NULL) { + data_path = strtok(NULL, "="); + if (data_path != NULL) { + strcpy(csv_file_path, crd_trim(data_path)); + strcat(csv_file_path, "/"); + found = 1; + break; + } + } + } + } + //strcat(csv_file_path, DATA_PATH "/mstdump_dbs/"); +#endif + if (!found) { + return CRD_CONF_BAD_FORMAT; + } + return CRD_OK; +} - case CRD_NOT_SUPPORTED: - return "Not supported"; +void crd_free(IN crd_ctxt_t *context) { + free(context->blocks); + free(context); +} - case CRD_EXCEED_VALUE: - return "Value exceed"; - case CRD_CAUSE_BIT: - return crd_error; - default: - return "Unknown error"; +const char* crd_err_str(int rc) { + switch (rc) { + case CRD_OK: + return "Ok"; + case CRD_MEM_ALLOCATION_ERR: + return "Memory allocation error"; + case CRD_CR_READ_ERR: + return crd_error; + case CRD_INVALID_PARM: + return "Invalid parameter"; + case CRD_UNKOWN_DEVICE: + return "Unknown/Unsupported device"; + case CRD_CSV_BAD_FORMAT: + return crd_error; + case CRD_CONF_BAD_FORMAT: + return "Conf file has no valid mstdumb_db path."; + case CRD_OPEN_FILE_ERROR: + return crd_error; + case CRD_SKIP: + return "Skip"; + case CRD_NOT_SUPPORTED: + return "Not supported"; + case CRD_EXCEED_VALUE: + return "Value exceed"; + case CRD_CAUSE_BIT: + return crd_error; + default: + return "Unknown error"; } } diff --git a/mstdump/crd_lib/crdump.h b/mstdump/crd_lib/crdump.h index 911435e..0df0980 100644 --- a/mstdump/crd_lib/crdump.h +++ b/mstdump/crd_lib/crdump.h @@ -44,25 +44,26 @@ extern "C" { #endif enum crd_return_code { - CRD_OK = 0, - CRD_MEM_ALLOCATION_ERR, - CRD_CR_READ_ERR, - CRD_INVALID_PARM, - CRD_UNKOWN_DEVICE, - CRD_CSV_BAD_FORMAT, - CRD_OPEN_FILE_ERROR, - CRD_SKIP, - CRD_NOT_SUPPORTED, - CRD_EXCEED_VALUE, - CRD_CAUSE_BIT, + CRD_OK = 0, + CRD_MEM_ALLOCATION_ERR, + CRD_CR_READ_ERR, + CRD_INVALID_PARM, + CRD_UNKOWN_DEVICE, + CRD_CSV_BAD_FORMAT, + CRD_CONF_BAD_FORMAT, + CRD_OPEN_FILE_ERROR, + CRD_SKIP, + CRD_NOT_SUPPORTED, + CRD_EXCEED_VALUE, + CRD_CAUSE_BIT, }; typedef struct crd_ctxt crd_ctxt_t; typedef struct crd_dword { - u_int32_t addr; - u_int32_t data; + u_int32_t addr; + u_int32_t data; } crd_dword_t; @@ -85,33 +86,33 @@ typedef void (*crd_callback_t) (crd_dword_t *); // call back Must be called before others methods to allocat memory and store all needed configuration -*/ + */ int crd_init(OUT crd_ctxt_t **context, IN mfile *mf, IN int is_full, IN int cause, IN int cause_off); // fill device type, and number of dewords according to the is_full /* Store cr space length at arr_size -*/ + */ int crd_get_dword_num(IN crd_ctxt_t *context, OUT u_int32_t *arr_size); /* Store all addresses are dword_arr array -*/ + */ int crd_get_addr_list(IN crd_ctxt_t *context, OUT crd_dword_t* dword_arr); // caller well allocate the array and addresses will be filled. /* Store all addresses and data in dword_arr, if func is not null, it will be called on each dword -*/ + */ int crd_dump_data(IN crd_ctxt_t *context, OUT crd_dword_t* dword_arr, IN crd_callback_t func);// values will be filled. /* Return string representation of the error code -*/ + */ const char* crd_err_str(int rc); /* Free context -*/ + */ void crd_free(IN crd_ctxt_t *context); #ifdef __cplusplus diff --git a/mstdump/crd_main/Makefile.am b/mstdump/crd_main/Makefile.am index f271fab..5b7ab43 100755 --- a/mstdump/crd_main/Makefile.am +++ b/mstdump/crd_main/Makefile.am @@ -31,13 +31,15 @@ #-- # Makefile.am -- Process this file with automake to produce Makefile.in -INCLUDES = -I. -I$(srcdir)/../crd_lib -I$(top_srcdir)/include/mtcr_ul +MTCR_DIR = ../../mtcr_ul +USER_DIR = ../.. +INCLUDES = -I. -I ../crd_lib -I$(MTCR_DIR) -I$(USER_DIR) -I../../udump/mstdump -AM_CFLAGS = -MD -pipe -g -Wall -W +AM_CPPFLAGS = -MD -pipe -g -Wall -W -Werror -bin_PROGRAMS = mstregdump +bin_PROGRAMS = mstdump -mstregdump_SOURCES = mstdump.c +mstdump_SOURCES = mstdump.c -mstregdump_LDADD = ../crd_lib/libcrdump.la ../../dev_mgt/libdev_mgt.la ../../mtcr_ul/libmtcr_ul.a -lm -ldl +mstdump_LDADD = ../crd_lib/libcrdump.la $(USER_DIR)/dev_mgt/libdev_mgt.la $(MTCR_DIR)/libmtcr_ul.a -lm -ldl diff --git a/mstdump/crd_main/mstdump.c b/mstdump/crd_main/mstdump.c index 58efd7c..3160501 100755 --- a/mstdump/crd_main/mstdump.c +++ b/mstdump/crd_main/mstdump.c @@ -42,18 +42,16 @@ #include +#define CAUSE_FLAG "--cause" // string explaining the cmd-line structure char correct_cmdline[] = "[-full] [i2c-slave] [-v[ersion] [-h[elp]]]"; - - void print_dword(crd_dword_t *dword) { printf("0x%8.8x 0x%8.8x\n", dword->addr, dword->data); } -int main(int argc, char** argv) -{ +int main(int argc, char** argv) { int i ; mfile *mf; int rc; @@ -66,28 +64,27 @@ int main(int argc, char** argv) } for (i = 1; i < argc; ++i) { - #define CAUSE_FLAG "--cause" /* check position-independent flags */ - if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help")){ - fprintf(stderr, "Usage: %s %s.\n", argv[0], correct_cmdline); - exit (0); - } - else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "-version")) { - print_version_string("mstdump", ""); - exit(0); - } - else if (!strncmp(argv[i], CAUSE_FLAG, strlen(CAUSE_FLAG))) { - if (sscanf(argv[i], CAUSE_FLAG"=%i.%d", &cause_addr, &cause_off) != 2) { - fprintf(stderr, "Invalid parameters to " CAUSE_FLAG " flag\n"); - exit(1); - } - if (cause_addr < 0 || cause_off < 0) { - fprintf(stderr, "Parameters to " CAUSE_FLAG " flag must be non-negative values\n"); - exit(1); - } - } + if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help")) { + fprintf(stderr, "Usage: %s %s.\n", argv[0], correct_cmdline); + exit (0); + } + else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "-version")) { + print_version_string("mstdump", ""); + exit(0); + } + else if (!strncmp(argv[i], CAUSE_FLAG, strlen(CAUSE_FLAG))) { + if (sscanf(argv[i], CAUSE_FLAG"=%i.%d", &cause_addr, &cause_off) != 2) { + fprintf(stderr, "Invalid parameters to " CAUSE_FLAG " flag\n"); + exit(1); + } + if (cause_addr < 0 || cause_off < 0) { + fprintf(stderr, "Parameters to " CAUSE_FLAG " flag must be non-negative values\n"); + exit(1); + } + } } - + i = 1; // i points to the current command line argument if (i < argc && !strcasecmp(argv[i], "-full")) { @@ -102,40 +99,40 @@ int main(int argc, char** argv) } ++i; // move past the device parameter - if (i < argc) - mset_i2c_slave(mf, (u_int8_t)strtoul(argv[i],0,0)); - + if (i < argc) { + mset_i2c_slave(mf, (u_int8_t)strtoul(argv[i], 0, 0)); + } - rc = CRD_OK; + rc = CRD_OK; crd_ctxt_t *context; rc = crd_init(&context, mf, full, cause_addr, cause_off); - if (rc){ - mclose(mf); - goto error; + if (rc) { + mclose(mf); + goto error; } //printf("Number of blocks : 0x%d\n",(context)->block_count); u_int32_t arr_size = 0; rc = crd_get_dword_num(context, &arr_size); - if (rc){ - crd_free(context); - mclose(mf); - goto error; + if (rc) { + crd_free(context); + mclose(mf); + goto error; } rc = crd_dump_data(context, NULL, print_dword); - if (rc){ - crd_free(context); - mclose(mf); - goto error; + if (rc) { + crd_free(context); + mclose(mf); + goto error; } crd_free(context); mclose(mf); return 0; - error : - printf("-E- %s\n", crd_err_str(rc)); - return rc; + error : + printf("-E- %s\n", crd_err_str(rc)); + return rc; } diff --git a/mstdump/mstdump_dbs/ConnectIB.csv b/mstdump/mstdump_dbs/ConnectIB.csv index f92fe73..050d90f 100755 --- a/mstdump/mstdump_dbs/ConnectIB.csv +++ b/mstdump/mstdump_dbs/ConnectIB.csv @@ -1,4 +1,4 @@ -# addr, size, enable addr +#Addr, Size, Enable addr 0x000000,16385, 0x010010,8, 0x010104,1, @@ -6,7 +6,8 @@ 0x010200,1, 0x010210,4, 0x010300,4, -0x010400,5, +0x010400,3, +0x010410,1, 0x010444,1, 0x01044c,4, 0x010480,2, @@ -72,25 +73,20 @@ 0x011e08,1, 0x011e10,1, 0x012000,32, -0x012100,2, 0x012200,32, -0x012300,2, 0x012400,32, -0x012500,2, 0x012600,32, -0x012700,2, 0x012800,20, 0x012888,22, 0x012900,18, 0x012a00,36, 0x012b00,3, 0x012b10,1, -0x012b18,3, -0x012b28,3, -0x012b38,3, -0x012b48,3, -0x012b58,3, -0x012b68,2, +0x012b20,1, +0x012b30,1, +0x012b40,1, +0x012b50,1, +0x012b60,1, 0x012c00,1, 0x012c08,1, 0x012c10,1, @@ -109,7 +105,8 @@ 0x012c88,1, 0x012d00,5, 0x012d20,2, -0x012e00,16, +0x012e00,6, +0x012e20,6, 0x012e80,5, 0x013000,4, 0x013084,1, @@ -144,18 +141,18 @@ 0x01524c,1, 0x015254,1, 0x01525c,2, -0x015268,3, -0x015278,3, -0x015288,3, -0x015298,3, -0x0152a8,3, -0x0152b8,3, -0x0152c8,3, -0x0152d8,3, -0x0152e8,3, -0x0152f8,3, -0x015308,3, -0x015318,3, +0x015270,1, +0x015280,1, +0x015290,1, +0x0152a0,1, +0x0152b0,1, +0x0152c0,1, +0x0152d0,1, +0x0152e0,1, +0x0152f0,1, +0x015300,1, +0x015310,1, +0x015320,1, 0x015330,1, 0x016800,3, 0x016820,8, @@ -166,15 +163,23 @@ 0x017934,1, 0x01794c,1, 0x017970,2, -0x017a00,8, -0x017c00,67, +0x017a00,6, +0x017c00,6, +0x017c20,6, +0x017c40,6, +0x017c60,6, +0x017c80,6, +0x017ca0,6, +0x017cc0,6, +0x017ce0,6, +0x017d00,3, 0x017d10,4, 0x018400,11, 0x018430,2, 0x018440,4, 0x018604,1, 0x018618,2, -0x018640,8, +0x018640,4, 0x018800,1, 0x018810,4, 0x018c04,1, @@ -228,7 +233,8 @@ 0x022504,1, 0x02250c,4, 0x022624,1, -0x02262c,5, +0x02262c,3, +0x02263c,1, 0x022804,1, 0x02280c,4, 0x022904,4, @@ -241,8 +247,7 @@ 0x024070,9, 0x0240a0,1, 0x0240b0,4, -0x024100,12, -0x024138,10, +0x024100,24, 0x024200,5, 0x024218,3, 0x0243a0,6, @@ -257,11 +262,10 @@ 0x024500,1, 0x02450c,7, 0x024530,1, -0x024538,2, 0x024544,4, -0x024558,3, -0x024568,3, -0x024578,6, +0x024560,1, +0x024570,1, +0x024580,4, 0x0245a4,2, 0x0245b4,3, 0x0245c4,2, @@ -278,8 +282,7 @@ 0x024780,32, 0x024824,4, 0x024864,6, -0x024888,5, -0x0248a0,2, +0x024888,10, 0x0248b4,3, 0x0248c4,1, 0x0248cc,1, @@ -287,7 +290,7 @@ 0x0248dc,7, 0x024908,6, 0x024928,6, -0x02496c,5, +0x024968,6, 0x024984,3, 0x024994,1, 0x02499c,6, @@ -315,7 +318,7 @@ 0x02a584,16, 0x02a604,16, 0x02a6fc,34, -0x02a788,6, +0x02a790,4, 0x02a7c4,1, 0x02a7d4,11, 0x02a900,1, @@ -327,7 +330,7 @@ 0x02abb4,1, 0x02abbc,1, 0x02abc4,1, -0x02abcc,10, +0x02abcc,9, 0x02ac00,2, 0x02ac10,3, 0x02ac44,3, @@ -368,7 +371,8 @@ 0x02c204,1, 0x02c214,3, 0x02c224,1, -0x02c22c,9, +0x02c22c,4, +0x02c244,2, 0x02c400,2, 0x02c418,2, 0x02c434,2, @@ -376,9 +380,28 @@ 0x02c534,2, 0x02c54c,1, 0x02c570,3, -0x02c600,16, +0x02c600,6, +0x02c620,6, 0x02c800,3, -0x02c820,152, +0x02c820,6, +0x02c840,6, +0x02c860,6, +0x02c880,6, +0x02c8a0,6, +0x02c8c0,6, +0x02c8e0,6, +0x02c900,6, +0x02c920,6, +0x02c940,6, +0x02c960,6, +0x02c980,6, +0x02c9a0,6, +0x02c9c0,6, +0x02c9e0,6, +0x02ca00,6, +0x02ca20,6, +0x02ca40,6, +0x02ca60,6, 0x02cc00,3, 0x02cc20,9, 0x02cc48,4, @@ -399,7 +422,7 @@ 0x03080c,4, 0x030c04,1, 0x030c0c,4, -0x030e00,3, +0x030e00,1, 0x031000,6, 0x031100,6, 0x031200,17, @@ -415,7 +438,7 @@ 0x034200,19, 0x034254,21, 0x0342ac,1, -0x0342c0,8, +0x0342c0,6, 0x0342f0,4, 0x034504,2, 0x034518,12, @@ -423,7 +446,7 @@ 0x034600,19, 0x034654,21, 0x0346ac,1, -0x0346c0,8, +0x0346c0,6, 0x0346f0,4, 0x034800,1, 0x034904,2, @@ -449,8 +472,7 @@ 0x035244,3, 0x035300,64, 0x037000,5, -0x03702c,4, -0x037040,2, +0x03702c,7, 0x037080,4, 0x037094,1, 0x037100,2, @@ -458,8 +480,7 @@ 0x037210,3, 0x037244,3, 0x037300,69, -0x03742c,4, -0x037440,2, +0x03742c,7, 0x037480,4, 0x037494,1, 0x037500,2, @@ -477,9 +498,12 @@ 0x038534,1, 0x03854c,1, 0x038570,2, -0x038600,8, +0x038600,6, 0x038800,3, -0x038820,32, +0x038820,6, +0x038840,6, +0x038860,6, +0x038880,6, 0x038900,20, 0x038958,1, 0x038980,3, @@ -543,7 +567,9 @@ 0x03f0c0,16, 0x03f200,1, 0x03f210,1, -0x03f300,19, +0x03f300,6, +0x03f320,6, +0x03f340,3, 0x03f360,8, 0x050000,1, 0x050008,2, @@ -583,8 +609,8 @@ 0x052330,5, 0x052350,4, 0x052364,4, -0x052378,35, -0x052408,4, +0x052380,33, +0x052410,2, 0x05241c,1, 0x052424,1, 0x05242c,23, @@ -602,11 +628,17 @@ 0x0526f4,1, 0x052710,14, 0x0527ec,1, -0x0527fc,30, -0x052878,4, -0x052898,1, +0x0527fc,40, 0x052c00,3, -0x052c20,72, +0x052c20,6, +0x052c40,6, +0x052c60,6, +0x052c80,6, +0x052ca0,6, +0x052cc0,6, +0x052ce0,6, +0x052d00,6, +0x052d20,6, 0x052e00,32, 0x052e84,1, 0x052e8c,1, @@ -615,26 +647,25 @@ 0x052ea4,1, 0x052eac,1, 0x052eb4,4, -0x052ec8,3, -0x052ed8,3, -0x052ee8,3, -0x052ef8,3, -0x052f08,3, -0x052f18,3, -0x052f28,3, -0x052f38,3, -0x052f48,3, -0x052f58,3, -0x052f68,3, -0x052f78,3, -0x052f88,3, -0x052f98,3, -0x052fa8,3, -0x052fb8,3, -0x052fc8,3, -0x052fd8,3, -0x052fe8,3, -0x052ff8,2, +0x052ed0,1, +0x052ee0,1, +0x052ef0,1, +0x052f00,1, +0x052f10,1, +0x052f20,1, +0x052f30,1, +0x052f40,1, +0x052f50,1, +0x052f60,1, +0x052f70,1, +0x052f80,1, +0x052f90,1, +0x052fa0,1, +0x052fb0,1, +0x052fc0,1, +0x052fd0,1, +0x052fe0,1, +0x052ff0,1, 0x054004,1, 0x05400c,4, 0x054200,1, @@ -649,13 +680,23 @@ 0x054680,24, 0x054700,4, 0x05477c,34, -0x054808,2, 0x055000,6, 0x055020,6, 0x055100,13, 0x055140,11, 0x055400,3, -0x055420,96, +0x055420,6, +0x055440,6, +0x055460,6, +0x055480,6, +0x0554a0,6, +0x0554c0,6, +0x0554e0,6, +0x055500,6, +0x055520,6, +0x055540,6, +0x055560,6, +0x055580,6, 0x056000,2, 0x056404,1, 0x05640c,4, @@ -673,11 +714,11 @@ 0x058820,6, 0x058844,2, 0x058850,9, -0x058880,3, -0x058890,3, -0x0588a0,3, -0x0588b0,3, -0x0588c0,3, +0x058880,1, +0x058890,1, +0x0588a0,1, +0x0588b0,1, +0x0588c0,1, 0x058904,3, 0x058978,66, 0x058a84,1, @@ -689,21 +730,20 @@ 0x05900c,4, 0x059080,39, 0x059120,1, -0x059128,3, -0x059138,3, -0x059148,3, -0x059158,2, -0x059800,3, -0x059810,3, -0x059820,3, -0x059830,3, -0x059840,3, -0x059850,3, -0x059860,3, -0x059870,3, -0x059880,3, -0x059890,3, -0x0598ac,8, +0x059130,1, +0x059140,1, +0x059150,1, +0x059800,1, +0x059810,1, +0x059820,1, +0x059830,1, +0x059840,1, +0x059850,1, +0x059860,1, +0x059870,1, +0x059880,1, +0x059890,1, +0x0598c4,2, 0x059900,3, 0x059940,3, 0x059960,40, @@ -714,17 +754,16 @@ 0x059d34,1, 0x059d4c,1, 0x059d70,2, -0x059e00,8, +0x059e00,6, 0x05a000,4, 0x05a020,2, 0x05a030,1, 0x05a040,1, 0x05a04c,2, 0x05a080,5, -0x05a098,3, -0x05a0a8,3, -0x05a0b8,3, -0x05a0c8,3, +0x05a0a0,1, +0x05a0b0,1, +0x05a0c0,1, 0x060004,11, 0x060120,4, 0x060144,2, @@ -738,8 +777,8 @@ 0x06020c,4, 0x060400,2, 0x060420,3, -0x060430,3, -0x060440,3, +0x060430,1, +0x060440,1, 0x060484,2, 0x0604b8,18, 0x060504,1, @@ -747,15 +786,16 @@ 0x060514,1, 0x060900,1, 0x060914,1, -0x06091c,4, -0x060930,3, +0x06091c,2, +0x060930,1, 0x060a00,32, 0x060a84,1, 0x060a8c,1, 0x060a94,1, 0x060a9c,1, 0x060bf0,3, -0x060c00,15, +0x060c00,11, +0x060c30,3, 0x061004,1, 0x061010,1, 0x061018,1, @@ -763,8 +803,7 @@ 0x061044,2, 0x061054,3, 0x061100,32, -0x061200,3, -0x061214,2, +0x061200,1, 0x061404,1, 0x06140c,4, 0x06180c,8, @@ -772,7 +811,7 @@ 0x061914,3, 0x061934,3, 0x061a00,4, -0x062000,7, +0x062008,5, 0x062024,3, 0x062034,1, 0x06203c,1, @@ -783,11 +822,11 @@ 0x06206c,1, 0x062080,2, 0x062094,1, -0x06209c,4, -0x0620b0,3, -0x0620c0,3, -0x0620d0,3, -0x0620e0,3, +0x06209c,2, +0x0620b0,1, +0x0620c0,1, +0x0620d0,1, +0x0620e0,1, 0x0620f4,4, 0x062404,1, 0x06240c,4, @@ -801,9 +840,9 @@ 0x062924,1, 0x06292c,1, 0x062934,1, -0x06293c,4, +0x06293c,2, 0x062950,2, -0x063000,3, +0x063000,1, 0x063010,4, 0x063024,1, 0x06302c,1, @@ -811,10 +850,10 @@ 0x063044,1, 0x06304c,1, 0x063054,1, -0x06305c,4, -0x063070,3, -0x063080,3, -0x063090,3, +0x06305c,2, +0x063070,1, +0x063080,1, +0x063090,1, 0x0630a4,3, 0x063100,2, 0x063144,1, @@ -838,11 +877,11 @@ 0x064338,2, 0x064380,2, 0x064394,1, -0x06439c,4, +0x06439c,2, 0x064400,2, 0x064420,3, -0x064430,3, -0x064440,3, +0x064430,1, +0x064440,1, 0x064484,2, 0x0644b8,18, 0x064504,1, @@ -856,7 +895,10 @@ 0x065060,8, 0x065104,5, 0x065200,3, -0x065220,32, +0x065220,6, +0x065240,6, +0x065260,6, +0x065280,6, 0x065f00,2, 0x066000,2, 0x066018,2, @@ -865,7 +907,8 @@ 0x066134,2, 0x06614c,1, 0x066170,3, -0x066200,16, +0x066200,6, +0x066220,6, 0x0662c0,1, 0x066400,8, 0x066500,14, @@ -946,7 +989,8 @@ 0x074860,8, 0x074884,2, 0x074890,4, -0x074900,16, +0x074900,6, +0x074920,6, 0x074a00,3, 0x074c00,1, 0x074c18,1, @@ -955,7 +999,7 @@ 0x074d34,1, 0x074d4c,1, 0x074d70,2, -0x074e00,8, +0x074e00,6, 0x075000,3, 0x075010,2, 0x075020,3, @@ -967,7 +1011,7 @@ 0x078098,4, 0x078100,5, 0x078118,4, -0x078130,3, +0x078130,2, 0x078204,2, 0x078244,15, 0x078284,2, @@ -977,7 +1021,6 @@ 0x078360,2, 0x078380,2, 0x0783a0,2, -0x0783c4,1, 0x0783d4,1, 0x0783dc,1, 0x078404,1, @@ -1013,9 +1056,12 @@ 0x079d10,2, 0x079d24,1, 0x079d2c,2, -0x079d60,1, -0x079d80,4, -0x079f00,32, +0x079d80,2, +0x079d8c,1, +0x079f00,6, +0x079f20,6, +0x079f40,6, +0x079f60,6, 0x079fa0,3, 0x079fb0,1, 0x079fc0,3, @@ -1147,15 +1193,39 @@ 0x086040,1, 0x086400,11, 0x086800,3, -0x086820,56, +0x086820,6, +0x086840,6, +0x086860,6, +0x086880,6, +0x0868a0,6, +0x0868c0,6, +0x0868e0,6, 0x086980,3, 0x0869a0,9, 0x0869c8,1, 0x0869d0,3, 0x087000,26, -0x087100,53, +0x087100,1, +0x087108,1, +0x087110,1, +0x087118,1, +0x087120,1, +0x087128,1, +0x087130,1, +0x087138,1, +0x087140,1, +0x087148,1, +0x087150,1, +0x087158,1, +0x087160,1, +0x087168,1, +0x087170,1, +0x087178,1, +0x087180,10, +0x0871b0,9, 0x090000,17, -0x090060,4, +0x090060,2, +0x09006c,1, 0x090104,1, 0x090110,12, 0x090180,9, @@ -1170,7 +1240,8 @@ 0x090400,6, 0x090420,9, 0x090448,1, -0x090500,10, +0x090500,6, +0x090520,2, 0x090540,1, 0x090564,2, 0x090578,3, @@ -1208,7 +1279,7 @@ 0x094934,1, 0x09494c,1, 0x094970,2, -0x094a00,8, +0x094a00,6, 0x096000,1, 0x096010,4, 0x096024,4, @@ -1230,7 +1301,8 @@ 0x096800,11, 0x096884,3, 0x0968a0,12, -0x097100,9, +0x097100,6, +0x097120,1, 0x0a0000,1, 0x0a0008,3, 0x0a0018,4, @@ -1241,8 +1313,7 @@ 0x0a0804,1, 0x0a080c,4, 0x0a0c00,2, -0x0a0c0c,1, -0x0a0c14,3, +0x0a0c0c,5, 0x0a0c40,1, 0x0a0c50,4, 0x0a0c64,1, @@ -1299,14 +1370,20 @@ 0x0a5134,2, 0x0a514c,1, 0x0a5170,3, -0x0a5200,16, +0x0a5200,6, +0x0a5220,6, 0x0a52c0,2, 0x0a6000,3, -0x0a6020,32, +0x0a6020,6, +0x0a6040,6, +0x0a6060,6, +0x0a6080,6, 0x0a7000,2, 0x0a7040,3, 0x0a7060,10, -0x0a8000,32, +0x0a8000,10, +0x0a802c,15, +0x0a806c,5, 0x0a8408,5, 0x0a8424,3, 0x0a8434,6, @@ -1317,26 +1394,25 @@ 0x0a84cc,4, 0x0a8604,1, 0x0a860c,4, -0x0a8700,18, +0x0a8700,17, 0x0a8750,4, 0x0a8800,4, 0x0a8880,1, 0x0a88a0,1, 0x0a88c0,1, 0x0a8900,1, -0x0a8920,1, -0x0a8940,1, 0x0a8960,1, 0x0a8980,4, 0x0a8994,1, 0x0a899c,1, 0x0a89a4,3, -0x0a89c0,2, +0x0a89c0,1, 0x0a8a00,3, 0x0a8aa4,1, 0x0a8aac,1, 0x0a8ab4,1, -0x0a8ad4,14, +0x0a8ad4,10, +0x0a8b00,2, 0x0a8b80,4, 0x0a8c04,6, 0x0a9000,3, @@ -1355,7 +1431,9 @@ 0x0a954c,13, 0x0a9804,1, 0x0a980c,4, -0x0a9c00,9, +0x0a9c00,2, +0x0a9c0c,3, +0x0a9c1c,2, 0x0a9c28,1, 0x0a9c44,1, 0x0a9c60,17, @@ -1372,7 +1450,11 @@ 0x0a9e84,1, 0x0a9e98,1, 0x0a9ea0,8, -0x0a9f00,35, +0x0a9f00,6, +0x0a9f20,6, +0x0a9f40,6, +0x0a9f60,6, +0x0a9f80,3, 0x0a9fa0,23, 0x0aa004,1, 0x0aa00c,4, @@ -1384,42 +1466,54 @@ 0x0b0900,2, 0x0b0910,2, 0x0b0920,2, -0x0b0960,4, +0x0b0960,2, +0x0b096c,1, 0x0b0980,3, 0x0b0990,3, 0x0b09a0,3, -0x0b09e0,4, +0x0b09e0,2, +0x0b09ec,1, 0x0b0a00,2, 0x0b0a10,2, -0x0b0a60,4, +0x0b0a60,2, +0x0b0a6c,1, 0x0b0a80,3, 0x0b0a90,3, -0x0b0ae0,4, +0x0b0ae0,2, +0x0b0aec,1, 0x0b0b00,2, 0x0b0b10,2, 0x0b0b20,2, -0x0b0b60,4, +0x0b0b60,2, +0x0b0b6c,1, 0x0b0b80,3, 0x0b0b90,3, -0x0b0be0,4, +0x0b0be0,2, +0x0b0bec,1, 0x0b0c00,3, 0x0b0c10,3, -0x0b0c60,4, +0x0b0c60,2, +0x0b0c6c,1, 0x0b0c80,3, 0x0b0c90,7, 0x0b0cb0,4, -0x0b0ce0,4, +0x0b0ce0,2, +0x0b0cec,1, 0x0b0d00,2, 0x0b0d10,2, -0x0b0d60,4, +0x0b0d60,2, +0x0b0d6c,1, 0x0b0d80,3, 0x0b0d90,3, -0x0b0de0,4, +0x0b0de0,2, +0x0b0dec,1, 0x0b0e00,3, 0x0b0e10,3, -0x0b0e60,4, +0x0b0e60,2, +0x0b0e6c,1, 0x0b0e80,8, -0x0b0ee0,4, +0x0b0ee0,2, +0x0b0eec,1, 0x0b0f00,3, 0x0b0f20,8, 0x0b1000,3, @@ -1477,9 +1571,16 @@ 0x0b4134,1, 0x0b414c,1, 0x0b4170,2, -0x0b4200,8, +0x0b4200,6, 0x0b4800,3, -0x0b4820,64, +0x0b4820,6, +0x0b4840,6, +0x0b4860,6, +0x0b4880,6, +0x0b48a0,6, +0x0b48c0,6, +0x0b48e0,6, +0x0b4900,6, 0x0c0000,4, 0x0c0058,2, 0x0c0064,1, @@ -1501,13 +1602,14 @@ 0x0c0ba0,28, 0x0c0c80,20, 0x0c0d00,3, -0x0c0d20,8, +0x0c0d20,6, 0x0c0d80,4, 0x0c0da0,1, -0x0c0da8,14, +0x0c0da8,12, 0x0c0e00,17, 0x0c0e80,4, -0x0c0ec0,16, +0x0c0ec0,6, +0x0c0ee0,6, 0x0c1000,32, 0x0c1084,5, 0x0c10f8,3, @@ -1551,7 +1653,9 @@ 0x0c1d84,1, 0x0c1d90,4, 0x0c1e00,3, -0x0c1e20,24, +0x0c1e20,6, +0x0c1e40,6, +0x0c1e60,6, 0x0c1f80,3, 0x0c1fa0,8, 0x0c2000,1, @@ -1561,18 +1665,21 @@ 0x0c2134,1, 0x0c214c,1, 0x0c2170,2, -0x0c2200,8, +0x0c2200,6, 0x0c2400,36, 0x0c24a0,8, 0x0c2500,1, 0x0c2584,7, 0x0c2604,1, 0x0c26f0,70, -0x0c8000,35, +0x0c8000,25, +0x0c8068,4, +0x0c807c,4, 0x0c80a0,3, 0x0c80b0,2, 0x0c80c8,6, -0x0c8180,16, +0x0c8180,6, +0x0c81a0,6, 0x0c9000,1, 0x0c9018,1, 0x0c9034,1, @@ -1580,65 +1687,127 @@ 0x0c9134,1, 0x0c914c,1, 0x0c9170,2, -0x0c9200,8, +0x0c9200,6, 0x0c9400,3, 0x0c9500,3, 0x0c9520,10, 0x0ca000,3, -0x0ca010,42, +0x0ca010,36, +0x0ca0a4,2, +0x0ca0b0,2, 0x0ca0c0,14, 0x0ca100,14, 0x0ca140,5, 0x0ca160,4, -0x0ca180,25, +0x0ca180,13, +0x0ca1b8,11, 0x0ca1e8,3, -0x0ca1f8,98, -0x0ca400,128, +0x0ca1f8,8, +0x0ca220,6, +0x0ca240,6, +0x0ca260,6, +0x0ca280,6, +0x0ca2a0,6, +0x0ca2c0,6, +0x0ca2e0,6, +0x0ca300,6, +0x0ca320,6, +0x0ca340,6, +0x0ca360,6, +0x0ca400,6, +0x0ca420,6, +0x0ca440,6, +0x0ca460,6, +0x0ca480,6, +0x0ca4a0,6, +0x0ca4c0,6, +0x0ca4e0,6, +0x0ca500,6, +0x0ca520,6, +0x0ca540,6, +0x0ca560,6, +0x0ca580,6, +0x0ca5a0,6, +0x0ca5c0,6, +0x0ca5e0,6, 0x0ca6fc,1, 0x0ca704,1, 0x0ca72c,17, 0x0ca780,16, -0x0ca800,14, -0x0ca840,14, -0x0ca880,14, -0x0ca8c0,14, -0x0ca900,14, -0x0ca940,14, -0x0ca980,14, -0x0ca9c0,14, -0x0caa00,14, -0x0caa40,14, -0x0caa80,14, -0x0caac0,14, -0x0cab00,14, -0x0cab40,14, -0x0cab80,14, -0x0cabc0,14, +0x0ca800,8, +0x0ca824,5, +0x0ca840,8, +0x0ca864,5, +0x0ca880,8, +0x0ca8a4,5, +0x0ca8c0,8, +0x0ca8e4,5, +0x0ca900,8, +0x0ca924,5, +0x0ca940,8, +0x0ca964,5, +0x0ca980,8, +0x0ca9a4,5, +0x0ca9c0,8, +0x0ca9e4,5, +0x0caa00,8, +0x0caa24,5, +0x0caa40,8, +0x0caa64,5, +0x0caa80,8, +0x0caaa4,5, +0x0caac0,8, +0x0caae4,5, +0x0cab00,8, +0x0cab24,5, +0x0cab40,8, +0x0cab64,5, +0x0cab80,8, +0x0caba4,5, +0x0cabc0,8, +0x0cabe4,5, 0x0cac04,6, 0x0cac20,2, 0x0cac30,2, 0x0cac40,2, 0x0cac50,2, 0x0cb000,16, -0x0cb044,3, +0x0cb044,1, +0x0cb04c,1, 0x0cb100,16, 0x0cb1f0,6, -0x0cb210,6, -0x0cb230,6, -0x0cb250,6, -0x0cb270,6, -0x0cb290,6, -0x0cb2b0,6, -0x0cb2d0,6, -0x0cb2f0,6, -0x0cb310,6, -0x0cb330,6, -0x0cb350,6, -0x0cb370,6, -0x0cb390,6, -0x0cb3b0,6, -0x0cb3d0,6, -0x0cb3f0,21, +0x0cb210,3, +0x0cb220,2, +0x0cb230,3, +0x0cb240,2, +0x0cb250,3, +0x0cb260,2, +0x0cb270,3, +0x0cb280,2, +0x0cb290,3, +0x0cb2a0,2, +0x0cb2b0,3, +0x0cb2c0,2, +0x0cb2d0,3, +0x0cb2e0,2, +0x0cb2f0,3, +0x0cb300,2, +0x0cb310,3, +0x0cb320,2, +0x0cb330,3, +0x0cb340,2, +0x0cb350,3, +0x0cb360,2, +0x0cb370,3, +0x0cb380,2, +0x0cb390,3, +0x0cb3a0,2, +0x0cb3b0,3, +0x0cb3c0,2, +0x0cb3d0,3, +0x0cb3e0,2, +0x0cb3f0,3, +0x0cb400,17, 0x0cb59c,25, 0x0cb700,11, 0x0cb74c,2, @@ -1695,88 +1864,114 @@ 0x0d002c,18, 0x0d1000,2, 0x0d100c,1, -0x0d1014,1, -0x0d1020,15, -0x0d1060,9, -0x0d10a0,8, +0x0d1020,13, +0x0d1058,1, +0x0d1060,6, +0x0d1080,1, +0x0d10a0,6, 0x0d1100,2, 0x0d110c,1, -0x0d1114,1, -0x0d1120,15, -0x0d1160,9, -0x0d11a0,8, +0x0d1120,13, +0x0d1158,1, +0x0d1160,6, +0x0d1180,1, +0x0d11a0,6, 0x0d1200,2, 0x0d120c,1, -0x0d1214,1, -0x0d1220,15, -0x0d1260,9, -0x0d12a0,8, +0x0d1220,13, +0x0d1258,1, +0x0d1260,6, +0x0d1280,1, +0x0d12a0,6, 0x0d1300,2, 0x0d130c,1, -0x0d1314,1, -0x0d1320,15, -0x0d1360,9, -0x0d13a0,8, -0x0d1400,16, +0x0d1320,13, +0x0d1358,1, +0x0d1360,6, +0x0d1380,1, +0x0d13a0,6, +0x0d1400,14, 0x0d1448,1, 0x0d1450,5, 0x0d1480,6, 0x0d1500,10, 0x0d152c,4, 0x0d1800,4, -0x0d1820,7, -0x0d1a00,25, -0x0d1c00,26, -0x0d1c80,11, +0x0d1820,3, +0x0d1830,3, +0x0d1a00,1, +0x0d1a08,13, +0x0d1a40,9, +0x0d1c00,24, +0x0d1c64,1, +0x0d1c80,6, +0x0d1ca0,3, 0x0d1cb0,2, 0x0d1d00,6, 0x0d1d40,12, 0x0d2000,2, 0x0d200c,1, -0x0d2014,1, -0x0d2020,15, -0x0d2060,9, -0x0d20a0,8, +0x0d2020,13, +0x0d2058,1, +0x0d2060,6, +0x0d2080,1, +0x0d20a0,6, 0x0d2100,2, 0x0d210c,1, -0x0d2114,1, -0x0d2120,15, -0x0d2160,9, -0x0d21a0,8, +0x0d2120,13, +0x0d2158,1, +0x0d2160,6, +0x0d2180,1, +0x0d21a0,6, 0x0d2200,2, 0x0d220c,1, -0x0d2214,1, -0x0d2220,15, -0x0d2260,9, -0x0d22a0,8, +0x0d2220,13, +0x0d2258,1, +0x0d2260,6, +0x0d2280,1, +0x0d22a0,6, 0x0d2300,2, 0x0d230c,1, -0x0d2314,1, -0x0d2320,15, -0x0d2360,9, -0x0d23a0,8, -0x0d2400,16, +0x0d2320,13, +0x0d2358,1, +0x0d2360,6, +0x0d2380,1, +0x0d23a0,6, +0x0d2400,14, 0x0d2448,1, 0x0d2450,5, 0x0d2480,6, 0x0d2500,10, 0x0d252c,4, 0x0d2800,4, -0x0d2820,7, -0x0d2a00,25, -0x0d2c00,26, -0x0d2c80,11, +0x0d2820,3, +0x0d2830,3, +0x0d2a00,1, +0x0d2a08,13, +0x0d2a40,9, +0x0d2c00,24, +0x0d2c64,1, +0x0d2c80,6, +0x0d2ca0,3, 0x0d2cb0,2, 0x0d2d00,6, 0x0d2d40,12, -0x0d3000,14, -0x0d3040,14, -0x0d3080,14, -0x0d30c0,14, -0x0d3100,14, -0x0d3140,14, -0x0d3180,14, -0x0d31c0,14, +0x0d3000,8, +0x0d3024,5, +0x0d3040,8, +0x0d3064,5, +0x0d3080,8, +0x0d30a4,5, +0x0d30c0,8, +0x0d30e4,5, +0x0d3100,8, +0x0d3124,5, +0x0d3140,8, +0x0d3164,5, +0x0d3180,8, +0x0d31a4,5, +0x0d31c0,8, +0x0d31e4,5, 0x0d3204,5, 0x0d3220,2, 0x0d3230,2, @@ -1788,7 +1983,7 @@ 0x0d3534,1, 0x0d354c,1, 0x0d3570,2, -0x0d3600,8, +0x0d3600,6, 0x0d3800,19, 0x0d3850,16, 0x0d389c,1, @@ -1819,9 +2014,12 @@ 0x0d3d04,1, 0x0d3d2c,17, 0x0d3d80,16, -0x0d3e00,19, +0x0d3e00,6, +0x0d3e20,6, +0x0d3e40,3, 0x0d3e50,1, -0x0d8000,11, +0x0d8000,6, +0x0d8020,3, 0x0d8030,3, 0x0d8040,6, 0x0d8060,4, @@ -1833,40 +2031,59 @@ 0x0d8534,2, 0x0d854c,1, 0x0d8570,2, -0x0d8600,16, +0x0d8600,6, +0x0d8620,6, 0x0d8800,1, -0x0d8820,24, +0x0d8820,13, +0x0d8858,8, 0x0d8900,12, 0x0d8984,1, 0x0d89bc,18, -0x0d8a20,24, +0x0d8a20,13, +0x0d8a58,8, 0x0d8b00,12, 0x0d8b84,1, 0x0d8bbc,17, -0x0d9000,16, +0x0d9000,6, +0x0d9020,6, 0x0d9048,3, -0x0d9080,11, +0x0d9080,6, +0x0d909c,1, +0x0d90a4,2, 0x0d90b8,3, -0x0d9200,24, -0x0d9280,27, +0x0d9200,12, +0x0d9234,11, +0x0d9280,26, 0x0d9300,2, 0x0d9320,1, 0x0d9404,4, -0x0d9418,21, -0x0d9600,27, -0x0d9680,11, -0x0d9800,16, +0x0d9418,16, +0x0d9460,3, +0x0d9600,5, +0x0d9618,1, +0x0d9644,9, +0x0d9680,6, +0x0d96a0,2, +0x0d9800,6, +0x0d9820,6, 0x0d9848,3, -0x0d9880,11, +0x0d9880,6, +0x0d989c,1, +0x0d98a4,2, 0x0d98b8,3, -0x0d9a00,24, -0x0d9a80,27, +0x0d9a00,12, +0x0d9a34,11, +0x0d9a80,26, 0x0d9b00,2, 0x0d9b20,1, 0x0d9c04,4, -0x0d9c18,21, -0x0d9e00,27, -0x0d9e80,11, +0x0d9c18,16, +0x0d9c60,3, +0x0d9e00,5, +0x0d9e18,1, +0x0d9e44,9, +0x0d9e80,6, +0x0d9ea0,2, 0x0db000,4, 0x0db018,18, 0x0db100,4, @@ -1876,89 +2093,114 @@ 0x0db320,5, 0x0db340,6, 0x0db360,5, -0x0db380,7, +0x0db380,6, 0x0db400,3, 0x0db420,8, -0x0db500,11, +0x0db500,10, 0x0db544,2, 0x0db55c,9, 0x0db584,7, 0x0db5a4,2, 0x0db5b8,3, 0x0db600,2, -0x0dbfc4,381, +0x0dbfc4,13, +0x0dc000,366, 0x0dc800,366, -0x0e0000,4, +0x0e0000,3, 0x0e001c,2, 0x0e0030,1, 0x0e0048,2, 0x0e0058,2, -0x0e0068,31, +0x0e0068,11, +0x0e009c,2, +0x0e00ac,14, 0x0e0180,2, -0x0e01e0,5, +0x0e01e0,1, +0x0e01e8,3, 0x0e01f8,1, -0x0e0200,4, +0x0e0200,3, 0x0e021c,2, 0x0e0230,1, 0x0e0248,2, 0x0e0258,2, -0x0e0268,31, +0x0e0268,11, +0x0e029c,2, +0x0e02ac,14, 0x0e0380,2, -0x0e03e0,5, +0x0e03e0,1, +0x0e03e8,3, 0x0e03f8,1, -0x0e0400,4, +0x0e0400,3, 0x0e041c,2, 0x0e0430,1, 0x0e0448,2, 0x0e0458,2, -0x0e0468,31, +0x0e0468,11, +0x0e049c,2, +0x0e04ac,14, 0x0e0580,2, -0x0e05e0,5, +0x0e05e0,1, +0x0e05e8,3, 0x0e05f8,1, -0x0e0600,4, +0x0e0600,3, 0x0e061c,2, 0x0e0630,1, 0x0e0648,2, 0x0e0658,2, -0x0e0668,31, +0x0e0668,11, +0x0e069c,2, +0x0e06ac,14, 0x0e0780,2, -0x0e07e0,5, +0x0e07e0,1, +0x0e07e8,3, 0x0e07f8,1, -0x0e0800,4, +0x0e0800,3, 0x0e081c,2, 0x0e0830,1, 0x0e0848,2, 0x0e0858,2, -0x0e0868,31, +0x0e0868,11, +0x0e089c,2, +0x0e08ac,14, 0x0e0980,2, -0x0e09e0,5, +0x0e09e0,1, +0x0e09e8,3, 0x0e09f8,1, -0x0e0a00,4, +0x0e0a00,3, 0x0e0a1c,2, 0x0e0a30,1, 0x0e0a48,2, 0x0e0a58,2, -0x0e0a68,31, +0x0e0a68,11, +0x0e0a9c,2, +0x0e0aac,14, 0x0e0b80,2, -0x0e0be0,5, +0x0e0be0,1, +0x0e0be8,3, 0x0e0bf8,1, -0x0e0c00,4, +0x0e0c00,3, 0x0e0c1c,2, 0x0e0c30,1, 0x0e0c48,2, 0x0e0c58,2, -0x0e0c68,31, +0x0e0c68,11, +0x0e0c9c,2, +0x0e0cac,14, 0x0e0d80,2, -0x0e0de0,5, +0x0e0de0,1, +0x0e0de8,3, 0x0e0df8,1, -0x0e0e00,4, +0x0e0e00,3, 0x0e0e1c,2, 0x0e0e30,1, 0x0e0e48,2, 0x0e0e58,2, -0x0e0e68,31, +0x0e0e68,11, +0x0e0e9c,2, +0x0e0eac,14, 0x0e0f80,2, -0x0e0fe0,5, +0x0e0fe0,1, +0x0e0fe8,3, 0x0e0ff8,1, 0x0e1400,8, 0x0e1450,3, @@ -1980,28 +2222,33 @@ 0x0e2134,1, 0x0e214c,1, 0x0e2170,2, -0x0e2200,8, +0x0e2200,6, 0x0e2420,2, -0x0e2430,31, -0x0e2500,6, +0x0e2430,10, +0x0e2460,6, +0x0e2480,6, +0x0e24a0,3, +0x0e2504,4, 0x0e2600,16, 0x0e2644,5, 0x0e2660,6, 0x0e2804,8, 0x0e2828,5, -0x0e2844,9, +0x0e2844,3, +0x0e2854,5, 0x0e2880,4, -0x0e28a0,8, +0x0e28a0,6, 0x0e2a04,3, 0x0e2b00,33, -0x0e2c00,19, +0x0e2c40,3, 0x0e2c60,11, 0x0e8000,9, 0x0e8050,1, 0x0e8064,6, 0x0e8080,1, 0x0e8088,2, -0x0f0000,13, +0x0f0000,3, +0x0f0014,8, 0x0f0040,3, 0x0f0050,4, 0x0f0080,12, @@ -2016,10 +2263,14 @@ 0x0f0200,61, 0x0f0404,8, 0x0f0440,4, -0x0f0460,5, -0x0f0480,16, -0x0f04e0,24, -0x0f0560,8, +0x0f0460,1, +0x0f0468,3, +0x0f0480,6, +0x0f04a0,8, +0x0f04e0,6, +0x0f0500,6, +0x0f0520,8, +0x0f0560,6, 0x0f05dc,73, 0x0f0704,1, 0x0f0714,10, @@ -2029,7 +2280,9 @@ 0x0f089c,5, 0x0f08bc,5, 0x0f08dc,1, -0x0f0900,24, +0x0f0900,6, +0x0f0920,6, +0x0f0940,6, 0x0f0980,3, 0x0f0990,1, 0x0f0ffc,1, diff --git a/mstdump/mstdump_dbs/ConnectX2.csv b/mstdump/mstdump_dbs/ConnectX2.csv index b453675..01d9838 100755 --- a/mstdump/mstdump_dbs/ConnectX2.csv +++ b/mstdump/mstdump_dbs/ConnectX2.csv @@ -1,30 +1,30 @@ -# addr, size, enable addr +#Addr, Size, Enable addr 0x010000,2, 0x0100a0,15, 0x0100ec,2, -0x0100fc,3, +0x0100fc,2, 0x01010c,2, 0x010150,1, 0x0101cc,1, 0x0101fc,1, 0x010208,10, -0x010300,7, +0x010300,6, 0x010320,20, 0x010374,3, -0x010400,3, +0x010400,1, 0x010410,2, -0x010440,3, +0x010440,1, 0x010450,2, 0x010480,1, 0x010488,2, 0x0104a0,1, 0x0104a8,14, -0x0104f4,6, +0x0104f4,4, 0x010510,2, -0x010520,14, +0x010520,13, 0x0105c0,15, 0x010600,29, -0x010680,3, +0x010680,1, 0x010690,2, 0x0106ac,1, 0x0106b8,1, @@ -35,29 +35,29 @@ 0x010800,2, 0x0108a0,15, 0x0108ec,2, -0x0108fc,3, +0x0108fc,2, 0x01090c,2, 0x010950,1, 0x0109cc,1, 0x0109fc,1, 0x010a08,10, -0x010b00,7, +0x010b00,6, 0x010b20,20, 0x010b74,3, -0x010c00,3, +0x010c00,1, 0x010c10,2, -0x010c40,3, +0x010c40,1, 0x010c50,2, 0x010c80,1, 0x010c88,2, 0x010ca0,1, 0x010ca8,14, -0x010cf4,6, +0x010cf4,4, 0x010d10,2, -0x010d20,14, +0x010d20,13, 0x010dc0,15, 0x010e00,29, -0x010e80,3, +0x010e80,1, 0x010e90,2, 0x010eac,1, 0x010eb8,1, @@ -76,7 +76,7 @@ 0x011240,4, 0x011260,1, 0x011280,5, -0x011300,3, +0x011300,1, 0x011310,2, 0x011400,1, 0x011408,1, @@ -93,16 +93,16 @@ 0x011a40,4, 0x011a60,1, 0x011a80,5, -0x011b00,3, +0x011b00,1, 0x011b10,2, 0x011c00,1, 0x011c08,1, 0x011c60,1, 0x011cb0,4, 0x012000,2, -0x012020,3, +0x012020,1, 0x012030,2, -0x012040,3, +0x012044,2, 0x0120a0,4, 0x0120c0,7, 0x01211c,13, @@ -133,38 +133,44 @@ 0x01275c,1, 0x0127d8,2, 0x0127e8,2, -0x012840,3, +0x012840,1, 0x012850,2, 0x0128a0,5, 0x0128c0,2, 0x012904,1, 0x012910,5, 0x012928,4, -0x012944,9, -0x0129a0,3, +0x012944,4, +0x012958,4, +0x0129a0,1, 0x0129b0,2, 0x012a00,2, 0x012a14,2, 0x012a28,3, -0x012a40,3, +0x012a40,1, 0x012a50,2, -0x012a60,3, +0x012a60,1, 0x012a70,2, 0x012ae4,4, -0x012b00,11, +0x012b00,9, 0x012b30,2, -0x012b40,7, -0x012b80,11, +0x012b40,2, +0x012b4c,4, +0x012b80,9, 0x012bb0,2, -0x012bc0,7, -0x012c00,38, -0x012ca0,6, -0x012cc0,6, -0x012ce0,6, +0x012bc0,2, +0x012bcc,4, +0x012c00,37, +0x012ca0,5, +0x012cc0,5, +0x012ce0,5, 0x012d00,2, 0x012d48,4, -0x012e00,44, -0x012ec0,12, +0x012e00,32, +0x012e84,7, +0x012ea8,2, +0x012ec4,7, +0x012ee8,2, 0x018000,1, 0x01805c,4, 0x018080,8, @@ -205,26 +211,26 @@ 0x0188d4,2, 0x0188e0,8, 0x018a04,3, -0x018a1c,4, +0x018a20,3, 0x018a30,4, 0x018a44,21, 0x018b04,3, 0x018b14,11, 0x018b4c,5, 0x018b68,5, -0x018c00,18, -0x018c50,30, +0x018c00,17, +0x018c50,29, 0x018cd0,14, 0x018d0c,2, -0x018e00,3, +0x018e00,1, 0x018e10,2, 0x018e50,2, 0x018f00,2, 0x018f14,2, 0x018f28,3, -0x018f40,3, +0x018f40,1, 0x018f50,2, -0x018f60,3, +0x018f60,1, 0x018f70,2, 0x018fe4,5, 0x019ff0,2052, @@ -232,9 +238,9 @@ 0x01c010,1, 0x01c01c,2, 0x01c06c,27, -0x01c180,3, +0x01c180,1, 0x01c190,2, -0x01c1a0,3, +0x01c1a0,1, 0x01c1b0,2, 0x01c1c0,7, 0x01c1e0,7, @@ -247,14 +253,12 @@ 0x01c434,1, 0x01c448,2, 0x01c454,1, -0x01c45c,1, -0x01c464,19, -0x01c4c0,1, +0x01c464,24, 0x01c4d8,2, 0x01c4e4,8, 0x01c514,1, 0x01c528,2, -0x01c540,3, +0x01c540,1, 0x01c550,2, 0x01c5e4,5, 0x01c608,4, @@ -271,43 +275,53 @@ 0x01c75c,1, 0x01c7dc,1, 0x01c7e4,1, -0x01c7f8,15, +0x01c7f8,7, +0x01c818,7, 0x01c840,19, 0x01c8a0,5, 0x01c8c0,1, -0x01c900,13, +0x01c900,5, +0x01c918,7, 0x01c940,19, 0x01c9a0,5, 0x01c9c0,1, -0x01ca00,13, +0x01ca00,5, +0x01ca18,7, 0x01ca40,19, 0x01caa0,5, 0x01cac0,1, -0x01cb00,13, +0x01cb00,5, +0x01cb18,7, 0x01cb40,19, 0x01cba0,5, 0x01cbc0,1, -0x01cc00,13, +0x01cc00,5, +0x01cc18,7, 0x01cc40,19, 0x01cca0,5, 0x01ccc0,1, -0x01cd00,13, +0x01cd00,5, +0x01cd18,7, 0x01cd40,19, 0x01cda0,5, 0x01cdc0,1, -0x01ce00,13, +0x01ce00,5, +0x01ce18,7, 0x01ce40,19, 0x01cea0,5, 0x01cec0,1, -0x01cf00,13, +0x01cf00,5, +0x01cf18,7, 0x01cf40,19, 0x01cfa0,5, 0x01cfc0,1, 0x01d000,19, -0x01d050,31, +0x01d050,22, +0x01d0ac,6, 0x01d0d0,2, 0x01d0e8,15, -0x01d140,55, +0x01d140,1, +0x01d148,53, 0x01d220,10, 0x01d260,5, 0x01d278,2, @@ -321,10 +335,12 @@ 0x01d3c0,5, 0x01d3e0,6, 0x01d400,19, -0x01d450,31, +0x01d450,22, +0x01d4ac,6, 0x01d4d0,2, 0x01d4e8,15, -0x01d540,55, +0x01d540,1, +0x01d548,53, 0x01d620,10, 0x01d660,5, 0x01d678,2, @@ -337,7 +353,8 @@ 0x01d77c,6, 0x01d7c0,5, 0x01d7e0,6, -0x01d800,19, +0x01d800,16, +0x01d844,1, 0x01d880,8, 0x01d8c4,1, 0x01d8cc,5, @@ -345,53 +362,61 @@ 0x01d920,1, 0x01d968,2, 0x01d9e0,6, -0x01da00,7, -0x01db0c,16, +0x01da00,4, +0x01da14,2, +0x01db0c,14, 0x01db50,2, -0x01db60,3, +0x01db60,1, 0x01db70,2, -0x01db80,3, +0x01db80,1, 0x01db90,2, 0x01dba0,3, -0x01dc00,5, +0x01dc00,1, +0x01dc0c,1, 0x01dd80,13, 0x01ddbc,1, 0x01dde0,9, 0x01df00,1, 0x01df14,1, 0x01df28,2, -0x01df40,3, +0x01df40,1, 0x01df50,2, 0x01dfe4,4, -0x01e5c0,3, +0x01e5c0,1, 0x01e5dc,1, 0x01e5e4,14, 0x01e620,4, -0x01e640,16, +0x01e668,6, 0x01e780,160, -0x01ea04,13, +0x01ea04,12, 0x01ec00,8, 0x01ec24,1, 0x01ec30,1, -0x01ec44,40, +0x01ec44,20, +0x01ec9c,2, +0x01ecac,14, 0x01ed80,1, 0x01edc4,1, -0x01ede0,5, +0x01ede0,1, +0x01ede8,3, 0x01edf8,1, 0x01ee00,8, 0x01ee24,1, 0x01ee30,1, -0x01ee44,40, +0x01ee44,20, +0x01ee9c,2, +0x01eeac,14, 0x01ef80,1, 0x01efc4,1, -0x01efe0,5, +0x01efe0,1, +0x01efe8,3, 0x01eff8,1, 0x01f000,1024, -0x030000,3, +0x030000,1, 0x030010,2, -0x030020,3, +0x030020,1, 0x030030,2, -0x030040,3, +0x030040,1, 0x030050,2, 0x030100,27, 0x030180,3, @@ -399,22 +424,21 @@ 0x030400,288, 0x030900,32, 0x030a04,1, -0x030b00,33, 0x030c00,128, 0x030e1c,1, 0x030e3c,1, 0x030e44,1, -0x030e5c,17, +0x030e5c,16, 0x030f10,28, 0x031000,14, 0x031040,14, 0x031080,14, 0x0310c0,14, -0x031100,147, -0x034000,3, +0x031100,133, +0x031318,13, +0x034000,1, 0x034010,2, 0x034224,1, -0x03422c,1, 0x034260,7, 0x034284,4, 0x034304,1, @@ -428,7 +452,7 @@ 0x034608,6, 0x034800,7, 0x034820,4, -0x034840,16, +0x034868,6, 0x034980,45, 0x034a40,13, 0x034a80,13, @@ -453,26 +477,29 @@ 0x035380,12, 0x0353c0,12, 0x036000,128, -0x036204,13, +0x036204,12, 0x036400,8, 0x036424,1, 0x036430,1, -0x036444,40, +0x036444,20, +0x03649c,2, +0x0364ac,14, 0x036580,1, 0x0365c4,1, -0x0365e0,5, +0x0365e0,1, +0x0365e8,3, 0x0365f8,1, 0x036600,2, 0x036614,2, 0x036628,3, -0x036640,3, +0x036640,1, 0x036650,2, -0x036660,3, +0x036660,1, 0x036670,2, 0x0366e4,5, -0x036700,3, +0x036700,1, 0x036710,2, -0x036720,3, +0x036720,1, 0x036730,2, 0x040000,19, 0x040050,3, @@ -544,33 +571,39 @@ 0x0411e4,15, 0x041224,1, 0x041230,1, -0x041244,40, +0x041244,20, +0x04129c,2, +0x0412ac,14, 0x041380,1, 0x0413c4,1, -0x0413e0,5, +0x0413e0,1, +0x0413e8,3, 0x0413f8,1, 0x041400,8, 0x041424,1, 0x041430,1, -0x041444,40, +0x041444,20, +0x04149c,2, +0x0414ac,14, 0x041580,1, 0x0415c4,1, -0x0415e0,5, +0x0415e0,1, +0x0415e8,3, 0x0415f8,1, 0x041600,2, 0x041614,2, 0x041628,3, -0x041640,3, +0x041640,1, 0x041650,2, -0x041660,3, +0x041660,1, 0x041670,2, -0x0416e4,5, -0x041a00,3, +0x0416e4,6, +0x041a00,1, 0x041a10,2, -0x041a20,3, +0x041a20,1, 0x041a30,2, 0x041c00,128, -0x041e04,13, +0x041e04,12, 0x042000,5, 0x042020,5, 0x042040,5, @@ -831,28 +864,9 @@ 0x044200,8, 0x044230,9, 0x044260,5, -0x044280,2, -0x044290,28, -0x044fc8,12, -0x045010,12, -0x045058,12, -0x0450a0,12, -0x0450e8,12, -0x045130,4, -0x045148,4, -0x045160,4, -0x045178,4, -0x045190,4, -0x0451a8,8, -0x0451d8,8, -0x045208,8, -0x045238,8, -0x045268,4, -0x045280,4, -0x045298,4, -0x0452b0,4, -0x0452c8,4, -0x0452e0,4, +0x044280,32, +0x044fc8,112, +0x045190,88, 0x045300,39, 0x045400,13, 0x045440,9, @@ -860,628 +874,643 @@ 0x047ff0,2, 0x048000,5, 0x048020,5, +0x048040,5, 0x048060,5, +0x048080,5, 0x0480a0,5, +0x0480c0,5, 0x0480e0,5, +0x048100,5, 0x048120,5, +0x048140,5, 0x048160,5, +0x048180,5, 0x0481a0,5, +0x0481c0,5, 0x0481e0,5, +0x048200,5, 0x048220,5, +0x048240,5, 0x048260,5, +0x048280,5, 0x0482a0,5, +0x0482c0,5, 0x0482e0,5, +0x048300,5, 0x048320,5, +0x048340,5, 0x048360,5, +0x048380,5, 0x0483a0,5, +0x0483c0,5, 0x0483e0,5, -#0x048400,5, +0x048400,5, 0x048420,5, -#0x048440,5, +0x048440,5, 0x048460,5, -#0x048480,5, +0x048480,5, 0x0484a0,5, -#0x0484c0,5, +0x0484c0,5, 0x0484e0,5, -#0x048500,5, +0x048500,5, 0x048520,5, -#0x048540,5, +0x048540,5, 0x048560,5, -#0x048580,5, +0x048580,5, 0x0485a0,5, -#0x0485c0,5, +0x0485c0,5, 0x0485e0,5, -#0x048600,5, +0x048600,5, 0x048620,5, -#0x048640,5, +0x048640,5, 0x048660,5, -#0x048680,5, +0x048680,5, 0x0486a0,5, -#0x0486c0,5, +0x0486c0,5, 0x0486e0,5, -#0x048700,5, +0x048700,5, 0x048720,5, -#0x048740,5, +0x048740,5, 0x048760,5, -#0x048780,5, +0x048780,5, 0x0487a0,5, -#0x0487c0,5, +0x0487c0,5, 0x0487e0,5, -#0x048800,5, +0x048800,5, 0x048820,5, -#0x048840,5, +0x048840,5, 0x048860,5, -#0x048880,5, +0x048880,5, 0x0488a0,5, -#0x0488c0,5, +0x0488c0,5, 0x0488e0,5, -#0x048900,5, +0x048900,5, 0x048920,5, -#0x048940,5, +0x048940,5, 0x048960,5, -#0x048980,5, +0x048980,5, 0x0489a0,5, -#0x0489c0,5, +0x0489c0,5, 0x0489e0,5, -#0x048a00,5, +0x048a00,5, 0x048a20,5, -#0x048a40,5, +0x048a40,5, 0x048a60,5, -#0x048a80,5, +0x048a80,5, 0x048aa0,5, -#0x048ac0,5, +0x048ac0,5, 0x048ae0,5, -#0x048b00,5, +0x048b00,5, 0x048b20,5, -#0x048b40,5, +0x048b40,5, 0x048b60,5, -#0x048b80,5, +0x048b80,5, 0x048ba0,5, -#0x048bc0,5, +0x048bc0,5, 0x048be0,5, -#0x048c00,5, +0x048c00,5, 0x048c20,5, -#0x048c40,5, +0x048c40,5, 0x048c60,5, -#0x048c80,5, +0x048c80,5, 0x048ca0,5, -#0x048cc0,5, +0x048cc0,5, 0x048ce0,5, -#0x048d00,5, +0x048d00,5, 0x048d20,5, -#0x048d40,5, +0x048d40,5, 0x048d60,5, -#0x048d80,5, +0x048d80,5, 0x048da0,5, -#0x048dc0,5, +0x048dc0,5, 0x048de0,5, -#0x048e00,5, +0x048e00,5, 0x048e20,5, -#0x048e40,5, +0x048e40,5, 0x048e60,5, -#0x048e80,5, +0x048e80,5, 0x048ea0,5, -#0x048ec0,5, +0x048ec0,5, 0x048ee0,5, -#0x048f00,5, +0x048f00,5, 0x048f20,5, -#0x048f40,5, +0x048f40,5, 0x048f60,5, -#0x048f80,5, +0x048f80,5, 0x048fa0,5, -#0x048fc0,5, +0x048fc0,5, 0x048fe0,5, -#0x049000,5, +0x049000,5, 0x049020,5, -#0x049040,5, +0x049040,5, 0x049060,5, -#0x049080,5, +0x049080,5, 0x0490a0,5, -#0x0490c0,5, +0x0490c0,5, 0x0490e0,5, -#0x049100,5, +0x049100,5, 0x049120,5, -#0x049140,5, +0x049140,5, 0x049160,5, -#0x049180,5, +0x049180,5, 0x0491a0,5, -#0x0491c0,5, +0x0491c0,5, 0x0491e0,5, -#0x049200,5, +0x049200,5, 0x049220,5, -#0x049240,5, +0x049240,5, 0x049260,5, -#0x049280,5, +0x049280,5, 0x0492a0,5, -#0x0492c0,5, +0x0492c0,5, 0x0492e0,5, -#0x049300,5, +0x049300,5, 0x049320,5, -#0x049340,5, +0x049340,5, 0x049360,5, -#0x049380,5, +0x049380,5, 0x0493a0,5, -#0x0493c0,5, +0x0493c0,5, 0x0493e0,5, -#0x049400,5, +0x049400,5, 0x049420,5, -#0x049440,5, +0x049440,5, 0x049460,5, -#0x049480,5, +0x049480,5, 0x0494a0,5, -#0x0494c0,5, +0x0494c0,5, 0x0494e0,5, -#0x049500,5, +0x049500,5, 0x049520,5, -#0x049540,5, +0x049540,5, 0x049560,5, -#0x049580,5, +0x049580,5, 0x0495a0,5, -#0x0495c0,5, +0x0495c0,5, 0x0495e0,5, -#0x049600,5, +0x049600,5, 0x049620,5, -#0x049640,5, +0x049640,5, 0x049660,5, -#0x049680,5, +0x049680,5, 0x0496a0,5, -#0x0496c0,5, +0x0496c0,5, 0x0496e0,5, -#0x049700,5, +0x049700,5, 0x049720,5, -#0x049740,5, +0x049740,5, 0x049760,5, -#0x049780,5, +0x049780,5, 0x0497a0,5, -#0x0497c0,5, +0x0497c0,5, 0x0497e0,5, -#0x049800,5, +0x049800,5, 0x049820,5, -#0x049840,5, +0x049840,5, 0x049860,5, -#0x049880,5, +0x049880,5, 0x0498a0,5, -#0x0498c0,5, +0x0498c0,5, 0x0498e0,5, -#0x049900,5, +0x049900,5, 0x049920,5, -#0x049940,5, +0x049940,5, 0x049960,5, -#0x049980,5, +0x049980,5, 0x0499a0,5, -#0x0499c0,5, +0x0499c0,5, 0x0499e0,5, -#0x049a00,5, +0x049a00,5, 0x049a20,5, -#0x049a40,5, +0x049a40,5, 0x049a60,5, -#0x049a80,5, +0x049a80,5, 0x049aa0,5, -#0x049ac0,5, +0x049ac0,5, 0x049ae0,5, -#0x049b00,5, +0x049b00,5, 0x049b20,5, -#0x049b40,5, +0x049b40,5, 0x049b60,5, -#0x049b80,5, +0x049b80,5, 0x049ba0,5, -#0x049bc0,5, +0x049bc0,5, 0x049be0,5, -#0x049c00,5, +0x049c00,5, 0x049c20,5, -#0x049c40,5, +0x049c40,5, 0x049c60,5, -#0x049c80,5, +0x049c80,5, 0x049ca0,5, -#0x049cc0,5, +0x049cc0,5, 0x049ce0,5, -#0x049d00,5, +0x049d00,5, 0x049d20,5, -#0x049d40,5, +0x049d40,5, 0x049d60,5, -#0x049d80,5, +0x049d80,5, 0x049da0,5, -#0x049dc0,5, +0x049dc0,5, 0x049de0,5, -#0x049e00,5, +0x049e00,5, 0x049e20,5, -#0x049e40,5, +0x049e40,5, 0x049e60,5, -#0x049e80,5, +0x049e80,5, 0x049ea0,5, -#0x049ec0,5, +0x049ec0,5, 0x049ee0,5, -#0x049f00,5, +0x049f00,5, 0x049f20,5, -#0x049f40,5, +0x049f40,5, 0x049f60,5, -#0x049f80,5, +0x049f80,5, 0x049fa0,5, -#0x049fc0,5, +0x049fc0,5, 0x049fe0,5, -#0x04a000,5, +0x04a000,5, 0x04a020,5, -#0x04a040,5, +0x04a040,5, 0x04a060,5, -#0x04a080,5, +0x04a080,5, 0x04a0a0,5, -#0x04a0c0,5, +0x04a0c0,5, 0x04a0e0,5, -#0x04a100,5, +0x04a100,5, 0x04a120,5, -#0x04a140,5, +0x04a140,5, 0x04a160,5, -#0x04a180,5, +0x04a180,5, 0x04a1a0,5, -#0x04a1c0,5, +0x04a1c0,5, 0x04a1e0,5, -#0x04a200,5, +0x04a200,5, 0x04a220,5, -#0x04a240,5, +0x04a240,5, 0x04a260,5, -#0x04a280,5, +0x04a280,5, 0x04a2a0,5, -#0x04a2c0,5, +0x04a2c0,5, 0x04a2e0,5, -#0x04a300,5, +0x04a300,5, 0x04a320,5, -#0x04a340,5, +0x04a340,5, 0x04a360,5, -#0x04a380,5, +0x04a380,5, 0x04a3a0,5, -#0x04a3c0,5, +0x04a3c0,5, 0x04a3e0,5, -#0x04a400,5, +0x04a400,5, 0x04a420,5, -#0x04a440,5, +0x04a440,5, 0x04a460,5, -#0x04a480,5, +0x04a480,5, 0x04a4a0,5, -#0x04a4c0,5, +0x04a4c0,5, 0x04a4e0,5, -#0x04a500,5, +0x04a500,5, 0x04a520,5, -#0x04a540,5, +0x04a540,5, 0x04a560,5, -#0x04a580,5, +0x04a580,5, 0x04a5a0,5, -#0x04a5c0,5, +0x04a5c0,5, 0x04a5e0,5, -#0x04a600,5, +0x04a600,5, 0x04a620,5, -#0x04a640,5, +0x04a640,5, 0x04a660,5, -#0x04a680,5, +0x04a680,5, 0x04a6a0,5, -#0x04a6c0,5, +0x04a6c0,5, 0x04a6e0,5, -#0x04a700,5, +0x04a700,5, 0x04a720,5, -#0x04a740,5, +0x04a740,5, 0x04a760,5, -#0x04a780,5, +0x04a780,5, 0x04a7a0,5, -#0x04a7c0,5, +0x04a7c0,5, 0x04a7e0,5, -#0x04a800,5, +0x04a800,5, 0x04a820,5, -#0x04a840,5, +0x04a840,5, 0x04a860,5, -#0x04a880,5, +0x04a880,5, 0x04a8a0,5, -#0x04a8c0,5, +0x04a8c0,5, 0x04a8e0,5, -#0x04a900,5, +0x04a900,5, 0x04a920,5, -#0x04a940,5, +0x04a940,5, 0x04a960,5, -#0x04a980,5, +0x04a980,5, 0x04a9a0,5, -#0x04a9c0,5, +0x04a9c0,5, 0x04a9e0,5, -#0x04aa00,5, +0x04aa00,5, 0x04aa20,5, -#0x04aa40,5, +0x04aa40,5, 0x04aa60,5, -#0x04aa80,5, +0x04aa80,5, 0x04aaa0,5, -#0x04aac0,5, +0x04aac0,5, 0x04aae0,5, -#0x04ab00,5, +0x04ab00,5, 0x04ab20,5, -#0x04ab40,5, +0x04ab40,5, 0x04ab60,5, -#0x04ab80,5, +0x04ab80,5, 0x04aba0,5, -#0x04abc0,5, +0x04abc0,5, 0x04abe0,5, -#0x04ac00,5, +0x04ac00,5, 0x04ac20,5, -#0x04ac40,5, +0x04ac40,5, 0x04ac60,5, -#0x04ac80,5, +0x04ac80,5, 0x04aca0,5, -#0x04acc0,5, +0x04acc0,5, 0x04ace0,5, -#0x04ad00,5, +0x04ad00,5, 0x04ad20,5, -#0x04ad40,5, +0x04ad40,5, 0x04ad60,5, -#0x04ad80,5, +0x04ad80,5, 0x04ada0,5, -#0x04adc0,5, +0x04adc0,5, 0x04ade0,5, -#0x04ae00,5, +0x04ae00,5, 0x04ae20,5, -#0x04ae40,5, +0x04ae40,5, 0x04ae60,5, -#0x04ae80,5, +0x04ae80,5, 0x04aea0,5, -#0x04aec0,5, +0x04aec0,5, 0x04aee0,5, -#0x04af00,5, +0x04af00,5, 0x04af20,5, -#0x04af40,5, +0x04af40,5, 0x04af60,5, -#0x04af80,5, +0x04af80,5, 0x04afa0,5, -#0x04afc0,5, +0x04afc0,5, 0x04afe0,5, -#0x04b000,5, +0x04b000,5, 0x04b020,5, -#0x04b040,5, +0x04b040,5, 0x04b060,5, -#0x04b080,5, +0x04b080,5, 0x04b0a0,5, -#0x04b0c0,5, +0x04b0c0,5, 0x04b0e0,5, -#0x04b100,5, +0x04b100,5, 0x04b120,5, -#0x04b140,5, +0x04b140,5, 0x04b160,5, -#0x04b180,5, +0x04b180,5, 0x04b1a0,5, -#0x04b1c0,5, +0x04b1c0,5, 0x04b1e0,5, -#0x04b200,5, +0x04b200,5, 0x04b220,5, -#0x04b240,5, +0x04b240,5, 0x04b260,5, -#0x04b280,5, +0x04b280,5, 0x04b2a0,5, -#0x04b2c0,5, +0x04b2c0,5, 0x04b2e0,5, -#0x04b300,5, +0x04b300,5, 0x04b320,5, -#0x04b340,5, +0x04b340,5, 0x04b360,5, -#0x04b380,5, +0x04b380,5, 0x04b3a0,5, -#0x04b3c0,5, +0x04b3c0,5, 0x04b3e0,5, -#0x04b400,5, +0x04b400,5, 0x04b420,5, -#0x04b440,5, +0x04b440,5, 0x04b460,5, -#0x04b480,5, +0x04b480,5, 0x04b4a0,5, -#0x04b4c0,5, +0x04b4c0,5, 0x04b4e0,5, -#0x04b500,5, +0x04b500,5, 0x04b520,5, -#0x04b540,5, +0x04b540,5, 0x04b560,5, -#0x04b580,5, +0x04b580,5, 0x04b5a0,5, -#0x04b5c0,5, +0x04b5c0,5, 0x04b5e0,5, -#0x04b600,5, +0x04b600,5, 0x04b620,5, -#0x04b640,5, +0x04b640,5, 0x04b660,5, -#0x04b680,5, +0x04b680,5, 0x04b6a0,5, -#0x04b6c0,5, +0x04b6c0,5, 0x04b6e0,5, -#0x04b700,5, +0x04b700,5, 0x04b720,5, -#0x04b740,5, +0x04b740,5, 0x04b760,5, -#0x04b780,5, +0x04b780,5, 0x04b7a0,5, -#0x04b7c0,5, +0x04b7c0,5, 0x04b7e0,5, -#0x04b800,5, +0x04b800,5, 0x04b820,5, -#0x04b840,5, +0x04b840,5, 0x04b860,5, -#0x04b880,5, +0x04b880,5, 0x04b8a0,5, -#0x04b8c0,5, +0x04b8c0,5, 0x04b8e0,5, -#0x04b900,5, +0x04b900,5, 0x04b920,5, -#0x04b940,5, +0x04b940,5, 0x04b960,5, -#0x04b980,5, +0x04b980,5, 0x04b9a0,5, -#0x04b9c0,5, +0x04b9c0,5, 0x04b9e0,5, -#0x04ba00,5, +0x04ba00,5, 0x04ba20,5, -#0x04ba40,5, +0x04ba40,5, 0x04ba60,5, -#0x04ba80,5, +0x04ba80,5, 0x04baa0,5, -#0x04bac0,5, +0x04bac0,5, 0x04bae0,5, -#0x04bb00,5, +0x04bb00,5, 0x04bb20,5, -#0x04bb40,5, +0x04bb40,5, 0x04bb60,5, -#0x04bb80,5, +0x04bb80,5, 0x04bba0,5, -#0x04bbc0,5, +0x04bbc0,5, 0x04bbe0,5, -#0x04bc00,5, +0x04bc00,5, 0x04bc20,5, -#0x04bc40,5, +0x04bc40,5, 0x04bc60,5, -#0x04bc80,5, +0x04bc80,5, 0x04bca0,5, -#0x04bcc0,5, +0x04bcc0,5, 0x04bce0,5, -#0x04bd00,5, +0x04bd00,5, 0x04bd20,5, -#0x04bd40,5, +0x04bd40,5, 0x04bd60,5, -#0x04bd80,5, +0x04bd80,5, 0x04bda0,5, -#0x04bdc0,5, +0x04bdc0,5, 0x04bde0,5, -#0x04be00,5, +0x04be00,5, 0x04be20,5, -#0x04be40,5, +0x04be40,5, 0x04be60,5, -#0x04be80,5, +0x04be80,5, 0x04bea0,5, -#0x04bec0,5, +0x04bec0,5, 0x04bee0,5, -#0x04bf00,5, +0x04bf00,5, 0x04bf20,5, -#0x04bf40,5, +0x04bf40,5, 0x04bf60,5, -#0x04bf80,5, +0x04bf80,5, 0x04bfa0,5, -#0x04bfc0,5, +0x04bfc0,5, 0x04bfe0,5, -#0x04c000,5, +0x04c000,5, 0x04c020,5, -#0x04c040,5, +0x04c040,5, 0x04c060,5, -#0x04c080,5, +0x04c080,5, 0x04c0a0,5, -#0x04c0c0,5, +0x04c0c0,5, 0x04c0e0,5, -#0x04c100,5, +0x04c100,5, 0x04c120,5, -#0x04c140,5, +0x04c140,5, 0x04c160,5, -#0x04c180,5, +0x04c180,5, 0x04c1a0,5, -#0x04c1c0,5, +0x04c1c0,5, 0x04c1e0,5, -#0x04c200,5, +0x04c200,5, 0x04c220,5, -#0x04c240,5, +0x04c240,5, 0x04c260,5, -#0x04c280,5, +0x04c280,5, 0x04c2a0,5, -#0x04c2c0,5, +0x04c2c0,5, 0x04c2e0,5, -#0x04c300,5, +0x04c300,5, 0x04c320,5, -#0x04c340,5, +0x04c340,5, 0x04c360,5, -#0x04c380,5, +0x04c380,5, 0x04c3a0,5, -#0x04c3c0,5, +0x04c3c0,5, 0x04c3e0,5, -#0x04c400,5, +0x04c400,5, 0x04c420,5, -#0x04c440,5, +0x04c440,5, 0x04c460,5, -#0x04c480,5, +0x04c480,5, 0x04c4a0,5, -#0x04c4c0,5, +0x04c4c0,5, 0x04c4e0,5, -#0x04c500,5, +0x04c500,5, 0x04c520,5, -#0x04c540,5, +0x04c540,5, 0x04c560,5, -#0x04c580,5, +0x04c580,5, 0x04c5a0,5, -#0x04c5c0,5, +0x04c5c0,5, 0x04c5e0,5, -#0x04c600,5, +0x04c600,5, 0x04c620,5, -#0x04c640,5, +0x04c640,5, 0x04c660,5, -#0x04c680,5, +0x04c680,5, 0x04c6a0,5, -#0x04c6c0,5, +0x04c6c0,5, 0x04c6e0,5, -#0x04c700,5, +0x04c700,5, 0x04c720,5, -#0x04c740,5, +0x04c740,5, 0x04c760,5, -#0x04c780,5, +0x04c780,5, 0x04c7a0,5, -#0x04c7c0,5, +0x04c7c0,5, 0x04c7e0,5, -#0x04c800,5, +0x04c800,5, 0x04c820,5, -#0x04c840,5, +0x04c840,5, 0x04c860,5, -#0x04c880,5, +0x04c880,5, 0x04c8a0,5, -#0x04c8c0,5, +0x04c8c0,5, 0x04c8e0,5, -#0x04c900,5, +0x04c900,5, 0x04c920,5, -#0x04c940,5, +0x04c940,5, 0x04c960,5, -#0x04c980,5, +0x04c980,5, 0x04c9a0,5, -#0x04c9c0,5, +0x04c9c0,5, 0x04c9e0,5, -#0x04ca00,5, +0x04ca00,5, 0x04ca20,5, -#0x04ca40,5, +0x04ca40,5, 0x04ca60,5, -#0x04ca80,5, +0x04ca80,5, 0x04caa0,5, -#0x04cac0,5, +0x04cac0,5, 0x04cae0,5, -#0x04cb00,5, +0x04cb00,5, 0x04cb20,5, -#0x04cb40,5, +0x04cb40,5, 0x04cb60,5, -#0x04cb80,5, +0x04cb80,5, 0x04cba0,5, -#0x04cbc0,5, +0x04cbc0,5, 0x04cbe0,5, -#0x04cc00,5, +0x04cc00,5, 0x04cc20,5, -#0x04cc40,5, +0x04cc40,5, 0x04cc60,5, -#0x04cc80,5, +0x04cc80,5, 0x04cca0,5, -#0x04ccc0,5, +0x04ccc0,5, 0x04cce0,5, -#0x04cd00,5, +0x04cd00,5, 0x04cd20,5, -#0x04cd40,5, +0x04cd40,5, 0x04cd60,5, -#0x04cd80,5, +0x04cd80,5, 0x04cda0,5, -#0x04cdc0,5, +0x04cdc0,5, 0x04cde0,5, -#0x04ce00,5, +0x04ce00,5, 0x04ce20,5, -#0x04ce40,5, +0x04ce40,5, 0x04ce60,5, -#0x04ce80,5, +0x04ce80,5, 0x04cea0,5, -#0x04cec0,5, +0x04cec0,5, 0x04cee0,5, -#0x04cf00,5, +0x04cf00,5, 0x04cf20,5, -#0x04cf40,5, +0x04cf40,5, 0x04cf60,5, -#0x04cf80,5, +0x04cf80,5, 0x04cfa0,5, -#0x04cfc0,5, +0x04cfc0,5, 0x04cfe0,5, 0x050004,1, 0x05000c,5, @@ -1493,46 +1522,45 @@ 0x060600,6, 0x060700,7, 0x060800,64, -0x060940,3, +0x060940,1, 0x060a04,7, 0x060c00,4, 0x060d00,2, 0x060e00,4, 0x060f40,16, 0x060f88,2, -0x061000,2, -0x061100,2, -0x061200,2, -0x061300,2, -0x061400,2, -0x061500,2, -0x061600,2, -0x061700,2, -0x061800,2, -0x061900,2, -0x061a00,2, -0x061b00,2, -0x061c00,2, -0x061d00,2, -0x061e00,2, -0x061f00,2, +0x061000,34, +0x061100,34, +0x061200,34, +0x061300,34, +0x061400,34, +0x061500,34, +0x061600,34, +0x061700,34, +0x061800,34, +0x061900,34, +0x061a00,34, +0x061b00,34, +0x061c00,34, +0x061d00,34, +0x061e00,34, +0x061f00,34, 0x062100,2, 0x064000,2048, 0x066100,3, 0x068000,2, 0x068014,2, 0x068028,3, -0x068040,3, +0x068040,1, 0x068050,2, -0x068060,3, +0x068060,1, 0x068070,2, 0x0680e4,5, -0x068800,5, -0x068818,1, +0x068800,7, 0x068820,4, -0x068840,16, +0x068868,6, 0x068980,32, -0x068a20,3, +0x068a20,1, 0x068a30,2, 0x068a80,2, 0x070000,1, @@ -1542,7 +1570,8 @@ 0x07007c,13, 0x0700bc,6, 0x0700d8,5, -0x0700f0,23, +0x0700f0,20, +0x070144,1, 0x070180,5, 0x0701fc,1, 0x070210,12, @@ -1557,53 +1586,53 @@ 0x070434,3, 0x070448,1, 0x070450,1, -0x071000,2, -0x071100,2, -0x071200,2, -0x071300,2, -0x071400,2, -0x071500,2, -0x071600,2, -0x071700,2, -0x071800,2, -0x071900,2, -0x071a00,2, -0x071b00,2, -0x072000,2, -0x072200,2, -0x072400,2, -0x072600,2, -0x072800,2, -0x072a00,2, -0x072c00,2, -0x073000,2, -0x073100,2, -0x073200,2, -0x073300,2, -0x073400,2, -0x073500,2, -0x073600,2, -0x073700,2, -0x073800,2, -0x073900,2, -0x073a00,2, -0x073b00,2, +0x071000,33, +0x071100,33, +0x071200,33, +0x071300,33, +0x071400,33, +0x071500,33, +0x071600,33, +0x071700,33, +0x071800,33, +0x071900,33, +0x071a00,33, +0x071b00,33, +0x072000,67, +0x072200,67, +0x072400,67, +0x072600,67, +0x072800,67, +0x072a00,67, +0x072c00,67, +0x073000,33, +0x073100,33, +0x073200,33, +0x073300,33, +0x073400,33, +0x073500,33, +0x073600,33, +0x073700,33, +0x073800,33, +0x073900,33, +0x073a00,33, +0x073b00,33, 0x074000,1536, 0x076000,12, 0x077000,384, 0x077800,256, -0x078000,2, -0x078080,2, -0x078100,2, -0x078180,2, +0x078000,17, +0x078080,17, +0x078100,17, +0x078180,17, 0x078210,5, -0x078240,3, -0x078250,3, -0x078260,3, -0x078270,3, +0x078240,1, +0x078250,1, +0x078260,1, +0x078270,1, 0x078284,2, 0x0782d4,59, -0x078400,6, +0x078400,2, 0x078420,1, 0x078a60,5, 0x078a84,16, @@ -1612,11 +1641,10 @@ 0x078c20,10, 0x078c50,2, 0x078c5c,7, -0x078c80,5, +0x078c80,4, 0x078ca0,1, 0x078cc0,9, 0x078e60,1, -0x078e70,1, 0x078e80,10, 0x078ec0,2, 0x078ecc,1, @@ -1630,535 +1658,536 @@ 0x078f78,2, 0x078fb4,6, 0x078fd0,1, -0x079000,1,UNKNOWN -0x079008,1,UNKNOWN -#0x079010,1, -0x079018,1,UNKNOWN -#0x079020,1, -0x079028,1,UNKNOWN -#0x079030,1, -0x079038,1,UNKNOWN -0x079040,1,UNKNOWN -0x079048,1,UNKNOWN -0x079050,1,UNKNOWN -0x079058,1,UNKNOWN -0x079060,1,UNKNOWN -0x079068,1,UNKNOWN -0x079070,1,UNKNOWN -0x079078,1,UNKNOWN -0x079080,1,UNKNOWN -0x079088,1,UNKNOWN -0x079090,1,UNKNOWN -0x079098,1,UNKNOWN -0x0790a0,1,UNKNOWN -0x0790a8,1,UNKNOWN -0x0790b0,1,UNKNOWN -0x0790b8,1,UNKNOWN -0x0790c0,1,UNKNOWN -0x0790c8,1,UNKNOWN -0x0790d0,1,UNKNOWN -0x0790d8,1,UNKNOWN -0x0790e0,1,UNKNOWN -0x0790e8,1,UNKNOWN -0x0790f0,1,UNKNOWN -0x0790f8,1,UNKNOWN -0x079100,1,UNKNOWN -0x079108,1,UNKNOWN -0x079110,1,UNKNOWN -0x079118,1,UNKNOWN -0x079120,1,UNKNOWN -0x079128,1,UNKNOWN -0x079130,1,UNKNOWN -0x079138,1,UNKNOWN -0x079140,1,UNKNOWN -0x079148,1,UNKNOWN -0x079150,1,UNKNOWN -0x079158,1,UNKNOWN -0x079160,1,UNKNOWN -0x079168,1,UNKNOWN -#0x079170,1, -0x079178,1,UNKNOWN -#0x079180,1, -0x079188,1,UNKNOWN -#0x079190,1, -0x079198,1,UNKNOWN -#0x0791a0,1, -0x0791a8,1,UNKNOWN -#0x0791b0,1, -0x0791b8,1,UNKNOWN -#0x0791c0,1, -0x0791c8,1,UNKNOWN -#0x0791d0,1, -0x0791d8,1,UNKNOWN -#0x0791e0,1, -0x0791e8,1,UNKNOWN -#0x0791f0,1, -0x0791f8,1,UNKNOWN -#0x079200,1, -0x079208,1,UNKNOWN -#0x079210,1, -0x079218,1,UNKNOWN -#0x079220,1, -0x079228,1,UNKNOWN -#0x079230,1, -0x079238,1,UNKNOWN -#0x079240,1, -0x079248,1,UNKNOWN -#0x079250,1, -0x079258,1,UNKNOWN -#0x079260,1, -0x079268,1,UNKNOWN -#0x079270,1, -0x079278,1,UNKNOWN -#0x079280,1, -0x079288,1,UNKNOWN -#0x079290,1, -0x079298,1,UNKNOWN -#0x0792a0,1, -0x0792a8,1,UNKNOWN -#0x0792b0,1, -0x0792b8,1,UNKNOWN -#0x0792c0,1, -0x0792c8,1,UNKNOWN -#0x0792d0,1, -0x0792d8,1,UNKNOWN -#0x0792e0,1, -0x0792e8,1,UNKNOWN -#0x0792f0,1, -0x0792f8,1,UNKNOWN -#0x079300,1, -0x079308,1,UNKNOWN -#0x079310,1, -0x079318,1,UNKNOWN -#0x079320,1, -0x079328,1,UNKNOWN -#0x079330,1, -0x079338,1,UNKNOWN -#0x079340,1, -0x079348,1,UNKNOWN -#0x079350,1, -0x079358,1,UNKNOWN -#0x079360,1, -0x079368,1,UNKNOWN -#0x079370,1, -0x079378,1,UNKNOWN -#0x079380,1, -0x079388,1,UNKNOWN -#0x079390,1, -0x079398,1,UNKNOWN -#0x0793a0,1, -0x0793a8,1,UNKNOWN -#0x0793b0,1, -0x0793b8,1,UNKNOWN -#0x0793c0,1, -0x0793c8,1,UNKNOWN -#0x0793d0,1, -0x0793d8,1,UNKNOWN -#0x0793e0,1, -0x0793e8,1,UNKNOWN -#0x0793f0,1, -0x0793f8,1,UNKNOWN -#0x079400,1, -0x079408,1,UNKNOWN -#0x079410,1, -0x079418,1,UNKNOWN -#0x079420,1, -0x079428,1,UNKNOWN -#0x079430,1, -0x079438,1,UNKNOWN -#0x079440,1, -0x079448,1,UNKNOWN -#0x079450,1, -0x079458,1,UNKNOWN -#0x079460,1, -0x079468,1,UNKNOWN -#0x079470,1, -0x079478,1,UNKNOWN -#0x079480,1, -0x079488,1,UNKNOWN -#0x079490,1, -0x079498,1,UNKNOWN -#0x0794a0,1, -0x0794a8,1,UNKNOWN -#0x0794b0,1, -0x0794b8,1,UNKNOWN -#0x0794c0,1, -0x0794c8,1,UNKNOWN -#0x0794d0,1, -0x0794d8,1,UNKNOWN -#0x0794e0,1, -0x0794e8,1,UNKNOWN -#0x0794f0,1, -0x0794f8,1,UNKNOWN -#0x079500,1, -0x079508,1,UNKNOWN -#0x079510,1, -0x079518,1,UNKNOWN -#0x079520,1, -0x079528,1,UNKNOWN -#0x079530,1, -0x079538,1,UNKNOWN -#0x079540,1, -0x079548,1,UNKNOWN -#0x079550,1, -0x079558,1,UNKNOWN -#0x079560,1, -0x079568,1,UNKNOWN -#0x079570,1, -0x079578,1,UNKNOWN -#0x079580,1, -0x079588,1,UNKNOWN -#0x079590,1, -0x079598,1,UNKNOWN -#0x0795a0,1, -0x0795a8,1,UNKNOWN -#0x0795b0,1, -0x0795b8,1,UNKNOWN -#0x0795c0,1, -0x0795c8,1,UNKNOWN -#0x0795d0,1, -0x0795d8,1,UNKNOWN -#0x0795e0,1, -0x0795e8,1,UNKNOWN -#0x0795f0,1, -0x0795f8,1,UNKNOWN -#0x079600,1, -0x079608,1,UNKNOWN -#0x079610,1, -0x079618,1,UNKNOWN -#0x079620,1, -0x079628,1,UNKNOWN -#0x079630,1, -0x079638,1,UNKNOWN -#0x079640,1, -0x079648,1,UNKNOWN -#0x079650,1, -0x079658,1,UNKNOWN -#0x079660,1, -0x079668,1,UNKNOWN -#0x079670,1, -0x079678,1,UNKNOWN -#0x079680,1, -0x079688,1,UNKNOWN -#0x079690,1, -0x079698,1,UNKNOWN -#0x0796a0,1, -0x0796a8,1,UNKNOWN -#0x0796b0,1, -0x0796b8,1,UNKNOWN -#0x0796c0,1, -0x0796c8,1,UNKNOWN -#0x0796d0,1, -0x0796d8,1,UNKNOWN -#0x0796e0,1, -0x0796e8,1,UNKNOWN -#0x0796f0,1, -0x0796f8,1,UNKNOWN -#0x079700,1, -0x079708,1,UNKNOWN -#0x079710,1, -0x079718,1,UNKNOWN -#0x079720,1, -0x079728,1,UNKNOWN -#0x079730,1, -0x079738,1,UNKNOWN -#0x079740,1, -0x079748,1,UNKNOWN -#0x079750,1, -0x079758,1,UNKNOWN -#0x079760,1, -0x079768,1,UNKNOWN -#0x079770,1, -0x079778,1,UNKNOWN -#0x079780,1, -0x079788,1,UNKNOWN -#0x079790,1, -0x079798,1,UNKNOWN -#0x0797a0,1, -0x0797a8,1,UNKNOWN -#0x0797b0,1, -0x0797b8,1,UNKNOWN -#0x0797c0,1, -0x0797c8,1,UNKNOWN -#0x0797d0,1, -0x0797d8,1,UNKNOWN -#0x0797e0,1, -0x0797e8,1,UNKNOWN -#0x0797f0,1, -0x0797f8,1,UNKNOWN -#0x079800,1, -0x079808,1,UNKNOWN -#0x079810,1, -0x079818,1,UNKNOWN -#0x079820,1, -0x079828,1,UNKNOWN -#0x079830,1, -0x079838,1,UNKNOWN -#0x079840,1, -0x079848,1,UNKNOWN -#0x079850,1, -0x079858,1,UNKNOWN -#0x079860,1, -0x079868,1,UNKNOWN -#0x079870,1, -0x079878,1,UNKNOWN -#0x079880,1, -0x079888,1,UNKNOWN -#0x079890,1, -0x079898,1,UNKNOWN -#0x0798a0,1, -0x0798a8,1,UNKNOWN -#0x0798b0,1, -0x0798b8,1,UNKNOWN -#0x0798c0,1, -0x0798c8,1,UNKNOWN -#0x0798d0,1, -0x0798d8,1,UNKNOWN -#0x0798e0,1, -0x0798e8,1,UNKNOWN -#0x0798f0,1, -0x0798f8,1,UNKNOWN -#0x079900,1, -0x079908,1,UNKNOWN -#0x079910,1, -0x079918,1,UNKNOWN -#0x079920,1, -0x079928,1,UNKNOWN -#0x079930,1, -0x079938,1,UNKNOWN -#0x079940,1, -0x079948,1,UNKNOWN -#0x079950,1, -0x079958,1,UNKNOWN -#0x079960,1, -0x079968,1,UNKNOWN -#0x079970,1, -0x079978,1,UNKNOWN -#0x079980,1, -0x079988,1,UNKNOWN -#0x079990,1, -0x079998,1,UNKNOWN -#0x0799a0,1, -0x0799a8,1,UNKNOWN -#0x0799b0,1, -0x0799b8,1,UNKNOWN -#0x0799c0,1, -0x0799c8,1,UNKNOWN -#0x0799d0,1, -0x0799d8,1,UNKNOWN -#0x0799e0,1, -0x0799e8,1,UNKNOWN -#0x0799f0,1, -0x0799f8,1,UNKNOWN -#0x079a00,1, -0x079a08,1,UNKNOWN -#0x079a10,1, -0x079a18,1,UNKNOWN -#0x079a20,1, -0x079a28,1,UNKNOWN -#0x079a30,1, -0x079a38,1,UNKNOWN -#0x079a40,1, -0x079a48,1,UNKNOWN -#0x079a50,1, -0x079a58,1,UNKNOWN -#0x079a60,1, -0x079a68,1,UNKNOWN -#0x079a70,1, -0x079a78,1,UNKNOWN -#0x079a80,1, -0x079a88,1,UNKNOWN -#0x079a90,1, -0x079a98,1,UNKNOWN -#0x079aa0,1, -0x079aa8,1,UNKNOWN -#0x079ab0,1, -0x079ab8,1,UNKNOWN -#0x079ac0,1, -0x079ac8,1,UNKNOWN -#0x079ad0,1, -0x079ad8,1,UNKNOWN -#0x079ae0,1, -0x079ae8,1,UNKNOWN -#0x079af0,1, -0x079af8,1,UNKNOWN -#0x079b00,1, -0x079b08,1,UNKNOWN -#0x079b10,1, -0x079b18,1,UNKNOWN -#0x079b20,1, -0x079b28,1,UNKNOWN -#0x079b30,1, -0x079b38,1,UNKNOWN -#0x079b40,1, -0x079b48,1,UNKNOWN -#0x079b50,1, -0x079b58,1,UNKNOWN -#0x079b60,1, -0x079b68,1,UNKNOWN -#0x079b70,1, -0x079b78,1,UNKNOWN -#0x079b80,1, -0x079b88,1,UNKNOWN -#0x079b90,1, -0x079b98,1,UNKNOWN -#0x079ba0,1, -0x079ba8,1,UNKNOWN -#0x079bb0,1, -0x079bb8,1,UNKNOWN -#0x079bc0,1, -0x079bc8,1,UNKNOWN -#0x079bd0,1, -0x079bd8,1,UNKNOWN -#0x079be0,1, -0x079be8,1,UNKNOWN -#0x079bf0,1, -0x079bf8,1,UNKNOWN -#0x079c00,1, -0x079c08,1,UNKNOWN -#0x079c10,1, -0x079c18,1,UNKNOWN -#0x079c20,1, -0x079c28,1,UNKNOWN -#0x079c30,1, -0x079c38,1,UNKNOWN -#0x079c40,1, -0x079c48,1,UNKNOWN -#0x079c50,1, -0x079c58,1,UNKNOWN -#0x079c60,1, -0x079c68,1,UNKNOWN -#0x079c70,1, -0x079c78,1,UNKNOWN -#0x079c80,1, -0x079c88,1,UNKNOWN -#0x079c90,1, -0x079c98,1,UNKNOWN -#0x079ca0,1, -0x079ca8,1,UNKNOWN -#0x079cb0,1, -0x079cb8,1,UNKNOWN -#0x079cc0,1, -0x079cc8,1,UNKNOWN -#0x079cd0,1, -0x079cd8,1,UNKNOWN -#0x079ce0,1, -0x079ce8,1,UNKNOWN -#0x079cf0,1, -0x079cf8,1,UNKNOWN -#0x079d00,1, -0x079d08,1,UNKNOWN -#0x079d10,1, -0x079d18,1,UNKNOWN -#0x079d20,1, -0x079d28,1,UNKNOWN -#0x079d30,1, -0x079d38,1,UNKNOWN -#0x079d40,1, -0x079d48,1,UNKNOWN -#0x079d50,1, -0x079d58,1,UNKNOWN -#0x079d60,1, -0x079d68,1,UNKNOWN -#0x079d70,1, -0x079d78,1,UNKNOWN -#0x079d80,1, -0x079d88,1,UNKNOWN -#0x079d90,1, -0x079d98,1,UNKNOWN -#0x079da0,1, -0x079da8,1,UNKNOWN -#0x079db0,1, -0x079db8,1,UNKNOWN -#0x079dc0,1, -0x079dc8,1,UNKNOWN -#0x079dd0,1, -0x079dd8,1,UNKNOWN -#0x079de0,1, -0x079de8,1,UNKNOWN -#0x079df0,1, -0x079df8,1,UNKNOWN -#0x079e00,1, -0x079e08,1,UNKNOWN -#0x079e10,1, -0x079e18,1,UNKNOWN -#0x079e20,1, -0x079e28,1,UNKNOWN -#0x079e30,1, -0x079e38,1,UNKNOWN -#0x079e40,1, -0x079e48,1,UNKNOWN -#0x079e50,1, -0x079e58,1,UNKNOWN -#0x079e60,1, -0x079e68,1,UNKNOWN -#0x079e70,1, -0x079e78,1,UNKNOWN -#0x079e80,1, -0x079e88,1,UNKNOWN -#0x079e90,1, -0x079e98,1,UNKNOWN -#0x079ea0,1, -0x079ea8,1,UNKNOWN -#0x079eb0,1, -0x079eb8,1,UNKNOWN -#0x079ec0,1, -0x079ec8,1,UNKNOWN -#0x079ed0,1, -0x079ed8,1,UNKNOWN -#0x079ee0,1, -0x079ee8,1,UNKNOWN -#0x079ef0,1, -0x079ef8,1,UNKNOWN -#0x079f00,1, -0x079f08,1,UNKNOWN -#0x079f10,1, -0x079f18,1,UNKNOWN -#0x079f20,1, -0x079f28,1,UNKNOWN -#0x079f30,1, -0x079f38,1,UNKNOWN -#0x079f40,1, -0x079f48,1,UNKNOWN -#0x079f50,1, -0x079f58,1,UNKNOWN -#0x079f60,1, -0x079f68,1,UNKNOWN -#0x079f70,1, -0x079f78,1,UNKNOWN -#0x079f80,1, -0x079f88,1,UNKNOWN -#0x079f90,1, -0x079f98,1,UNKNOWN -#0x079fa0,1, -0x079fa8,1,UNKNOWN -#0x079fb0,1, -0x079fb8,1,UNKNOWN -#0x079fc0,1, -0x079fc8,1,UNKNOWN -#0x079fd0,1, -0x079fd8,1,UNKNOWN -#0x079fe0,1, -0x079fe8,1,UNKNOWN -#0x079ff0,1, -0x079ff8,1,UNKNOWN +0x079000,1, +0x079008,1, +0x079010,1, +0x079018,1, +0x079020,1, +0x079028,1, +0x079030,1, +0x079038,1, +0x079040,1, +0x079048,1, +0x079050,1, +0x079058,1, +0x079060,1, +0x079068,1, +0x079070,1, +0x079078,1, +0x079080,1, +0x079088,1, +0x079090,1, +0x079098,1, +0x0790a0,1, +0x0790a8,1, +0x0790b0,1, +0x0790b8,1, +0x0790c0,1, +0x0790c8,1, +0x0790d0,1, +0x0790d8,1, +0x0790e0,1, +0x0790e8,1, +0x0790f0,1, +0x0790f8,1, +0x079100,1, +0x079108,1, +0x079110,1, +0x079118,1, +0x079120,1, +0x079128,1, +0x079130,1, +0x079138,1, +0x079140,1, +0x079148,1, +0x079150,1, +0x079158,1, +0x079160,1, +0x079168,1, +0x079170,1, +0x079178,1, +0x079180,1, +0x079188,1, +0x079190,1, +0x079198,1, +0x0791a0,1, +0x0791a8,1, +0x0791b0,1, +0x0791b8,1, +0x0791c0,1, +0x0791c8,1, +0x0791d0,1, +0x0791d8,1, +0x0791e0,1, +0x0791e8,1, +0x0791f0,1, +0x0791f8,1, +0x079200,1, +0x079208,1, +0x079210,1, +0x079218,1, +0x079220,1, +0x079228,1, +0x079230,1, +0x079238,1, +0x079240,1, +0x079248,1, +0x079250,1, +0x079258,1, +0x079260,1, +0x079268,1, +0x079270,1, +0x079278,1, +0x079280,1, +0x079288,1, +0x079290,1, +0x079298,1, +0x0792a0,1, +0x0792a8,1, +0x0792b0,1, +0x0792b8,1, +0x0792c0,1, +0x0792c8,1, +0x0792d0,1, +0x0792d8,1, +0x0792e0,1, +0x0792e8,1, +0x0792f0,1, +0x0792f8,1, +0x079300,1, +0x079308,1, +0x079310,1, +0x079318,1, +0x079320,1, +0x079328,1, +0x079330,1, +0x079338,1, +0x079340,1, +0x079348,1, +0x079350,1, +0x079358,1, +0x079360,1, +0x079368,1, +0x079370,1, +0x079378,1, +0x079380,1, +0x079388,1, +0x079390,1, +0x079398,1, +0x0793a0,1, +0x0793a8,1, +0x0793b0,1, +0x0793b8,1, +0x0793c0,1, +0x0793c8,1, +0x0793d0,1, +0x0793d8,1, +0x0793e0,1, +0x0793e8,1, +0x0793f0,1, +0x0793f8,1, +0x079400,1, +0x079408,1, +0x079410,1, +0x079418,1, +0x079420,1, +0x079428,1, +0x079430,1, +0x079438,1, +0x079440,1, +0x079448,1, +0x079450,1, +0x079458,1, +0x079460,1, +0x079468,1, +0x079470,1, +0x079478,1, +0x079480,1, +0x079488,1, +0x079490,1, +0x079498,1, +0x0794a0,1, +0x0794a8,1, +0x0794b0,1, +0x0794b8,1, +0x0794c0,1, +0x0794c8,1, +0x0794d0,1, +0x0794d8,1, +0x0794e0,1, +0x0794e8,1, +0x0794f0,1, +0x0794f8,1, +0x079500,1, +0x079508,1, +0x079510,1, +0x079518,1, +0x079520,1, +0x079528,1, +0x079530,1, +0x079538,1, +0x079540,1, +0x079548,1, +0x079550,1, +0x079558,1, +0x079560,1, +0x079568,1, +0x079570,1, +0x079578,1, +0x079580,1, +0x079588,1, +0x079590,1, +0x079598,1, +0x0795a0,1, +0x0795a8,1, +0x0795b0,1, +0x0795b8,1, +0x0795c0,1, +0x0795c8,1, +0x0795d0,1, +0x0795d8,1, +0x0795e0,1, +0x0795e8,1, +0x0795f0,1, +0x0795f8,1, +0x079600,1, +0x079608,1, +0x079610,1, +0x079618,1, +0x079620,1, +0x079628,1, +0x079630,1, +0x079638,1, +0x079640,1, +0x079648,1, +0x079650,1, +0x079658,1, +0x079660,1, +0x079668,1, +0x079670,1, +0x079678,1, +0x079680,1, +0x079688,1, +0x079690,1, +0x079698,1, +0x0796a0,1, +0x0796a8,1, +0x0796b0,1, +0x0796b8,1, +0x0796c0,1, +0x0796c8,1, +0x0796d0,1, +0x0796d8,1, +0x0796e0,1, +0x0796e8,1, +0x0796f0,1, +0x0796f8,1, +0x079700,1, +0x079708,1, +0x079710,1, +0x079718,1, +0x079720,1, +0x079728,1, +0x079730,1, +0x079738,1, +0x079740,1, +0x079748,1, +0x079750,1, +0x079758,1, +0x079760,1, +0x079768,1, +0x079770,1, +0x079778,1, +0x079780,1, +0x079788,1, +0x079790,1, +0x079798,1, +0x0797a0,1, +0x0797a8,1, +0x0797b0,1, +0x0797b8,1, +0x0797c0,1, +0x0797c8,1, +0x0797d0,1, +0x0797d8,1, +0x0797e0,1, +0x0797e8,1, +0x0797f0,1, +0x0797f8,1, +0x079800,1, +0x079808,1, +0x079810,1, +0x079818,1, +0x079820,1, +0x079828,1, +0x079830,1, +0x079838,1, +0x079840,1, +0x079848,1, +0x079850,1, +0x079858,1, +0x079860,1, +0x079868,1, +0x079870,1, +0x079878,1, +0x079880,1, +0x079888,1, +0x079890,1, +0x079898,1, +0x0798a0,1, +0x0798a8,1, +0x0798b0,1, +0x0798b8,1, +0x0798c0,1, +0x0798c8,1, +0x0798d0,1, +0x0798d8,1, +0x0798e0,1, +0x0798e8,1, +0x0798f0,1, +0x0798f8,1, +0x079900,1, +0x079908,1, +0x079910,1, +0x079918,1, +0x079920,1, +0x079928,1, +0x079930,1, +0x079938,1, +0x079940,1, +0x079948,1, +0x079950,1, +0x079958,1, +0x079960,1, +0x079968,1, +0x079970,1, +0x079978,1, +0x079980,1, +0x079988,1, +0x079990,1, +0x079998,1, +0x0799a0,1, +0x0799a8,1, +0x0799b0,1, +0x0799b8,1, +0x0799c0,1, +0x0799c8,1, +0x0799d0,1, +0x0799d8,1, +0x0799e0,1, +0x0799e8,1, +0x0799f0,1, +0x0799f8,1, +0x079a00,1, +0x079a08,1, +0x079a10,1, +0x079a18,1, +0x079a20,1, +0x079a28,1, +0x079a30,1, +0x079a38,1, +0x079a40,1, +0x079a48,1, +0x079a50,1, +0x079a58,1, +0x079a60,1, +0x079a68,1, +0x079a70,1, +0x079a78,1, +0x079a80,1, +0x079a88,1, +0x079a90,1, +0x079a98,1, +0x079aa0,1, +0x079aa8,1, +0x079ab0,1, +0x079ab8,1, +0x079ac0,1, +0x079ac8,1, +0x079ad0,1, +0x079ad8,1, +0x079ae0,1, +0x079ae8,1, +0x079af0,1, +0x079af8,1, +0x079b00,1, +0x079b08,1, +0x079b10,1, +0x079b18,1, +0x079b20,1, +0x079b28,1, +0x079b30,1, +0x079b38,1, +0x079b40,1, +0x079b48,1, +0x079b50,1, +0x079b58,1, +0x079b60,1, +0x079b68,1, +0x079b70,1, +0x079b78,1, +0x079b80,1, +0x079b88,1, +0x079b90,1, +0x079b98,1, +0x079ba0,1, +0x079ba8,1, +0x079bb0,1, +0x079bb8,1, +0x079bc0,1, +0x079bc8,1, +0x079bd0,1, +0x079bd8,1, +0x079be0,1, +0x079be8,1, +0x079bf0,1, +0x079bf8,1, +0x079c00,1, +0x079c08,1, +0x079c10,1, +0x079c18,1, +0x079c20,1, +0x079c28,1, +0x079c30,1, +0x079c38,1, +0x079c40,1, +0x079c48,1, +0x079c50,1, +0x079c58,1, +0x079c60,1, +0x079c68,1, +0x079c70,1, +0x079c78,1, +0x079c80,1, +0x079c88,1, +0x079c90,1, +0x079c98,1, +0x079ca0,1, +0x079ca8,1, +0x079cb0,1, +0x079cb8,1, +0x079cc0,1, +0x079cc8,1, +0x079cd0,1, +0x079cd8,1, +0x079ce0,1, +0x079ce8,1, +0x079cf0,1, +0x079cf8,1, +0x079d00,1, +0x079d08,1, +0x079d10,1, +0x079d18,1, +0x079d20,1, +0x079d28,1, +0x079d30,1, +0x079d38,1, +0x079d40,1, +0x079d48,1, +0x079d50,1, +0x079d58,1, +0x079d60,1, +0x079d68,1, +0x079d70,1, +0x079d78,1, +0x079d80,1, +0x079d88,1, +0x079d90,1, +0x079d98,1, +0x079da0,1, +0x079da8,1, +0x079db0,1, +0x079db8,1, +0x079dc0,1, +0x079dc8,1, +0x079dd0,1, +0x079dd8,1, +0x079de0,1, +0x079de8,1, +0x079df0,1, +0x079df8,1, +0x079e00,1, +0x079e08,1, +0x079e10,1, +0x079e18,1, +0x079e20,1, +0x079e28,1, +0x079e30,1, +0x079e38,1, +0x079e40,1, +0x079e48,1, +0x079e50,1, +0x079e58,1, +0x079e60,1, +0x079e68,1, +0x079e70,1, +0x079e78,1, +0x079e80,1, +0x079e88,1, +0x079e90,1, +0x079e98,1, +0x079ea0,1, +0x079ea8,1, +0x079eb0,1, +0x079eb8,1, +0x079ec0,1, +0x079ec8,1, +0x079ed0,1, +0x079ed8,1, +0x079ee0,1, +0x079ee8,1, +0x079ef0,1, +0x079ef8,1, +0x079f00,1, +0x079f08,1, +0x079f10,1, +0x079f18,1, +0x079f20,1, +0x079f28,1, +0x079f30,1, +0x079f38,1, +0x079f40,1, +0x079f48,1, +0x079f50,1, +0x079f58,1, +0x079f60,1, +0x079f68,1, +0x079f70,1, +0x079f78,1, +0x079f80,1, +0x079f88,1, +0x079f90,1, +0x079f98,1, +0x079fa0,1, +0x079fa8,1, +0x079fb0,1, +0x079fb8,1, +0x079fc0,1, +0x079fc8,1, +0x079fd0,1, +0x079fd8,1, +0x079fe0,1, +0x079fe8,1, +0x079ff0,1, +0x079ff8,1, 0x07bef8,2, 0x07bf04,1, 0x07bf14,22, 0x07bf80,2, 0x07bffc,1033, 0x07e000,1044, -0x07f100,36, +0x07f100,8, +0x07f160,4, 0x07f200,3, 0x07f7f8,514, 0x080680,7, 0x081000,3, 0x081010,16, -0x081120,3, +0x081120,1, 0x081130,2, -0x081140,3, +0x081140,1, 0x081150,2, -0x081160,3, +0x081160,1, 0x081170,2, 0x081204,18, 0x081304,2, @@ -2167,21 +2196,32 @@ 0x081468,6, 0x081504,2, 0x081604,14, -0x081640,128, +0x081640,2, +0x08164c,15, +0x08168c,15, +0x0816cc,15, +0x08170c,15, +0x08174c,15, +0x08178c,15, +0x0817cc,15, +0x08180c,13, 0x081904,5, 0x081a30,4, 0x081a60,18, 0x081ab0,3, 0x081ad0,4, 0x081c00,128, -0x081e04,13, +0x081e04,12, 0x082000,8, 0x082024,1, 0x082030,1, -0x082044,40, +0x082044,20, +0x08209c,2, +0x0820ac,14, 0x082180,1, 0x0821c4,1, -0x0821e0,5, +0x0821e0,1, +0x0821e8,3, 0x0821f8,1, 0x082200,9, 0x08229c,3, @@ -2205,17 +2245,17 @@ 0x083800,2, 0x083814,2, 0x083828,3, -0x083840,3, +0x083840,1, 0x083850,2, -0x083860,3, +0x083860,1, 0x083870,2, 0x0838e4,5, 0x083910,5, 0x083948,6, -0x0f0000,9, -0x0f0040,8, -0x0f0064,1, -0x0f0078,5, +0x0f0000,3, +0x0f0014,4, +0x0f0040,6, +0x0f0078,3, 0x0f0090,2, 0x0f00a4,2, 0x0f00b0,4, @@ -2224,7 +2264,7 @@ 0x0f01e0,4, 0x0f01f4,1, 0x0f0200,4, -0x0f0240,11, +0x0f0240,9, 0x0f0270,2, 0x0f0280,3, 0x0f02a4,5, @@ -2241,7 +2281,8 @@ 0x0f310c,1, 0x0f3120,2, 0x0f3130,5, -0x0f3184,16, +0x0f3184,13, +0x0f31bc,2, 0x0f3204,1, 0x0f3210,5, 0x0f3240,1, @@ -2255,7 +2296,7 @@ 0x0f3500,1, 0x0f3520,6, 0x0f3540,15, -0x0f3580,11, +0x0f3580,9, 0x0f35b0,2, 0x0f35c0,2, 0x0f35dc,6, @@ -2263,16 +2304,18 @@ 0x0f362c,5, 0x0f3700,15, 0x0f3740,4, -0x0f3760,3, +0x0f3760,1, 0x0f3770,2, -0x0f3780,3, +0x0f3780,1, 0x0f3790,2, 0x0f3800,3, 0x0f3810,25, 0x0f389c,5, 0x0f38f8,2, 0x0f3a00,3, -0x0f3a10,13, +0x0f3a10,4, +0x0f3a24,3, +0x0f3a34,4, 0x0f3a84,3, 0x0f3b00,1, 0x0f3b08,2, @@ -2286,7 +2329,7 @@ 0x0f3d00,1, 0x0f3d14,1, 0x0f3d28,2, -0x0f3d40,3, +0x0f3d40,1, 0x0f3d50,2, 0x0f3de4,4, 0x0f3e00,73, diff --git a/mstdump/mstdump_dbs/ConnectX3.csv b/mstdump/mstdump_dbs/ConnectX3.csv index f7c3903..989c709 100755 --- a/mstdump/mstdump_dbs/ConnectX3.csv +++ b/mstdump/mstdump_dbs/ConnectX3.csv @@ -1,29 +1,29 @@ -# addr, size, enable addr +#Addr, Size, Enable addr 0x010000,2, 0x010010,2, 0x0100a0,15, 0x0100ec,2, -0x0100fc,3, +0x0100fc,2, 0x01010c,2, 0x010150,1, 0x0101cc,1, 0x0101fc,1, -0x010208,10, -0x010300,7, +0x010208,9, +0x010300,6, 0x010320,20, 0x010374,3, -0x010400,3, +0x010400,1, 0x010410,2, -0x010440,3, +0x010440,1, 0x010450,2, -0x010500,3, +0x010500,1, 0x010510,2, 0x010520,2, 0x01052c,3, 0x01053c,3, -0x010550,2, +0x010550,1, 0x010600,16, -0x010680,3, +0x010680,1, 0x010690,2, 0x0106ac,1, 0x0106b8,1, @@ -35,27 +35,27 @@ 0x010810,2, 0x0108a0,15, 0x0108ec,2, -0x0108fc,3, +0x0108fc,2, 0x01090c,2, 0x010950,1, 0x0109cc,1, 0x0109fc,1, -0x010a08,10, -0x010b00,7, +0x010a08,9, +0x010b00,6, 0x010b20,20, 0x010b74,3, -0x010c00,3, +0x010c00,1, 0x010c10,2, -0x010c40,3, +0x010c40,1, 0x010c50,2, -0x010d00,3, +0x010d00,1, 0x010d10,2, 0x010d20,2, 0x010d2c,3, 0x010d3c,3, -0x010d50,2, +0x010d50,1, 0x010e00,16, -0x010e80,3, +0x010e80,1, 0x010e90,2, 0x010eac,1, 0x010eb8,1, @@ -74,7 +74,7 @@ 0x011240,4, 0x011260,1, 0x011280,5, -0x011300,3, +0x011300,1, 0x011310,2, 0x011400,4, 0x011460,1, @@ -90,16 +90,16 @@ 0x011a40,4, 0x011a60,1, 0x011a80,5, -0x011b00,3, +0x011b00,1, 0x011b10,2, 0x011c00,4, 0x011c60,1, 0x011cb0,4, 0x012000,1, 0x01200c,1, -0x012020,3, +0x012020,1, 0x012030,2, -0x012040,3, +0x012044,2, 0x0120a0,4, 0x0120c0,7, 0x01211c,13, @@ -130,82 +130,90 @@ 0x01275c,1, 0x0127d8,2, 0x0127e8,2, -0x012840,3, +0x012840,1, 0x012850,2, 0x0128a0,5, 0x012904,1, 0x012910,5, 0x012928,4, -0x012944,9, +0x012944,2, +0x012950,1, +0x012958,4, 0x012980,4, -0x0129a0,3, +0x0129a0,1, 0x0129b0,2, 0x012d48,4, 0x013000,9, 0x013040,6, -0x013060,21, +0x013060,6, +0x013080,13, 0x0130c0,13, -0x013100,38, -0x0131a0,6, -0x0131c0,6, -0x0131e0,6, -0x013200,38, -0x0132a0,6, -0x0132c0,6, -0x0132e0,6, -0x013300,11, +0x013100,37, +0x0131a0,5, +0x0131c0,5, +0x0131e0,5, +0x013200,37, +0x0132a0,5, +0x0132c0,5, +0x0132e0,5, +0x013300,9, 0x013330,2, -0x013340,3, +0x013340,1, 0x013350,2, -0x013360,3, +0x013360,1, 0x013370,2, -0x013380,43, +0x013380,2, +0x01338c,38, 0x013430,2, -0x013440,3, +0x013440,1, 0x013450,2, -0x013460,3, +0x013460,1, 0x013470,2, -0x013480,35, +0x013480,2, +0x01348c,30, 0x013510,2, -0x013520,3, +0x013520,1, 0x013530,2, 0x013544,2, 0x013580,15, -0x0135c0,19, +0x0135c0,16, +0x013604,2, 0x013628,2, 0x013634,1, -0x013640,3, +0x013644,2, 0x013668,2, 0x013674,1, -0x013680,3, +0x013684,2, 0x0136a8,2, 0x0136b4,1, -0x0136c0,3, +0x0136c4,2, 0x0136e8,2, 0x0136f4,1, 0x013700,21, 0x013800,1, 0x013820,2, 0x01382c,10, -0x01386c,16, +0x01386c,10, +0x013898,3, 0x0138b0,2, 0x013a00,1, 0x013a20,2, 0x013a2c,10, -0x013a6c,16, +0x013a6c,10, +0x013a98,3, 0x013ab0,2, 0x013c00,4, 0x013c14,7, 0x013c38,4, 0x013c54,2, -0x013ca0,3, +0x013ca0,1, 0x013cb0,2, -0x013cc0,3, +0x013cc0,1, 0x013cd0,2, 0x013d00,3, 0x013d10,6, 0x013d44,7, -0x013d64,10, +0x013d64,8, 0x013d90,2, 0x013da0,6, 0x013e00,1, @@ -281,7 +289,7 @@ 0x0188d4,2, 0x0188e0,8, 0x018a04,3, -0x018a1c,4, +0x018a20,3, 0x018a30,4, 0x018a44,21, 0x018b00,16, @@ -291,16 +299,16 @@ 0x018c54,28, 0x018cd4,13, 0x018d0c,2, -0x018e00,3, +0x018e00,1, 0x018e10,2, 0x018e50,2, 0x018f00,4, 0x018f14,7, 0x018f38,5, 0x018f54,2, -0x018fa0,3, +0x018fa0,1, 0x018fb0,2, -0x018fc0,3, +0x018fc0,1, 0x018fd0,2, 0x018fe0,5, 0x019ff0,2052, @@ -308,9 +316,9 @@ 0x01c010,1, 0x01c01c,2, 0x01c06c,27, -0x01c180,3, +0x01c180,1, 0x01c190,2, -0x01c1a0,3, +0x01c1a0,1, 0x01c1b0,2, 0x01c1c0,7, 0x01c1e0,7, @@ -323,7 +331,6 @@ 0x01c434,1, 0x01c448,2, 0x01c454,1, -0x01c45c,1, 0x01c464,25, 0x01c4d8,2, 0x01c4e4,7, @@ -339,43 +346,53 @@ 0x01c75c,1, 0x01c7dc,1, 0x01c7e4,1, -0x01c7f8,15, +0x01c7f8,7, +0x01c818,7, 0x01c840,19, 0x01c8a0,5, 0x01c8c0,1, -0x01c900,13, +0x01c900,5, +0x01c918,7, 0x01c940,19, 0x01c9a0,5, 0x01c9c0,1, -0x01ca00,13, +0x01ca00,5, +0x01ca18,7, 0x01ca40,19, 0x01caa0,5, 0x01cac0,1, -0x01cb00,13, +0x01cb00,5, +0x01cb18,7, 0x01cb40,19, 0x01cba0,5, 0x01cbc0,1, -0x01cc00,13, +0x01cc00,5, +0x01cc18,7, 0x01cc40,19, 0x01cca0,5, 0x01ccc0,1, -0x01cd00,13, +0x01cd00,5, +0x01cd18,7, 0x01cd40,19, 0x01cda0,5, 0x01cdc0,1, -0x01ce00,13, +0x01ce00,5, +0x01ce18,7, 0x01ce40,19, 0x01cea0,5, 0x01cec0,1, -0x01cf00,13, +0x01cf00,5, +0x01cf18,7, 0x01cf40,19, 0x01cfa0,5, 0x01cfc0,1, 0x01d000,19, -0x01d054,30, +0x01d054,21, +0x01d0ac,6, 0x01d0d0,2, 0x01d0e8,15, -0x01d140,55, +0x01d140,1, +0x01d148,53, 0x01d220,12, 0x01d25c,6, 0x01d278,2, @@ -389,10 +406,12 @@ 0x01d3c0,5, 0x01d3e0,6, 0x01d400,19, -0x01d454,30, +0x01d454,21, +0x01d4ac,6, 0x01d4d0,2, 0x01d4e8,15, -0x01d540,55, +0x01d540,1, +0x01d548,53, 0x01d620,12, 0x01d65c,6, 0x01d678,2, @@ -405,24 +424,32 @@ 0x01d77c,6, 0x01d7c0,5, 0x01d7e0,6, -0x01d800,19, +0x01d800,16, +0x01d844,1, 0x01d880,8, 0x01d8c4,1, 0x01d8cc,5, 0x01d8e4,7, 0x01d920,1, -0x01d968,2, +0x01d968,3, 0x01d9e0,6, -0x01da00,7, +0x01da00,2, +0x01da14,2, +0x01da20,8, +0x01da44,1, +0x01da58,2, +0x01da64,1, +0x01da78,8, 0x01db04,1, -0x01db0c,16, +0x01db0c,14, 0x01db50,2, -0x01db60,3, +0x01db60,1, 0x01db70,2, -0x01db80,3, +0x01db80,1, 0x01db90,2, 0x01dba0,3, -0x01dc00,5, +0x01dc00,1, +0x01dc0c,1, 0x01dd80,13, 0x01ddbc,1, 0x01dde0,9, @@ -432,37 +459,43 @@ 0x01df38,1, 0x01df40,1, 0x01df54,2, -0x01dfa0,3, +0x01dfa0,1, 0x01dfb0,2, -0x01e5c0,3, +0x01e5c0,1, 0x01e5dc,1, 0x01e5e4,14, 0x01e620,4, -0x01e640,16, +0x01e668,6, 0x01e780,160, -0x01ea04,13, +0x01ea04,12, 0x01ec00,8, 0x01ec24,1, 0x01ec30,1, -0x01ec44,40, +0x01ec44,20, +0x01ec9c,2, +0x01ecac,14, 0x01ed80,1, 0x01edc4,1, -0x01ede0,5, +0x01ede0,1, +0x01ede8,3, 0x01edf8,1, 0x01ee00,8, 0x01ee24,1, 0x01ee30,1, -0x01ee44,40, +0x01ee44,20, +0x01ee9c,2, +0x01eeac,14, 0x01ef80,1, 0x01efc4,1, -0x01efe0,5, +0x01efe0,1, +0x01efe8,3, 0x01eff8,1, 0x01f000,1024, -0x030000,3, +0x030000,1, 0x030010,2, -0x030020,3, +0x030020,1, 0x030030,2, -0x030040,3, +0x030040,1, 0x030050,2, 0x030100,27, 0x030180,3, @@ -470,23 +503,22 @@ 0x030400,288, 0x030900,32, 0x030a04,1, -0x030b00,33, 0x030c00,128, 0x030e1c,1, 0x030e3c,1, 0x030e44,1, -0x030e5c,17, +0x030e5c,16, 0x030f10,28, 0x031000,14, 0x031040,14, 0x031080,14, 0x0310c0,14, -0x031100,147, -0x033000,1027, +0x031100,133, +0x031318,13, +0x033000,1025, 0x034010,2, 0x034104,1, 0x034224,1, -0x03422c,1, 0x034260,7, 0x034284,4, 0x034304,1, @@ -500,7 +532,7 @@ 0x034608,6, 0x034800,7, 0x034820,4, -0x034840,16, +0x034868,6, 0x034980,45, 0x034a40,13, 0x034a80,13, @@ -525,26 +557,29 @@ 0x035380,12, 0x0353c0,12, 0x036000,128, -0x036204,13, +0x036204,12, 0x036400,8, 0x036424,1, 0x036430,1, -0x036444,40, +0x036444,20, +0x03649c,2, +0x0364ac,14, 0x036580,1, 0x0365c4,1, -0x0365e0,5, +0x0365e0,1, +0x0365e8,3, 0x0365f8,1, 0x036600,4, 0x036614,6, 0x036638,3, 0x036654,2, -0x0366a0,3, +0x0366a0,1, 0x0366b0,2, -0x0366c0,3, +0x0366c0,1, 0x0366d0,2, -0x036700,3, +0x036700,1, 0x036710,2, -0x036720,3, +0x036720,1, 0x036730,2, 0x040000,19, 0x040050,3, @@ -617,34 +652,40 @@ 0x0411e4,15, 0x041224,1, 0x041230,1, -0x041244,40, +0x041244,20, +0x04129c,2, +0x0412ac,14, 0x041380,1, 0x0413c4,1, -0x0413e0,5, +0x0413e0,1, +0x0413e8,3, 0x0413f8,1, 0x041400,8, 0x041424,1, 0x041430,1, -0x041444,40, +0x041444,20, +0x04149c,2, +0x0414ac,14, 0x041580,1, 0x0415c4,1, -0x0415e0,5, +0x0415e0,1, +0x0415e8,3, 0x0415f8,1, 0x041600,4, 0x041614,7, 0x041638,4, 0x041654,2, -0x0416a0,3, +0x0416a0,1, 0x0416b0,2, -0x0416c0,3, +0x0416c0,1, 0x0416d0,2, 0x0416e0,1, -0x041a00,3, +0x041a00,1, 0x041a10,2, -0x041a20,3, +0x041a20,1, 0x041a30,2, 0x041c00,128, -0x041e04,13, +0x041e04,12, 0x042000,5, 0x042020,5, 0x042040,5, @@ -903,8 +944,7 @@ 0x043fe0,5, 0x044004,1, 0x044200,8, -0x044230,22, -0x044290,28, +0x044230,52, 0x044320,3, 0x044fc8,112, 0x045190,88, @@ -2588,7 +2628,7 @@ 0x060600,6, 0x060700,7, 0x060800,64, -0x060940,3, +0x060940,1, 0x060a04,7, 0x060c00,4, 0x060d00,2, @@ -2618,15 +2658,15 @@ 0x068014,7, 0x068038,4, 0x068054,2, -0x0680a0,3, +0x0680a0,1, 0x0680b0,2, -0x0680c0,3, +0x0680c0,1, 0x0680d0,2, 0x068800,7, 0x068820,4, -0x068840,16, +0x068868,6, 0x068980,33, -0x068a20,3, +0x068a20,1, 0x068a30,2, 0x068a80,2, 0x069000,4128, @@ -2637,7 +2677,8 @@ 0x07007c,13, 0x0700bc,6, 0x0700d8,5, -0x0700f0,23, +0x0700f0,20, +0x070144,1, 0x070180,5, 0x0701fc,1, 0x070210,12, @@ -2692,13 +2733,13 @@ 0x078100,17, 0x078180,17, 0x078210,5, -0x078240,3, -0x078250,3, -0x078260,3, -0x078270,3, +0x078240,1, +0x078250,1, +0x078260,1, +0x078270,1, 0x078284,2, 0x0782d4,59, -0x078400,6, +0x078400,2, 0x078420,1, 0x078600,96, 0x078a60,5, @@ -2708,11 +2749,10 @@ 0x078c20,10, 0x078c50,2, 0x078c5c,7, -0x078c80,5, +0x078c80,4, 0x078ca0,1, 0x078cc0,9, 0x078e60,1, -0x078e70,1, 0x078e80,10, 0x078ec0,2, 0x078ecc,1, @@ -3244,17 +3284,20 @@ 0x07bf80,2, 0x07bffc,1033, 0x07e000,1044, -0x07f100,36, +0x07f100,8, +0x07f160,4, 0x07f200,3, +0x07f300,20, +0x07f400,4, 0x07f7f8,514, 0x080680,7, 0x081000,3, 0x081010,21, -0x081120,3, +0x081120,1, 0x081130,2, -0x081140,3, +0x081140,1, 0x081150,2, -0x081160,3, +0x081160,1, 0x081170,2, 0x081204,18, 0x081304,2, @@ -3263,21 +3306,32 @@ 0x081468,6, 0x081504,2, 0x081604,14, -0x081640,128, +0x081640,2, +0x08164c,15, +0x08168c,15, +0x0816cc,15, +0x08170c,15, +0x08174c,15, +0x08178c,15, +0x0817cc,15, +0x08180c,13, 0x081904,5, 0x081a30,4, 0x081a60,18, 0x081ab0,3, 0x081ad0,4, 0x081c00,128, -0x081e04,13, +0x081e04,12, 0x082000,8, 0x082024,1, 0x082030,1, -0x082044,40, +0x082044,20, +0x08209c,2, +0x0820ac,14, 0x082180,1, 0x0821c4,1, -0x0821e0,5, +0x0821e0,1, +0x0821e8,3, 0x0821f8,1, 0x082200,10, 0x08229c,3, @@ -3302,17 +3356,18 @@ 0x083814,7, 0x083838,4, 0x083854,2, -0x0838a0,3, +0x0838a0,1, 0x0838b0,2, -0x0838c0,3, +0x0838c0,1, 0x0838d0,2, 0x083910,5, 0x083928,4, 0x083948,6, -0x0f0000,13, -0x0f0040,8, -0x0f0064,3, -0x0f0078,5, +0x0f0000,3, +0x0f0014,8, +0x0f0040,6, +0x0f0068,2, +0x0f0078,3, 0x0f0090,2, 0x0f00a4,2, 0x0f00b0,1, @@ -3321,8 +3376,9 @@ 0x0f01e0,4, 0x0f01f4,1, 0x0f0200,4, -0x0f0220,3, -0x0f0250,7, +0x0f0220,1, +0x0f0228,1, +0x0f0250,5, 0x0f0270,2, 0x0f0280,3, 0x0f02a4,5, @@ -3331,7 +3387,7 @@ 0x0f02f0,4, 0x0f0400,2, 0x0f0410,4, -0x0f0440,3, +0x0f0440,1, 0x0f0450,2, 0x0f0460,4, 0x0f0510,34, @@ -3340,18 +3396,26 @@ 0x0f1000,9, 0x0f107c,1, 0x0f2000,2, -0x0f2010,6, -0x0f2030,6, -0x0f2050,6, -0x0f2070,6, -0x0f2090,6, -0x0f20b0,6, -0x0f20d0,6, -0x0f20f0,7, -0x0f2110,8, -0x0f2134,22, +0x0f2010,3, +0x0f2020,2, +0x0f2030,3, +0x0f2040,2, +0x0f2050,3, +0x0f2060,2, +0x0f2070,3, +0x0f2080,2, +0x0f2090,3, +0x0f20a0,2, +0x0f20b0,3, +0x0f20c0,2, +0x0f20d0,3, +0x0f20e0,2, +0x0f20f0,3, +0x0f2100,3, +0x0f2110,25, +0x0f2178,3, 0x0f2190,2, -0x0f21a0,3, +0x0f21a0,1, 0x0f21b0,2, 0x0f21c0,2, 0x0f2200,3, @@ -3386,18 +3450,19 @@ 0x0f264c,8, 0x0f2670,2, 0x0f267c,17, -0x0f2700,11, +0x0f2700,9, +0x0f2728,1, 0x0f2804,2, -0x0f2840,3, +0x0f2844,2, 0x0f2868,2, 0x0f2874,1, -0x0f2880,3, +0x0f2884,2, 0x0f28a8,2, 0x0f28b4,1, -0x0f28c0,3, +0x0f28c4,2, 0x0f28e8,2, 0x0f28f4,1, -0x0f2900,3, +0x0f2904,2, 0x0f2928,2, 0x0f2934,1, 0x0f2a40,12, @@ -3413,7 +3478,23 @@ 0x0f2cc4,1, 0x0f2ccc,1, 0x0f2cd4,1, -0x0f2e00,172, +0x0f2e00,1, +0x0f2e08,7, +0x0f2e28,7, +0x0f2e48,7, +0x0f2e68,7, +0x0f2e88,7, +0x0f2ea8,7, +0x0f2ec8,7, +0x0f2ee8,7, +0x0f2f08,7, +0x0f2f28,7, +0x0f2f48,7, +0x0f2f68,7, +0x0f2f88,7, +0x0f2fa8,7, +0x0f2fc8,7, +0x0f2fe8,50, 0x0f30c0,13, 0x0f30fc,2, 0x0f310c,1, @@ -3421,7 +3502,7 @@ 0x0f3130,5, 0x0f3184,11, 0x0f31c4,3, -0x0f31e0,3, +0x0f31e0,1, 0x0f31f0,2, 0x0f3204,1, 0x0f3210,5, @@ -3440,63 +3521,65 @@ 0x0f35dc,7, 0x0f3600,18, 0x0f365c,11, -0x0f36a0,3, +0x0f36a0,1, 0x0f36b0,2, -0x0f36c0,3, +0x0f36c0,1, 0x0f36d0,2, -0x0f36e0,3, +0x0f36e0,1, 0x0f36f0,2, 0x0f3700,5, 0x0f371c,4, 0x0f3740,4, -0x0f3760,3, +0x0f3760,1, 0x0f3770,2, -0x0f3780,3, +0x0f3780,1, 0x0f3790,2, -0x0f37a0,3, +0x0f37a0,1, 0x0f37b0,2, -0x0f37c0,3, +0x0f37c0,1, 0x0f37d0,2, -0x0f37e0,3, +0x0f37e0,1, 0x0f37f0,2, 0x0f3800,3, 0x0f3810,18, 0x0f3878,6, 0x0f3894,3, -0x0f38c0,14, +0x0f38c0,7, +0x0f38e0,6, 0x0f3900,15, 0x0f3940,17, 0x0f3998,1, 0x0f39a0,9, -0x0f3a00,3, +0x0f3a00,1, 0x0f3a10,2, -0x0f3a20,3, +0x0f3a20,1, 0x0f3a30,2, -0x0f3a40,3, +0x0f3a40,1, 0x0f3a50,2, -0x0f3a60,3, +0x0f3a60,1, 0x0f3a70,2, -0x0f3a80,3, +0x0f3a80,1, 0x0f3a90,2, -0x0f3aa0,3, +0x0f3aa0,1, 0x0f3ab0,2, -0x0f3ac0,3, +0x0f3ac0,1, 0x0f3ad0,2, -0x0f3ae0,3, +0x0f3ae0,1, 0x0f3af0,2, -0x0f3b00,3, +0x0f3b00,1, 0x0f3b10,2, -0x0f3b20,3, +0x0f3b20,1, 0x0f3b30,2, -0x0f3b40,3, +0x0f3b40,1, 0x0f3b50,2, -0x0f3b60,3, +0x0f3b60,1, 0x0f3b70,2, -0x0f3b80,3, +0x0f3b80,1, 0x0f3b90,2, 0x0f3ba0,3, -0x0f3c00,20, -0x0f3c60,3, +0x0f3c00,12, +0x0f3c34,6, +0x0f3c60,1, 0x0f3c70,2, 0x0f3c84,3, 0x0f3d00,1, @@ -3506,7 +3589,7 @@ 0x0f3d38,1, 0x0f3d40,1, 0x0f3d54,2, -0x0f3da0,3, +0x0f3da0,1, 0x0f3db0,2, 0x0f3e00,76, 0x0f3f40,5, diff --git a/mstdump/mstdump_dbs/ConnectX3Pro.csv b/mstdump/mstdump_dbs/ConnectX3Pro.csv index 14408cb..f35e5dc 100755 --- a/mstdump/mstdump_dbs/ConnectX3Pro.csv +++ b/mstdump/mstdump_dbs/ConnectX3Pro.csv @@ -1,29 +1,29 @@ -# addr, size, enable addr +#Addr, Size, Enable addr 0x010000,2, 0x010010,2, 0x0100a0,15, 0x0100ec,2, -0x0100fc,3, +0x0100fc,2, 0x01010c,2, 0x010150,1, 0x0101cc,1, 0x0101fc,1, 0x010208,10, -0x010300,7, +0x010300,6, 0x010320,20, 0x010374,3, -0x010400,3, +0x010400,1, 0x010410,2, -0x010440,3, +0x010440,1, 0x010450,2, -0x010500,3, +0x010500,1, 0x010510,2, 0x010520,2, 0x01052c,3, 0x01053c,3, -0x010550,2, +0x010550,1, 0x010600,18, -0x010680,3, +0x010680,1, 0x010690,2, 0x0106ac,1, 0x0106b8,1, @@ -35,27 +35,27 @@ 0x010810,2, 0x0108a0,15, 0x0108ec,2, -0x0108fc,3, +0x0108fc,2, 0x01090c,2, 0x010950,1, 0x0109cc,1, 0x0109fc,1, 0x010a08,10, -0x010b00,7, +0x010b00,6, 0x010b20,20, 0x010b74,3, -0x010c00,3, +0x010c00,1, 0x010c10,2, -0x010c40,3, +0x010c40,1, 0x010c50,2, -0x010d00,3, +0x010d00,1, 0x010d10,2, 0x010d20,2, 0x010d2c,3, 0x010d3c,3, -0x010d50,2, +0x010d50,1, 0x010e00,18, -0x010e80,3, +0x010e80,1, 0x010e90,2, 0x010eac,1, 0x010eb8,1, @@ -74,9 +74,9 @@ 0x011240,4, 0x011260,1, 0x011280,5, -0x011300,3, +0x011300,1, 0x011310,2, -0x011400,4, +0x011400,6, 0x011460,1, 0x0114b0,4, 0x011800,1, @@ -90,16 +90,16 @@ 0x011a40,4, 0x011a60,1, 0x011a80,5, -0x011b00,3, +0x011b00,1, 0x011b10,2, -0x011c00,4, +0x011c00,6, 0x011c60,1, 0x011cb0,4, 0x012000,1, 0x01200c,1, -0x012020,3, +0x012020,1, 0x012030,2, -0x012040,3, +0x012044,2, 0x0120a0,4, 0x0120c0,7, 0x01211c,13, @@ -130,83 +130,104 @@ 0x01275c,1, 0x0127d8,2, 0x0127e8,2, -0x012840,3, +0x012840,1, 0x012850,2, -0x0128a0,5, +0x0128a0,6, 0x012904,1, 0x012910,5, 0x012928,4, -0x012944,9, -0x012980,4, -0x0129a0,3, +0x012944,2, +0x012950,1, +0x012958,4, +0x012980,7, +0x0129a0,1, 0x0129b0,2, 0x012d48,4, -0x013000,9, -0x013040,6, -0x013060,22, +0x013000,10, +0x013040,14, +0x013080,14, 0x0130c0,14, -0x013100,38, -0x0131a0,6, -0x0131c0,6, -0x0131e0,6, -0x013200,38, -0x0132a0,6, -0x0132c0,6, -0x0132e0,6, -0x013300,11, +0x013100,37, +0x013198,1, +0x0131a0,5, +0x0131b8,1, +0x0131c0,5, +0x0131d8,1, +0x0131e0,5, +0x0131f8,1, +0x013200,37, +0x013298,1, +0x0132a0,5, +0x0132b8,1, +0x0132c0,5, +0x0132d8,1, +0x0132e0,5, +0x0132f8,1, +0x013300,9, 0x013330,2, -0x013340,3, +0x013340,1, 0x013350,2, -0x013360,3, +0x013360,1, 0x013370,2, -0x013380,43, +0x013380,2, +0x01338c,38, 0x013430,2, -0x013440,3, +0x013440,1, 0x013450,2, -0x013460,3, +0x013460,1, 0x013470,2, -0x013480,35, +0x013480,2, +0x01348c,30, 0x013510,2, -0x013520,3, +0x013520,1, 0x013530,2, -0x013540,3, +0x013544,2, 0x013580,8, 0x0135a4,6, -0x0135c0,19, +0x0135c0,16, +0x013604,2, 0x013628,2, 0x013634,1, -0x013640,3, +0x013644,2, 0x013668,2, 0x013674,1, -0x013680,3, +0x013684,2, 0x0136a8,2, 0x0136b4,1, -0x0136c0,3, +0x0136c4,2, 0x0136e8,2, 0x0136f4,1, 0x013700,21, +0x013760,1, +0x013770,2, +0x013780,1, +0x013790,2, +0x0137a0,1, +0x0137b0,2, 0x013800,1, 0x013820,2, 0x01382c,10, -0x01386c,16, +0x01386c,10, +0x013898,3, 0x0138b0,2, 0x013a00,1, 0x013a20,2, 0x013a2c,10, -0x013a6c,16, +0x013a6c,10, +0x013a98,3, 0x013ab0,2, 0x013c00,4, 0x013c14,7, 0x013c38,4, 0x013c54,2, -0x013ca0,3, +0x013ca0,1, 0x013cb0,2, -0x013cc0,3, +0x013cc0,1, 0x013cd0,2, 0x013d00,3, 0x013d10,6, 0x013d44,7, -0x013d64,10, +0x013d64,8, 0x013d90,2, 0x013da0,6, 0x013e00,1, @@ -222,7 +243,7 @@ 0x014158,1, 0x014180,1, 0x014194,2, -0x0141ac,11, +0x0141ac,12, 0x0141ec,4, 0x014200,3, 0x014210,15, @@ -236,20 +257,28 @@ 0x014358,1, 0x014380,1, 0x014394,2, -0x0143ac,11, +0x0143ac,12, 0x0143ec,4, -0x014400,11, +0x014400,12, 0x01444c,8, 0x014470,2, 0x01447c,33, -0x014800,14, -0x014840,14, -0x014880,14, -0x0148c0,14, -0x014900,14, -0x014940,14, -0x014980,14, -0x0149c0,14, +0x014800,8, +0x014824,5, +0x014840,8, +0x014864,5, +0x014880,8, +0x0148a4,5, +0x0148c0,8, +0x0148e4,5, +0x014900,8, +0x014924,5, +0x014940,8, +0x014964,5, +0x014980,8, +0x0149a4,5, +0x0149c0,8, +0x0149e4,5, 0x014a04,5, 0x018000,2, 0x01805c,4, @@ -291,7 +320,7 @@ 0x0188d4,2, 0x0188e0,8, 0x018a04,3, -0x018a1c,4, +0x018a20,3, 0x018a30,4, 0x018a44,21, 0x018b00,16, @@ -301,16 +330,16 @@ 0x018c54,28, 0x018cd4,13, 0x018d0c,2, -0x018e00,3, +0x018e00,1, 0x018e10,2, 0x018e50,2, 0x018f00,4, 0x018f14,7, 0x018f38,5, 0x018f54,2, -0x018fa0,3, +0x018fa0,1, 0x018fb0,2, -0x018fc0,3, +0x018fc0,1, 0x018fd0,2, 0x018fe0,5, 0x019ff0,2052, @@ -318,25 +347,22 @@ 0x01c010,1, 0x01c01c,2, 0x01c06c,27, -0x01c180,3, +0x01c180,1, 0x01c190,2, -0x01c1a0,3, +0x01c1a0,1, 0x01c1b0,2, -0x01c1c0,7, -0x01c1e0,7, -0x01c200,17, +0x01c1c0,33, 0x01c254,28, 0x01c2d4,13, 0x01c30c,2, 0x01c40c,5, 0x01c428,2, -0x01c434,1, +0x01c434,2, 0x01c448,2, 0x01c454,1, -0x01c45c,1, 0x01c464,25, 0x01c4d8,2, -0x01c4e4,7, +0x01c4e4,12, 0x01c608,4, 0x01c624,3, 0x01c63c,1, @@ -349,43 +375,61 @@ 0x01c75c,1, 0x01c7dc,1, 0x01c7e4,1, -0x01c7f8,15, -0x01c840,19, +0x01c7f8,7, +0x01c818,7, +0x01c840,2, +0x01c84c,16, 0x01c8a0,5, 0x01c8c0,1, -0x01c900,13, -0x01c940,19, +0x01c900,5, +0x01c918,7, +0x01c940,2, +0x01c94c,16, 0x01c9a0,5, 0x01c9c0,1, -0x01ca00,13, -0x01ca40,19, +0x01ca00,5, +0x01ca18,7, +0x01ca40,2, +0x01ca4c,16, 0x01caa0,5, 0x01cac0,1, -0x01cb00,13, -0x01cb40,19, +0x01cb00,5, +0x01cb18,7, +0x01cb40,2, +0x01cb4c,16, 0x01cba0,5, 0x01cbc0,1, -0x01cc00,13, -0x01cc40,19, +0x01cc00,5, +0x01cc18,7, +0x01cc40,2, +0x01cc4c,16, 0x01cca0,5, 0x01ccc0,1, -0x01cd00,13, -0x01cd40,19, +0x01cd00,5, +0x01cd18,7, +0x01cd40,2, +0x01cd4c,16, 0x01cda0,5, 0x01cdc0,1, -0x01ce00,13, -0x01ce40,19, +0x01ce00,5, +0x01ce18,7, +0x01ce40,2, +0x01ce4c,16, 0x01cea0,5, 0x01cec0,1, -0x01cf00,13, -0x01cf40,19, +0x01cf00,5, +0x01cf18,7, +0x01cf40,2, +0x01cf4c,16, 0x01cfa0,5, 0x01cfc0,1, 0x01d000,19, -0x01d054,30, +0x01d054,21, +0x01d0ac,6, 0x01d0d0,2, 0x01d0e8,15, -0x01d140,55, +0x01d140,1, +0x01d148,53, 0x01d220,12, 0x01d25c,6, 0x01d278,2, @@ -393,16 +437,20 @@ 0x01d298,2, 0x01d2a8,6, 0x01d300,2, -0x01d310,20, -0x01d368,2, +0x01d310,11, +0x01d350,4, +0x01d368,3, 0x01d37c,6, -0x01d3c0,5, +0x01d3a0,3, +0x01d3b0,9, 0x01d3e0,6, 0x01d400,19, -0x01d454,30, +0x01d454,21, +0x01d4ac,6, 0x01d4d0,2, 0x01d4e8,15, -0x01d540,55, +0x01d540,1, +0x01d548,53, 0x01d620,12, 0x01d65c,6, 0x01d678,2, @@ -410,12 +458,15 @@ 0x01d698,2, 0x01d6a8,6, 0x01d700,2, -0x01d710,20, -0x01d768,2, +0x01d710,11, +0x01d750,4, +0x01d768,3, 0x01d77c,6, -0x01d7c0,5, +0x01d7a0,3, +0x01d7b0,9, 0x01d7e0,6, -0x01d800,19, +0x01d800,16, +0x01d844,1, 0x01d880,8, 0x01d8c4,1, 0x01d8cc,5, @@ -424,89 +475,96 @@ 0x01d968,3, 0x01d9e0,6, 0x01da00,2, -0x01da10,3, +0x01da14,2, 0x01da20,8, 0x01da44,1, 0x01da58,2, 0x01da64,1, 0x01da78,8, 0x01db04,1, -0x01db0c,16, +0x01db0c,14, 0x01db50,2, -0x01db60,3, +0x01db60,1, 0x01db70,2, -0x01db80,3, +0x01db80,1, 0x01db90,2, 0x01dba0,3, -0x01dc00,5, +0x01dc00,1, +0x01dc0c,1, +0x01dc80,6, +0x01dca0,1, 0x01dd80,13, 0x01ddbc,1, 0x01dde0,9, 0x01df00,1, 0x01df08,1, -0x01df14,5, +0x01df14,1, +0x01df1c,3, 0x01df38,1, 0x01df40,1, 0x01df54,2, -0x01dfa0,3, +0x01dfa0,1, 0x01dfb0,2, -0x01e5c0,3, +0x01e5c0,1, 0x01e5dc,1, 0x01e5e4,14, 0x01e620,4, -0x01e640,16, +0x01e668,6, 0x01e780,160, -0x01ea04,13, +0x01ea04,12, 0x01ec00,8, 0x01ec24,1, 0x01ec30,1, -0x01ec44,40, +0x01ec44,20, +0x01ec9c,2, +0x01ecac,14, 0x01ed80,1, 0x01edc4,1, -0x01ede0,5, +0x01ede0,1, +0x01ede8,3, 0x01edf8,1, 0x01ee00,8, 0x01ee24,1, 0x01ee30,1, -0x01ee44,40, +0x01ee44,20, +0x01ee9c,2, +0x01eeac,14, 0x01ef80,1, 0x01efc4,1, -0x01efe0,5, +0x01efe0,1, +0x01efe8,3, 0x01eff8,1, 0x01f000,1024, -0x030000,3, +0x030000,1, 0x030010,2, -0x030020,3, +0x030020,1, 0x030030,2, -0x030040,3, +0x030040,1, 0x030050,2, 0x030100,27, 0x030180,3, 0x030200,80, -0x030400,288, -0x030900,32, -0x030a04,1, -0x030b00,33, 0x030c00,128, 0x030e1c,1, 0x030e3c,1, 0x030e44,1, -0x030e5c,17, -0x030f10,28, +0x030e5c,16, +0x030f10,4, +0x030f40,32, 0x031000,14, 0x031040,14, 0x031080,14, 0x0310c0,14, -0x031100,147, -0x033000,463, -0x03374c,214, -0x033aa8,214, -0x033e04,84, -0x033f94,30, +0x031100,133, +0x031318,13, +0x031a00,64, +0x031c00,64, +0x031e04,1, +0x032000,512, +0x033000,1025, 0x034010,2, 0x034104,1, 0x034224,1, -0x03422c,1, 0x034260,7, 0x034284,4, 0x034304,1, @@ -520,7 +578,7 @@ 0x034608,6, 0x034800,7, 0x034820,4, -0x034840,16, +0x034868,6, 0x034980,45, 0x034a40,13, 0x034a80,13, @@ -545,26 +603,29 @@ 0x035380,12, 0x0353c0,12, 0x036000,128, -0x036204,13, +0x036204,12, 0x036400,8, 0x036424,1, 0x036430,1, -0x036444,40, +0x036444,20, +0x03649c,2, +0x0364ac,14, 0x036580,1, 0x0365c4,1, -0x0365e0,5, +0x0365e0,1, +0x0365e8,3, 0x0365f8,1, 0x036600,4, 0x036614,6, 0x036638,3, 0x036654,2, -0x0366a0,3, +0x0366a0,1, 0x0366b0,2, -0x0366c0,3, +0x0366c0,1, 0x0366d0,2, -0x036700,3, +0x036700,1, 0x036710,2, -0x036720,3, +0x036720,1, 0x036730,2, 0x040000,19, 0x040050,3, @@ -608,7 +669,7 @@ 0x04056c,3, 0x04057c,3, 0x04058c,2, -0x04059c,17, +0x04059c,18, 0x040610,16, 0x0406e0,51, 0x0407d0,3, @@ -636,34 +697,40 @@ 0x0411e4,15, 0x041224,1, 0x041230,1, -0x041244,40, +0x041244,20, +0x04129c,2, +0x0412ac,14, 0x041380,1, 0x0413c4,1, -0x0413e0,5, +0x0413e0,1, +0x0413e8,3, 0x0413f8,1, 0x041400,8, 0x041424,1, 0x041430,1, -0x041444,40, +0x041444,20, +0x04149c,2, +0x0414ac,14, 0x041580,1, 0x0415c4,1, -0x0415e0,5, +0x0415e0,1, +0x0415e8,3, 0x0415f8,1, 0x041600,4, 0x041614,7, 0x041638,4, 0x041654,2, -0x0416a0,3, +0x0416a0,1, 0x0416b0,2, -0x0416c0,3, +0x0416c0,1, 0x0416d0,2, 0x0416e0,1, -0x041a00,3, +0x041a00,1, 0x041a10,2, -0x041a20,3, +0x041a20,1, 0x041a30,2, 0x041c00,128, -0x041e04,13, +0x041e04,12, 0x042000,5, 0x042020,5, 0x042040,5, @@ -920,25 +987,22 @@ 0x043fa0,5, 0x043fc0,5, 0x043fe0,5, -0x044004,31, -0x044088,6, -0x0440a4,4, -0x0440c4,3, -0x0440d4,2, -0x0440e4,3, -0x0440f4,5, +0x044004,32, +0x04408c,6, +0x0440a8,4, +0x0440c8,3, +0x0440d8,2, +0x0440e8,3, +0x0440f8,5, 0x044200,8, -0x044230,52, +0x044240,48, 0x044320,3, 0x044ec8,4, 0x044fc8,202, 0x045300,48, -0x045400,13, -0x045440,9, +0x045400,25, 0x045468,22, -0x046480,2, -0x046490,6, -0x0464b4,10, +0x046480,23, 0x047000,60, 0x047ff0,2, 0x048000,5, @@ -2610,17 +2674,14 @@ 0x05bfe8,1, 0x05bff0,1, 0x05bff8,1, -0x05c000,800, -0x05cc8c,69, -0x05ce38,109, -0x05cff0,4, +0x05c000,1024, 0x060400,5, 0x060500,6, 0x060520,6, 0x060600,6, 0x060700,7, 0x060800,64, -0x060940,3, +0x060940,1, 0x060a04,7, 0x060c00,4, 0x060d00,2, @@ -2650,15 +2711,15 @@ 0x068014,7, 0x068038,4, 0x068054,2, -0x0680a0,3, +0x0680a0,1, 0x0680b0,2, -0x0680c0,3, +0x0680c0,1, 0x0680d0,2, 0x068800,7, 0x068820,4, -0x068840,16, +0x068868,6, 0x068980,33, -0x068a20,3, +0x068a20,1, 0x068a30,2, 0x068a80,2, 0x069000,4128, @@ -2669,7 +2730,8 @@ 0x07007c,13, 0x0700bc,6, 0x0700d8,5, -0x0700f0,23, +0x0700f0,20, +0x070144,1, 0x070180,5, 0x0701fc,1, 0x070210,12, @@ -2724,13 +2786,13 @@ 0x078100,17, 0x078180,17, 0x078210,5, -0x078240,3, -0x078250,3, -0x078260,3, -0x078270,3, +0x078240,1, +0x078250,1, +0x078260,1, +0x078270,1, 0x078284,2, 0x0782d4,59, -0x078400,6, +0x078400,2, 0x078420,1, 0x078600,96, 0x078a60,5, @@ -2740,11 +2802,10 @@ 0x078c20,10, 0x078c50,2, 0x078c5c,7, -0x078c80,5, +0x078c80,4, 0x078ca0,1, 0x078cc0,9, 0x078e60,1, -0x078e70,1, 0x078e80,10, 0x078ec0,2, 0x078ecc,1, @@ -3276,44 +3337,55 @@ 0x07bf80,2, 0x07bffc,1033, 0x07e000,1044, -0x07f100,36, +0x07f100,8, +0x07f160,4, 0x07f200,3, 0x07f300,20, 0x07f400,4, -0x07f500,4, -0x07f600,4, 0x07f7f8,514, 0x080680,7, 0x081000,3, 0x081010,21, -0x081120,3, +0x081104,2, +0x081120,1, 0x081130,2, -0x081140,3, +0x081140,1, 0x081150,2, -0x081160,3, +0x081160,1, 0x081170,2, -0x081204,18, +0x081204,21, 0x081304,2, 0x08139c,25, 0x081404,23, 0x081468,6, 0x081504,2, 0x081604,14, -0x081640,128, +0x081640,2, +0x08164c,15, +0x08168c,15, +0x0816cc,15, +0x08170c,15, +0x08174c,15, +0x08178c,15, +0x0817cc,15, +0x08180c,13, 0x081904,5, 0x081a30,4, 0x081a60,18, 0x081ab0,3, 0x081ad0,4, 0x081c00,128, -0x081e04,13, +0x081e04,12, 0x082000,8, 0x082024,1, 0x082030,1, -0x082044,40, +0x082044,20, +0x08209c,2, +0x0820ac,14, 0x082180,1, 0x0821c4,1, -0x0821e0,5, +0x0821e0,1, +0x0821e8,3, 0x0821f8,1, 0x082200,10, 0x08229c,3, @@ -3338,17 +3410,18 @@ 0x083814,7, 0x083838,4, 0x083854,2, -0x0838a0,3, +0x0838a0,1, 0x0838b0,2, -0x0838c0,3, +0x0838c0,1, 0x0838d0,2, 0x083910,5, 0x083928,4, 0x083948,6, -0x0f0000,13, -0x0f0040,8, -0x0f0064,3, -0x0f0078,5, +0x0f0000,3, +0x0f0014,8, +0x0f0040,6, +0x0f0068,2, +0x0f0078,3, 0x0f0090,2, 0x0f00a4,2, 0x0f00b0,1, @@ -3357,8 +3430,9 @@ 0x0f01e0,4, 0x0f01f4,1, 0x0f0200,4, -0x0f0220,3, -0x0f0250,7, +0x0f0220,1, +0x0f0228,1, +0x0f0250,5, 0x0f0270,2, 0x0f0280,3, 0x0f02a4,5, @@ -3367,7 +3441,7 @@ 0x0f02f0,4, 0x0f0400,2, 0x0f0410,4, -0x0f0440,3, +0x0f0440,1, 0x0f0450,2, 0x0f0460,4, 0x0f0510,34, @@ -3376,17 +3450,26 @@ 0x0f1000,9, 0x0f107c,1, 0x0f2000,2, -0x0f2010,6, -0x0f2030,6, -0x0f2050,6, -0x0f2070,6, -0x0f2090,6, -0x0f20b0,6, -0x0f20d0,6, -0x0f20f0,7, -0x0f2110,31, +0x0f2010,3, +0x0f2020,2, +0x0f2030,3, +0x0f2040,2, +0x0f2050,3, +0x0f2060,2, +0x0f2070,3, +0x0f2080,2, +0x0f2090,3, +0x0f20a0,2, +0x0f20b0,3, +0x0f20c0,2, +0x0f20d0,3, +0x0f20e0,2, +0x0f20f0,3, +0x0f2100,3, +0x0f2110,25, +0x0f2178,3, 0x0f2190,2, -0x0f21a0,3, +0x0f21a0,1, 0x0f21b0,2, 0x0f21c0,2, 0x0f2200,3, @@ -3401,7 +3484,7 @@ 0x0f2358,1, 0x0f2380,1, 0x0f2394,2, -0x0f23ac,11, +0x0f23ac,12, 0x0f23ec,4, 0x0f2400,3, 0x0f2410,15, @@ -3415,24 +3498,25 @@ 0x0f2558,1, 0x0f2580,1, 0x0f2594,2, -0x0f25ac,11, +0x0f25ac,12, 0x0f25ec,4, -0x0f2600,11, +0x0f2600,12, 0x0f264c,8, 0x0f2670,2, 0x0f267c,17, -0x0f2700,11, -0x0f2800,3, -0x0f2840,3, +0x0f2700,9, +0x0f2728,1, +0x0f2804,2, +0x0f2844,2, 0x0f2868,2, 0x0f2874,1, -0x0f2880,3, +0x0f2884,2, 0x0f28a8,2, 0x0f28b4,1, -0x0f28c0,3, +0x0f28c4,2, 0x0f28e8,2, 0x0f28f4,1, -0x0f2900,3, +0x0f2904,2, 0x0f2928,2, 0x0f2934,1, 0x0f2a40,12, @@ -3448,7 +3532,23 @@ 0x0f2cc4,1, 0x0f2ccc,1, 0x0f2cd4,1, -0x0f2e00,172, +0x0f2e00,1, +0x0f2e08,7, +0x0f2e28,7, +0x0f2e48,7, +0x0f2e68,7, +0x0f2e88,7, +0x0f2ea8,7, +0x0f2ec8,7, +0x0f2ee8,7, +0x0f2f08,7, +0x0f2f28,7, +0x0f2f48,7, +0x0f2f68,7, +0x0f2f88,7, +0x0f2fa8,7, +0x0f2fc8,7, +0x0f2fe8,50, 0x0f30c0,13, 0x0f30fc,2, 0x0f310c,1, @@ -3456,7 +3556,7 @@ 0x0f3130,5, 0x0f3184,11, 0x0f31c4,3, -0x0f31e0,3, +0x0f31e0,1, 0x0f31f0,2, 0x0f3204,1, 0x0f3210,5, @@ -3475,64 +3575,66 @@ 0x0f35dc,7, 0x0f3600,18, 0x0f365c,11, -0x0f36a0,3, +0x0f36a0,1, 0x0f36b0,2, -0x0f36c0,3, +0x0f36c0,1, 0x0f36d0,2, -0x0f36e0,3, +0x0f36e0,1, 0x0f36f0,2, 0x0f3700,5, 0x0f371c,4, 0x0f3740,4, -0x0f3760,3, +0x0f3760,1, 0x0f3770,2, -0x0f3780,3, +0x0f3780,1, 0x0f3790,2, -0x0f37a0,3, +0x0f37a0,1, 0x0f37b0,2, -0x0f37c0,3, +0x0f37c0,1, 0x0f37d0,2, -0x0f37e0,3, +0x0f37e0,1, 0x0f37f0,2, 0x0f3800,3, 0x0f3810,18, 0x0f3878,6, 0x0f3894,3, -0x0f38c0,14, +0x0f38c0,7, +0x0f38e0,6, 0x0f3900,8, 0x0f3924,6, 0x0f3940,17, 0x0f3998,1, 0x0f39a0,9, -0x0f3a00,3, +0x0f3a00,1, 0x0f3a10,2, -0x0f3a20,3, +0x0f3a20,1, 0x0f3a30,2, -0x0f3a40,3, +0x0f3a40,1, 0x0f3a50,2, -0x0f3a60,3, +0x0f3a60,1, 0x0f3a70,2, -0x0f3a80,3, +0x0f3a80,1, 0x0f3a90,2, -0x0f3aa0,3, +0x0f3aa0,1, 0x0f3ab0,2, -0x0f3ac0,3, +0x0f3ac0,1, 0x0f3ad0,2, -0x0f3ae0,3, +0x0f3ae0,1, 0x0f3af0,2, -0x0f3b00,3, +0x0f3b00,1, 0x0f3b10,2, -0x0f3b20,3, +0x0f3b20,1, 0x0f3b30,2, -0x0f3b40,3, +0x0f3b40,1, 0x0f3b50,2, -0x0f3b60,3, +0x0f3b60,1, 0x0f3b70,2, -0x0f3b80,3, +0x0f3b80,1, 0x0f3b90,2, 0x0f3ba0,3, -0x0f3c00,20, -0x0f3c60,3, +0x0f3c00,12, +0x0f3c34,6, +0x0f3c60,1, 0x0f3c70,2, 0x0f3c84,3, 0x0f3d00,1, @@ -3542,7 +3644,7 @@ 0x0f3d38,1, 0x0f3d40,1, 0x0f3d54,2, -0x0f3da0,3, +0x0f3da0,1, 0x0f3db0,2, 0x0f3e00,76, 0x0f3f40,5, diff --git a/mstdump/mstdump_dbs/InfiniHost.csv b/mstdump/mstdump_dbs/InfiniHost.csv deleted file mode 100755 index 286d148..0000000 --- a/mstdump/mstdump_dbs/InfiniHost.csv +++ /dev/null @@ -1,494 +0,0 @@ -# addr, size, enable addr -0x010000,14, -0x010050,4, -0x010070,4, -0x01009c,9, -0x0100d8,3, -0x0100e8,1, -0x0100f0,1, -0x0100f8,3, -0x01010c,20, -0x010164,1, -0x01017c,1, -0x010188,1, -0x010194,3, -0x010230,2, -0x010240,9, -0x010270,2, -0x010280,16, -0x0102f8,3, -0x010308,1, -0x010310,1, -0x010318,1, -0x010320,1, -0x010328,1, -0x010330,1, -0x010338,1, -0x010340,1, -0x010348,1, -0x010350,1, -0x010358,1, -0x010360,1, -0x010368,1, -0x010370,1, -0x010378,1, -0x010390,13, -0x0103cc,1, -0x0103dc,2, -0x0103e8,1, -0x0103f0,1, -0x0103f8,2, -0x010800,14, -0x010850,4, -0x010870,4, -0x01089c,9, -0x0108d8,3, -0x0108e8,1, -0x0108f0,1, -0x0108f8,3, -0x01090c,20, -0x010964,1, -0x01097c,1, -0x010988,1, -0x010994,3, -0x010a30,2, -0x010a40,9, -0x010a70,2, -0x010a80,16, -0x010af8,3, -0x010b08,1, -0x010b10,1, -0x010b18,1, -0x010b20,1, -0x010b28,1, -0x010b30,1, -0x010b38,1, -0x010b40,1, -0x010b48,1, -0x010b50,1, -0x010b58,1, -0x010b60,1, -0x010b68,1, -0x010b70,1, -0x010b78,1, -0x010b90,13, -0x010bcc,1, -0x010bdc,2, -0x010be8,1, -0x010bf0,1, -0x010bf8,2, -0x040000,4, -0x040020,4, -0x040040,4, -0x040060,4, -0x040100,5, -0x040180,1, -0x04018c,3, -0x040200,35, -0x040400,17, -0x042004,5, -0x042024,8, -0x042210,1, -0x042310,3, -0x042350,4, -0x042380,1, -0x04238c,3, -0x0423c0,4, -0x042400,5, -0x042420,5, -0x04243c,11, -0x042500,20, -0x044000,7, -0x044024,1, -0x044070,7, -0x0440a0,1, -0x0440ac,9, -0x044180,1, -0x0441e0,5, -0x0441f8,1, -0x044200,7, -0x044224,1, -0x044270,7, -0x0442a0,1, -0x0442ac,9, -0x044380,1, -0x0443e0,5, -0x0443f8,1, -0x044500,4, -0x044520,4, -0x044540,2, -0x044604,45, -0x044704,45, -0x044b00,26, -0x044f00,1, -0x044f20,1, -0x044f40,1, -0x045100,4, -0x045210,3, -0x045260,1, -0x045284,4, -0x045300,1, -0x04530c,3, -0x045340,8, -0x045380,2, -0x045390,1, -0x045398,2, -0x045400,128, -0x045800,256, -0x046000,2, -0x04600c,3, -0x046020,5, -0x046080,5, -0x046100,2, -0x04610c,3, -0x046120,5, -0x046180,5, -0x046200,2, -0x04620c,3, -0x046220,5, -0x046280,5, -0x046300,2, -0x04630c,3, -0x046320,5, -0x046380,5, -0x046400,2, -0x04640c,3, -0x046420,5, -0x046480,5, -0x046500,2, -0x04650c,3, -0x046520,5, -0x046580,5, -0x046600,2, -0x04660c,3, -0x046620,5, -0x046680,5, -0x046700,2, -0x04670c,3, -0x046720,5, -0x046780,5, -0x046800,2, -0x04680c,3, -0x046820,5, -0x046880,5, -0x046900,2, -0x04690c,3, -0x046920,5, -0x046980,5, -0x046a00,2, -0x046a0c,3, -0x046a20,5, -0x046a80,5, -0x046b00,2, -0x046b0c,3, -0x046b20,5, -0x046b80,5, -0x046c00,2, -0x046c0c,3, -0x046c20,5, -0x046c80,5, -0x046d00,2, -0x046d0c,3, -0x046d20,5, -0x046d80,5, -0x046e00,2, -0x046e0c,3, -0x046e20,5, -0x046e80,5, -0x046f00,2, -0x046f0c,3, -0x046f20,5, -0x046f80,5, -0x04c000,7, -0x04c024,1, -0x04c070,7, -0x04c0a0,1, -0x04c0ac,9, -0x04c180,1, -0x04c1e0,5, -0x04c1f8,1, -0x04c300,5, -0x04c340,5, -0x04c380,7, -0x04c500,16, -0x04c560,16, -0x04c5b0,6, -0x04c5d0,7, -0x04c5f0,4, -0x04c700,34, -0x04c790,14, -0x04c800,256, -0x04d004,45, -0x04d130,1, -0x04d140,12, -0x04d200,51, -0x04d500,9, -0x04d540,7, -0x04d560,3, -0x04d570,2, -0x04d580,3, -0x04d590,4, -0x04d5e4,3, -0x04d600,6, -0x04d620,10, -0x04d800,128, -0x04dc00,1, -0x04dc0c,3, -0x04dc24,4, -0x04dc44,3, -0x04dd00,15, -0x04de00,15, -0x04dff8,578, -0x080000,7, -0x080024,1, -0x080070,7, -0x0800a0,1, -0x0800ac,9, -0x080180,1, -0x0801e0,5, -0x0801f8,1, -0x080200,2, -0x080240,3, -0x080250,2, -0x080280,19, -0x0802d4,10, -0x080300,8, -0x080380,1, -0x080400,1, -0x080500,1, -0x080600,1, -0x08060c,3, -0x080640,1, -0x080680,7, -0x080700,2, -0x081000,9, -0x081040,9, -0x081080,2, -0x0810c0,2, -0x0810d0,2, -0x081100,2, -0x081110,2, -0x081410,7, -0x081440,1, -0x081500,64, -0x081800,28, -0x082000,1024, -0x086000,2, -0x08600c,8, -0x086030,2, -0x086040,1, -0x08604c,3, -0x0860a0,3, -0x0860b0,3, -0x0860e8,3, -0x086100,2, -0x086130,3, -0x086160,3, -0x086180,1, -0x0861a0,10, -0x0861d0,2, -0x088000,7, -0x088024,1, -0x088070,7, -0x0880a0,1, -0x0880ac,9, -0x088180,1, -0x0881e0,5, -0x0881f8,1, -0x088280,1, -0x08828c,3, -0x088300,1, -0x088340,1, -0x088380,1, -0x088404,5, -0x088424,5, -0x088474,3, -0x088498,2, -0x0884e0,4, -0x088504,5, -0x088524,5, -0x088574,3, -0x088598,2, -0x0885e0,4, -0x088604,5, -0x088624,5, -0x088674,3, -0x088698,2, -0x0886e0,4, -0x088700,1, -0x088708,4, -0x088780,3, -0x088810,7, -0x088840,1, -0x088900,64, -0x088b00,3, -0x088b10,3, -0x088b20,3, -0x088b30,3, -0x088b80,1, -0x088c00,111, -0x088e90,2, -0x08c000,2, -0x08c010,9, -0x08c040,3, -0x08c084,4, -0x08c100,1, -0x08c10c,3, -0x0f0000,2, -0x0f0010,8, -0x0f0040,9, -0x0f0080,10, -0x0f00b8,4, -0x0f0100,2, -0x0f0118,4, -0x0f0134,13, -0x0f0180,4, -0x0f01a0,3, -0x0f01c0,6, -0x0f01e0,4, -0x0f0200,8, -0x0f0240,1, -0x0f0500,9, -0x0f3000,9, -0x0f3040,3, -0x0f3054,3, -0x0f3070,1, -0x0f3084,6, -0x0f3200,9, -0x0f3240,9, -0x0f3280,2, -0x0f32c0,2, -0x0f32d0,2, -0x0f3300,2, -0x0f3310,2, -0x0f3484,4, -0x0f34c0,16, -0x0f3504,4, -0x0f3540,16, -0x0f3584,3, -0x0f3600,8, -0x0f3640,4, -0x0f3680,7, -0x0f3800,1, -0x0f380c,3, -0x0f3820,1, -0x0f382c,3, -0x0f3840,2, -0x0f3850,2, -0x0f5000,3, -0x0f5020,2, -0x0f50a0,2, -0x0f5100,1, -0x0f510c,3, -0x0f5200,1, -0x0f5240,1, -0x0f5284,2, -0x0f52c0,1, -0x0f5300,4, -0x0f5340,4, -0x0f5380,4, -0x0f53c0,4, -0x0f5800,7, -0x0f5900,1, -0x0f5910,16, -0x0f5a00,1, -0x0f5a40,1, -0x0f5a50,2, -0x0f5a60,1, -0x0f5a80,1, -0x0f5a90,2, -0x0f5aa0,1, -0x0f5ab0,2, -0x0f5ac0,1, -0x0f5ad0,2, -0x0f5ae0,1, -0x0f5af0,2, -0x0f5b04,3, -0x0f5b18,6, -0x0f5b6c,5, -0x0f5c00,65, -0x0f5d08,1, -0x0f5d10,1, -0x0f5d18,1, -0x0f5d20,1, -0x0f5d28,1, -0x0f5d30,1, -0x0f5d38,1, -0x0f5d40,1, -0x0f5d48,1, -0x0f5d50,1, -0x0f5d58,1, -0x0f5d60,1, -0x0f5d68,1, -0x0f5d70,1, -0x0f5d78,1, -0x0f5d80,1, -0x0f5d88,1, -0x0f5da0,1, -0x0f5db0,1, -0x0f5dc0,1, -0x0f5dd0,1, -0x0f5de0,1, -0x0f5df0,1, -0x0f5e00,1, -0x0f5e10,1, -0x0f5e20,1, -0x0f5e30,1, -0x0f5e40,1, -0x0f5e50,1, -0x0f5e60,1, -0x0f5e70,1, -0x0f5e80,1, -0x0f5e90,1, -0x0f5ea0,1, -0x0f5eb0,1, -0x0f5f00,1, -0x0f5f08,1, -0x0f5f10,1, -0x0f5f18,1, -0x0f5f20,1, -0x0f5f28,1, -0x0f5f30,1, -0x0f5f38,1, -0x0f5f40,1, -0x0f8000,7, -0x0f8024,1, -0x0f8070,7, -0x0f80a0,1, -0x0f80ac,9, -0x0f8180,1, -0x0f81e0,5, -0x0f81f8,1, -0x0f8230,2, -0x0f8240,2, -0x0f8300,3, -0x0f8314,4, -0x0f8340,5, -0x0f8380,1, -0x0f838c,3, -0x0f8400,10, -0x0f8440,10, -0x0f8480,10, -0x0f84c0,10, -0x0f8500,2, -0x0f8510,1, -0x0f8518,3, -0x0f8540,2, -0x0f8550,1, -0x0f8558,3, -0x0f8600,24, -0x0f8804,1, -0x0f880c,5, -0x0f8824,1, -0x0f8904,2, -0x0f8a04,8, -0x0f8a44,3, -0x0f8b00,3, -0x0f8b20,2, -0x0f8b40,1, -0x0f8b48,1, -0x0f8b50,4, -0x0f8c04,6, -0x0f8d04,5, -0x0f8e04,4, -0x0f8e80,5, diff --git a/mstdump/mstdump_dbs/InfiniHostIIIEx_MF.csv b/mstdump/mstdump_dbs/InfiniHostIIIEx_MF.csv deleted file mode 100755 index 59a3720..0000000 --- a/mstdump/mstdump_dbs/InfiniHostIIIEx_MF.csv +++ /dev/null @@ -1,570 +0,0 @@ -# addr, size, enable addr -0x010000,16, -0x010050,4, -0x010070,4, -0x01009c,9, -0x0100d8,3, -0x0100e8,1, -0x010100,20, -0x010158,1, -0x010164,1, -0x01017c,1, -0x010188,6, -0x010230,2, -0x010280,16, -0x0102f8,3, -0x010308,1, -0x010310,1, -0x010318,1, -0x010320,1, -0x010328,1, -0x010330,1, -0x010338,1, -0x010340,1, -0x010348,1, -0x010350,1, -0x010358,1, -0x010360,1, -0x010368,1, -0x010370,1, -0x010378,1, -0x010390,11, -0x0103cc,1, -0x0103e0,3, -0x0103f0,4, -0x010780,5, -0x0107a0,5, -0x0107c0,5, -0x0107d8,2, -0x010800,16, -0x010850,4, -0x010870,4, -0x01089c,9, -0x0108d8,3, -0x0108e8,1, -0x010900,20, -0x010958,1, -0x010964,1, -0x01097c,1, -0x010988,6, -0x010a30,2, -0x010a80,16, -0x010af8,3, -0x010b08,1, -0x010b10,1, -0x010b18,1, -0x010b20,1, -0x010b28,1, -0x010b30,1, -0x010b38,1, -0x010b40,1, -0x010b48,1, -0x010b50,1, -0x010b58,1, -0x010b60,1, -0x010b68,1, -0x010b70,1, -0x010b78,1, -0x010b90,11, -0x010bcc,1, -0x010be0,3, -0x010bf0,4, -0x010f80,5, -0x010fa0,5, -0x010fc0,5, -0x010fd8,2, -0x040000,4, -0x040020,4, -0x040040,4, -0x040060,4, -0x040100,6, -0x040180,1, -0x04018c,3, -0x040200,35, -0x0403c0,54, -0x040800,256, -0x042004,5, -0x042024,8, -0x042210,1, -0x042244,6, -0x042310,3, -0x042320,2, -0x042350,4, -0x042380,1, -0x04238c,3, -0x0423c0,4, -0x042400,5, -0x042420,5, -0x04243c,11, -0x042500,19, -0x042700,13, -0x042740,1, -0x042780,32, -0x044000,8, -0x044024,4, -0x044038,2, -0x044044,20, -0x04409c,2, -0x0440ac,13, -0x044180,1, -0x0441e0,1, -0x0441ec,2, -0x0441f8,1, -0x044200,8, -0x044224,4, -0x044238,2, -0x044244,20, -0x04429c,2, -0x0442ac,13, -0x044380,1, -0x0443e0,1, -0x0443ec,2, -0x0443f8,1, -0x044500,4, -0x044520,4, -0x044540,2, -0x044604,45, -0x044700,46, -0x044804,45, -0x044900,46, -0x044b00,10, -0x044b40,2, -0x044c00,16, -0x044f00,1, -0x044f20,1, -0x044f40,1, -0x045100,4, -0x045130,3, -0x045140,8, -0x045210,3, -0x045220,1, -0x045260,1, -0x045284,4, -0x0452b0,5, -0x045300,1, -0x04530c,3, -0x045340,8, -0x045380,2, -0x045390,5, -0x0453a8,4, -0x045400,128, -0x045800,256, -0x045d10,9, -0x045d40,1, -0x045e00,64, -0x046000,2, -0x04600c,2, -0x046020,5, -0x046080,5, -0x0460a8,2, -0x046100,2, -0x04610c,2, -0x046120,5, -0x046180,5, -0x0461a8,2, -0x046200,2, -0x04620c,2, -0x046220,5, -0x046280,5, -0x0462a8,2, -0x046300,2, -0x04630c,2, -0x046320,5, -0x046380,5, -0x0463a8,2, -0x046400,2, -0x04640c,2, -0x046420,5, -0x046480,5, -0x0464a8,2, -0x046500,2, -0x04650c,2, -0x046520,5, -0x046580,5, -0x0465a8,2, -0x046600,2, -0x04660c,2, -0x046620,5, -0x046680,5, -0x0466a8,2, -0x046700,2, -0x04670c,2, -0x046720,5, -0x046780,5, -0x0467a8,2, -0x046800,2, -0x04680c,2, -0x046820,5, -0x046880,5, -0x0468a8,2, -0x046900,2, -0x04690c,2, -0x046920,5, -0x046980,5, -0x0469a8,2, -0x046a00,2, -0x046a0c,2, -0x046a20,5, -0x046a80,5, -0x046aa8,2, -0x046b00,2, -0x046b0c,2, -0x046b20,5, -0x046b80,5, -0x046ba8,2, -0x046c00,2, -0x046c0c,2, -0x046c20,5, -0x046c80,5, -0x046ca8,2, -0x046d00,2, -0x046d0c,2, -0x046d20,5, -0x046d80,5, -0x046da8,2, -0x046e00,2, -0x046e0c,2, -0x046e20,5, -0x046e80,5, -0x046ea8,2, -0x046f00,2, -0x046f0c,2, -0x046f20,5, -0x046f80,5, -0x046fa8,2, -0x0473f0,2, -0x047400,256, -0x047900,64, -0x047a84,5, -0x047aa0,2, -0x047ab0,2, -0x047b84,3, -0x047ba0,1, -0x04c000,8, -0x04c024,4, -0x04c038,2, -0x04c044,20, -0x04c09c,2, -0x04c0ac,13, -0x04c180,1, -0x04c1e0,1, -0x04c1ec,2, -0x04c1f8,1, -0x04c300,5, -0x04c340,5, -0x04c380,7, -0x04c500,16, -0x04c560,16, -0x04c5b0,6, -0x04c5d0,7, -0x04c5f0,11, -0x04c640,2, -0x04c700,35, -0x04c790,25, -0x04c800,256, -0x04d004,45, -0x04d130,3, -0x04d140,12, -0x04d200,51, -0x04d4a0,6, -0x04d500,9, -0x04d540,7, -0x04d560,3, -0x04d570,3, -0x04d580,3, -0x04d590,4, -0x04d5e4,3, -0x04d600,6, -0x04d620,10, -0x04d700,2, -0x04d718,8, -0x04d77c,2, -0x04d800,128, -0x04dc00,1, -0x04dc0c,3, -0x04dc24,4, -0x04dc44,3, -0x04dd00,15, -0x04de00,16, -0x04dff8,578, -0x080000,8, -0x080024,4, -0x080038,2, -0x080044,20, -0x08009c,2, -0x0800ac,13, -0x080180,1, -0x0801e0,1, -0x0801ec,2, -0x0801f8,1, -0x080200,3, -0x080210,1, -0x080240,6, -0x080284,30, -0x080300,8, -0x080330,8, -0x080380,1, -0x080414,1, -0x080488,8, -0x080500,1, -0x080510,2, -0x08051c,1, -0x080530,8, -0x080580,6, -0x0805a0,9, -0x0805d0,1, -0x0805dc,5, -0x080600,1, -0x08060c,3, -0x080640,1, -0x080680,7, -0x080700,2, -0x080800,6, -0x080840,4, -0x080854,1, -0x080860,22, -0x0808e4,1, -0x08092c,2, -0x081000,9, -0x081040,9, -0x081080,2, -0x0810c0,2, -0x0810d0,2, -0x081100,2, -0x081110,2, -0x081304,7, -0x081410,9, -0x081440,1, -0x081500,64, -0x081800,38, -0x081a00,2, -0x081a18,8, -0x081a7c,1, -0x081c04,45, -0x082000,1025, -0x086000,2, -0x08600c,8, -0x086030,2, -0x086040,1, -0x08604c,3, -0x086060,12, -0x0860a0,3, -0x0860b0,3, -0x0860e8,3, -0x086100,2, -0x086130,3, -0x086160,3, -0x086180,1, -0x0861a0,5, -0x0861bc,1, -0x0861c4,1, -0x0861d0,2, -0x088000,8, -0x088024,4, -0x088038,2, -0x088044,20, -0x08809c,2, -0x0880ac,13, -0x088180,1, -0x0881e0,1, -0x0881ec,2, -0x0881f8,1, -0x088280,1, -0x08828c,3, -0x088300,2, -0x088340,2, -0x088380,2, -0x0883a0,1, -0x0883b0,1, -0x0883c0,1, -0x088404,5, -0x088424,7, -0x088474,3, -0x088498,2, -0x0884e0,4, -0x088504,5, -0x088524,7, -0x088574,3, -0x088598,2, -0x0885e0,4, -0x088604,5, -0x088624,7, -0x088674,3, -0x088698,2, -0x0886e0,4, -0x088708,4, -0x088780,7, -0x0887c4,7, -0x088810,9, -0x088840,1, -0x088900,64, -0x088b00,3, -0x088b10,3, -0x088b20,8, -0x088b80,1, -0x088b90,4, -0x088c00,8, -0x088c80,18, -0x088d00,16, -0x088d80,16, -0x088e90,4, -0x088eb0,4, -0x089000,3, -0x089ffc,129, -0x08c000,2, -0x08c010,10, -0x08c040,2, -0x08c084,4, -0x08c100,1, -0x08c10c,3, -0x0f0000,2, -0x0f0010,2, -0x0f001c,18, -0x0f006c,15, -0x0f00b8,4, -0x0f00e0,2, -0x0f0134,2, -0x0f0140,2, -0x0f0150,6, -0x0f0180,5, -0x0f01a0,3, -0x0f01c0,6, -0x0f01e0,6, -0x0f0200,11, -0x0f0240,1, -0x0f02c0,2, -0x0f0500,3, -0x0f0520,1, -0x0f0540,2, -0x0f0554,5, -0x0f0580,5, -0x0f05a0,3, -0x0f05b0,2, -0x0f0800,4, -0x0f0820,1, -0x0f0830,2, -0x0f0840,1, -0x0f1000,3, -0x0f1200,2, -0x0f1400,256, -0x0f3000,17, -0x0f3048,10, -0x0f3078,11, -0x0f30b0,30, -0x0f3130,4, -0x0f3170,4, -0x0f3184,13, -0x0f31bc,1, -0x0f3204,1, -0x0f3210,4, -0x0f3240,16, -0x0f3284,6, -0x0f32b0,20, -0x0f3304,5, -0x0f3328,1, -0x0f3330,3, -0x0f3400,9, -0x0f3430,6, -0x0f344c,3, -0x0f3480,9, -0x0f34b0,6, -0x0f34cc,3, -0x0f3800,17, -0x0f3848,14, -0x0f396c,9, -0x0f399c,5, -0x0f39e8,78, -0x0f3b38,6, -0x0f3b60,1, -0x0f3b6c,3, -0x0f3b80,29, -0x0f3c00,6, -0x0f3c1c,2, -0x0f3c30,7, -0x0f3c60,8, -0x0f3cf8,1, -0x0f3d00,3, -0x0f3d80,10, -0x0f3dc0,10, -0x0f3e00,1, -0x0f3e10,4, -0x0f3e24,3, -0x0f3e34,4, -0x0f3e60,6, -0x0f3e84,3, -0x0f5000,4, -0x0f5020,4, -0x0f50a0,1, -0x0f5100,1, -0x0f510c,3, -0x0f5200,1, -0x0f5240,1, -0x0f5284,2, -0x0f52c0,1, -0x0f5300,4, -0x0f5340,4, -0x0f5380,4, -0x0f53c0,4, -0x0f5800,10, -0x0f5900,1, -0x0f5910,16, -0x0f5a00,1, -0x0f5a40,1, -0x0f5a50,2, -0x0f5a60,1, -0x0f5a80,1, -0x0f5a90,2, -0x0f5aa0,1, -0x0f5ab0,2, -0x0f5ac0,1, -0x0f5ad0,2, -0x0f5ae0,1, -0x0f5af0,2, -0x0f5b04,3, -0x0f5b18,6, -0x0f5b6c,5, -0x0f5bc0,81, -0x0f5d08,1, -0x0f5d10,1, -0x0f5d18,1, -0x0f5d20,1, -0x0f5d28,1, -0x0f5d30,1, -0x0f5d38,1, -0x0f5d40,1, -0x0f5d48,1, -0x0f5d50,1, -0x0f5d58,1, -0x0f5d60,1, -0x0f5d68,1, -0x0f5d70,1, -0x0f5d78,1, -0x0f5d80,1, -0x0f5d88,1, -0x0f5da0,1, -0x0f5db0,1, -0x0f5dc0,1, -0x0f5dd0,1, -0x0f5de0,1, -0x0f5df0,1, -0x0f5e00,1, -0x0f5e10,1, -0x0f5e20,1, -0x0f5e30,1, -0x0f5e40,1, -0x0f5e50,1, -0x0f5e60,1, -0x0f5e70,1, -0x0f5e80,1, -0x0f5e90,1, -0x0f5ea0,1, -0x0f5eb0,1, -0x0f5f00,1, -0x0f5f08,1, -0x0f5f10,1, -0x0f5f18,1, -0x0f5f20,1, -0x0f5f28,1, -0x0f5f30,1, -0x0f5f38,1, -0x0f5f40,1, diff --git a/mstdump/mstdump_dbs/InfiniHostIIILx.csv b/mstdump/mstdump_dbs/InfiniHostIIILx.csv deleted file mode 100755 index c8d9e43..0000000 --- a/mstdump/mstdump_dbs/InfiniHostIIILx.csv +++ /dev/null @@ -1,332 +0,0 @@ -# addr, size, enable addr -0x010010,1, -0x010020,3, -0x010034,2, -0x010050,4, -0x010070,4, -0x01009c,5, -0x0100d8,3, -0x0100e8,1, -0x010100,18, -0x010158,5, -0x01017c,2, -0x010188,6, -0x010230,2, -0x010240,3, -0x010250,2, -0x010280,8, -0x0102f8,2, -0x0103cc,1, -0x0103e8,1, -0x0103fc,9, -0x010440,2, -0x010700,13, -0x010738,12, -0x0107b0,2, -0x0107c0,5, -0x0107d8,2, -0x0107e8,1, -0x0107f0,1, -0x011004,5, -0x011024,8, -0x011210,1, -0x011244,6, -0x011310,3, -0x011320,2, -0x011350,1, -0x011358,2, -0x011380,1, -0x01138c,3, -0x0113c0,3, -0x011400,5, -0x011420,5, -0x01143c,11, -0x011500,2, -0x011700,13, -0x011740,1, -0x011780,8, -0x012004,2, -0x012014,2, -0x012020,6, -0x012040,4, -0x012080,4, -0x012100,1, -0x01210c,3, -0x0123c0,1, -0x0123e0,1, -0x012400,32, -0x012ff8,578, -0x044000,8, -0x044024,4, -0x044038,2, -0x044044,20, -0x04409c,2, -0x0440ac,13, -0x044180,1, -0x04419c,5, -0x0441e0,1, -0x0441ec,2, -0x0441f8,1, -0x044500,3, -0x044520,2, -0x044540,2, -0x044604,45, -0x044804,45, -0x044c00,4, -0x044f00,1, -0x044f20,1, -0x044f40,1, -0x045100,1, -0x045108,2, -0x045130,3, -0x045140,8, -0x045260,1, -0x045284,4, -0x045300,1, -0x04530c,3, -0x04535c,1, -0x045380,2, -0x045390,5, -0x0453a8,4, -0x0453bc,1, -0x045400,64, -0x045800,128, -0x045d04,3, -0x045d14,3, -0x045d24,3, -0x045d80,4, -0x045d94,1, -0x046000,2, -0x04600c,2, -0x046020,3, -0x046030,1, -0x046080,5, -0x0460a8,2, -0x046100,2, -0x04610c,2, -0x046120,3, -0x046130,1, -0x046180,5, -0x0461a8,2, -0x046200,2, -0x04620c,2, -0x046220,3, -0x046230,1, -0x046280,5, -0x0462a8,2, -0x046300,2, -0x04630c,2, -0x046320,3, -0x046330,1, -0x046380,5, -0x0463a8,2, -0x0473f0,2, -0x047900,16, -0x047980,2, -0x047990,2, -0x0479a0,2, -0x0479b0,2, -0x047a84,5, -0x047aa0,2, -0x047ab0,2, -0x047b84,3, -0x047ba0,1, -0x047d00,33, -0x060380,7, -0x0603c0,2, -0x0603d0,3, -0x060500,16, -0x060560,16, -0x0605b0,3, -0x0605c0,2, -0x0605d0,7, -0x0605f0,7, -0x060610,3, -0x060700,35, -0x060790,27, -0x060800,128, -0x061004,45, -0x061130,2, -0x061140,12, -0x061200,6, -0x0612c0,3, -0x0614a0,6, -0x061500,9, -0x061540,7, -0x061560,3, -0x061570,3, -0x061580,3, -0x061590,4, -0x0615e4,3, -0x061600,6, -0x061620,10, -0x061700,2, -0x061718,8, -0x06177c,2, -0x061800,64, -0x061c00,1, -0x061c0c,3, -0x061c44,3, -0x061d00,15, -0x061ff8,578, -0x070000,2, -0x070010,3, -0x070280,1, -0x07028c,3, -0x070300,2, -0x0703a0,1, -0x070604,5, -0x070624,7, -0x070674,3, -0x07069c,1, -0x0706e0,4, -0x070708,4, -0x070780,1, -0x07078c,4, -0x0707c4,7, -0x070810,2, -0x070820,3, -0x070840,1, -0x070900,64, -0x070b08,1, -0x070b10,3, -0x070b20,3, -0x070b30,3, -0x070b80,1, -0x070cc0,4, -0x070e90,4, -0x071000,3, -0x0713fc,1, -0x072000,128, -0x074000,2, -0x074010,10, -0x074084,4, -0x074100,1, -0x07410c,3, -0x080000,8, -0x080024,4, -0x080038,2, -0x080044,20, -0x08009c,2, -0x0800ac,13, -0x080180,1, -0x08019c,5, -0x0801e0,1, -0x0801ec,2, -0x0801f8,1, -0x080200,3, -0x080210,1, -0x080240,6, -0x080284,30, -0x080300,8, -0x080330,8, -0x080380,1, -0x080414,1, -0x080488,8, -0x080500,1, -0x080510,2, -0x08051c,1, -0x080530,8, -0x080580,6, -0x0805a0,9, -0x0805d0,1, -0x0805dc,5, -0x080600,1, -0x08060c,3, -0x080640,1, -0x080680,7, -0x080700,1, -0x080800,6, -0x080840,4, -0x080854,1, -0x080860,22, -0x0808e4,1, -0x08092c,2, -0x081304,7, -0x081410,2, -0x081420,3, -0x081440,1, -0x081500,64, -0x08188c,5, -0x081a00,2, -0x081a18,8, -0x081a7c,1, -0x082000,1024, -0x0f0010,3, -0x0f0084,1, -0x0f008c,1, -0x0f0094,1, -0x0f009c,1, -0x0f00a4,1, -0x0f00bc,1, -0x0f00c4,1, -0x0f00e0,4, -0x0f0154,5, -0x0f0180,5, -0x0f0200,1, -0x0f0208,1, -0x0f0210,1, -0x0f0220,1, -0x0f0228,1, -0x0f0230,1, -0x0f0280,2, -0x0f02a0,4, -0x0f02c0,5, -0x0f0400,7, -0x0f0500,4, -0x0f0540,2, -0x0f05b0,2, -0x0f0800,6, -0x0f0840,1, -0x0f0880,5, -0x0f08a8,5, -0x0f3000,9, -0x0f3028,3, -0x0f3040,1, -0x0f3048,2, -0x0f3058,6, -0x0f3078,13, -0x0f30c0,13, -0x0f3100,6, -0x0f3120,2, -0x0f3130,5, -0x0f3170,1, -0x0f3178,1, -0x0f3184,13, -0x0f31bc,1, -0x0f3204,1, -0x0f3210,5, -0x0f3244,6, -0x0f3264,5, -0x0f3290,5, -0x0f32e4,4, -0x0f3400,17, -0x0f344c,15, -0x0f3500,2, -0x0f350c,11, -0x0f3540,5, -0x0f3580,9, -0x0f35ac,3, -0x0f35cc,5, -0x0f35fc,65, -0x0f3800,6, -0x0f381c,2, -0x0f3830,3, -0x0f3844,1, -0x0f3860,18, -0x0f38f8,1, -0x0f3900,3, -0x0f3980,11, -0x0f39b0,1, -0x0f39c0,11, -0x0f39f0,1, -0x0f3a00,1, -0x0f3a10,4, -0x0f3a24,3, -0x0f3a34,4, -0x0f3a84,3, -0x0f3e00,10, -0x0f3e38,3, -0x0f3e4c,3, -0x0f3e60,11, -0x0f3e90,18, diff --git a/mstdump/mstdump_dbs/InfiniScaleIII.csv b/mstdump/mstdump_dbs/InfiniScaleIII.csv deleted file mode 100755 index c5efc55..0000000 --- a/mstdump/mstdump_dbs/InfiniScaleIII.csv +++ /dev/null @@ -1,844 +0,0 @@ -# addr, size, enable addr -0x010000,1, -0x010018,1, -0x010070,7, -0x0100a0,1, -0x0100ac,9, -0x010180,1, -0x0101e0,5, -0x0101f8,1, -0x010300,18, -0x010400,1, -0x01040c,4, -0x010424,3, -0x010500,6, -0x010580,3, -0x010600,1, -0x010610,24, -0x010700,1, -0x010804,2, -0x010824,2, -0x010f04,1, -0x011000,1056, -0x018000,1056, -0x020000,30739, -0x03e050,35, -0x03e0e4,5, -0x03e100,233, -0x03e4a8,5, -0x03e4c0,5, -0x03e4d8,5, -0x03e4f0,5, -0x03e508,5, -0x03e520,5, -0x03e538,5, -0x03e550,5, -0x03e568,5, -0x03e580,5, -0x03e598,5, -0x03e5b0,5, -0x03e5c8,5, -0x03e5e0,5, -0x03e5f8,5, -0x03e610,143, -0x03e850,69, -0x03e96c,7, -0x03e9a4,83, -0x03eb6c,11, -0x03ebb0,2, -0x03ec30,63, -0x03ed34,13, -0x03ed6c,12, -0x03edb4,8, -0x03edec,140, -0x03f024,16, -0x03f084,28, -0x03f0f8,48, -0x03f210,3, -0x03f220,43, -0x03f2d0,9, -0x03f2f8,21, -0x03f3dc,145, -0x03f63c,48, -0x03f700,303, -0x03fc00,32, -0x03fd00,32, -0x03fdfc,13, -0x03fe50,4, -0x03fe80,34, -0x03ff0c,27, -0x03ff80,15, -0x03ffc0,6, -0x03ffdc,9, -0x060004,2, -0x060010,6, -0x06002c,14, -0x060070,3, -0x060080,10, -0x0600b8,4, -0x0600e0,1, -0x060128,2, -0x060140,2, -0x060150,6, -0x060180,5, -0x0601a0,3, -0x0601c0,4, -0x0601d8,1, -0x0601e0,2, -0x0601f0,1, -0x0601f8,1, -0x060200,11, -0x060240,2, -0x060250,2, -0x0602c0,1, -0x060500,3, -0x060520,3, -0x060554,5, -0x060580,5, -0x0605a0,3, -0x0605b0,2, -0x060600,5, -0x060618,1, -0x060624,13, -0x060800,1, -0x060808,1, -0x060820,1, -0x060830,2, -0x060840,1, -0x060848,1, -0x060850,1, -0x060860,6, -0x061000,3, -0x061200,2, -0x070000,2, -0x070080,1, -0x0700a0,2, -0x0700d0,2, -0x070100,1, -0x070200,12, -0x070400,12, -0x070500,5, -0x070540,2, -0x070560,1, -0x070570,1, -0x070580,1, -0x07058c,3, -0x0705b0,19, -0x070600,29, -0x080000,2, -0x080080,1, -0x0800a0,2, -0x0800d0,2, -0x080100,1, -0x080200,12, -0x080400,12, -0x080500,5, -0x080540,2, -0x080560,1, -0x080570,1, -0x080580,1, -0x08058c,3, -0x0805b0,19, -0x080600,29, -0x0a0000,4, -0x0a0080,4, -0x0a0100,4, -0x0a0114,1, -0x0a0120,3, -0x0a0140,2, -0x0a0180,1, -0x0a0c10,1, -0x0a0c20,1, -0x0a0c2c,5, -0x0a1000,4, -0x0a1080,4, -0x0a1100,6, -0x0a1120,3, -0x0a1140,4, -0x0a1400,4, -0x0a1480,4, -0x0a1500,6, -0x0a1520,3, -0x0a1540,4, -0x0a1800,4, -0x0a1880,4, -0x0a1900,6, -0x0a1920,3, -0x0a1940,4, -0x0a1c00,1, -0x0a1c10,1, -0x0a1c20,1, -0x0a1c2c,5, -0x0a2000,4, -0x0a2080,4, -0x0a2100,6, -0x0a2120,3, -0x0a2140,4, -0x0a2400,4, -0x0a2480,4, -0x0a2500,6, -0x0a2520,3, -0x0a2540,4, -0x0a2800,4, -0x0a2880,4, -0x0a2900,6, -0x0a2920,3, -0x0a2940,4, -0x0a2c00,1, -0x0a2c10,1, -0x0a2c20,1, -0x0a2c2c,5, -0x0a3000,4, -0x0a3080,4, -0x0a3100,6, -0x0a3120,3, -0x0a3140,4, -0x0a3400,4, -0x0a3480,4, -0x0a3500,6, -0x0a3520,3, -0x0a3540,4, -0x0a3800,4, -0x0a3880,4, -0x0a3900,6, -0x0a3920,3, -0x0a3940,4, -0x0a3c00,1, -0x0a3c10,1, -0x0a3c20,1, -0x0a3c2c,5, -0x0a4000,4, -0x0a4080,4, -0x0a4100,6, -0x0a4120,3, -0x0a4140,4, -0x0a4400,4, -0x0a4480,4, -0x0a4500,6, -0x0a4520,3, -0x0a4540,4, -0x0a4800,4, -0x0a4880,4, -0x0a4900,6, -0x0a4920,3, -0x0a4940,4, -0x0a4c00,1, -0x0a4c10,1, -0x0a4c20,1, -0x0a4c2c,5, -0x0a5000,4, -0x0a5080,4, -0x0a5100,6, -0x0a5120,3, -0x0a5140,4, -0x0a5400,4, -0x0a5480,4, -0x0a5500,6, -0x0a5520,3, -0x0a5540,4, -0x0a5800,4, -0x0a5880,4, -0x0a5900,6, -0x0a5920,3, -0x0a5940,4, -0x0a5c00,1, -0x0a5c10,1, -0x0a5c20,1, -0x0a5c2c,5, -0x0a6000,4, -0x0a6080,4, -0x0a6100,6, -0x0a6120,3, -0x0a6140,4, -0x0a6400,4, -0x0a6480,4, -0x0a6500,6, -0x0a6520,3, -0x0a6540,4, -0x0a6800,4, -0x0a6880,4, -0x0a6900,6, -0x0a6920,3, -0x0a6940,4, -0x0a6c00,1, -0x0a6c10,1, -0x0a6c20,1, -0x0a6c2c,5, -0x0a7000,4, -0x0a7080,4, -0x0a7100,6, -0x0a7120,3, -0x0a7140,4, -0x0a7400,4, -0x0a7480,4, -0x0a7500,6, -0x0a7520,3, -0x0a7540,4, -0x0a7800,4, -0x0a7880,4, -0x0a7900,6, -0x0a7920,3, -0x0a7940,4, -0x0a7c00,1, -0x0a7c10,1, -0x0a7c20,1, -0x0a7c2c,5, -0x0a8000,4, -0x0a8080,4, -0x0a8100,6, -0x0a8120,3, -0x0a8140,4, -0x0a8400,4, -0x0a8480,4, -0x0a8500,6, -0x0a8520,3, -0x0a8540,4, -0x0a8800,4, -0x0a8880,4, -0x0a8900,6, -0x0a8920,3, -0x0a8940,4, -0x0a8c00,1, -0x0a8c10,1, -0x0a8c20,1, -0x0a8c2c,5, -0x0a9160,44, -0x0a9220,1, -0x0a922c,4, -0x0a9244,6, -0x0a9c10,3, -0x0a9c24,3, -0x0a9ed0,9, -0x0a9f00,25, -0x100020,3, -0x100100,1, -0x10010c,9, -0x100134,1, -0x10013c,1, -0x100148,2, -0x100158,3, -0x10017c,1, -0x100188,1, -0x100194,3, -0x1003fc,1, -0x10041c,1, -0x101020,3, -0x101034,1, -0x101100,1, -0x10110c,17, -0x101158,4, -0x10117c,4, -0x101194,3, -0x101280,16, -0x1012f8,3, -0x101308,1, -0x101390,7, -0x1013cc,4, -0x1013e0,1, -0x1013e8,1, -0x1013fc,3, -0x101410,4, -0x101780,5, -0x1017a0,4, -0x1017d8,7, -0x1017f8,2, -0x101c00,26, -0x101cd0,1, -0x101d00,1, -0x101d0c,5, -0x101d84,10, -0x102020,3, -0x102034,1, -0x102100,1, -0x10210c,17, -0x102158,4, -0x10217c,4, -0x102194,3, -0x102280,16, -0x1022f8,3, -0x102308,1, -0x102390,7, -0x1023cc,4, -0x1023e0,1, -0x1023e8,1, -0x1023fc,3, -0x102410,4, -0x102780,5, -0x1027a0,4, -0x1027d8,7, -0x1027f8,2, -0x103020,3, -0x103034,1, -0x103100,1, -0x10310c,17, -0x103158,4, -0x10317c,4, -0x103194,3, -0x103280,16, -0x1032f8,3, -0x103308,1, -0x103390,7, -0x1033cc,4, -0x1033e0,1, -0x1033e8,1, -0x1033fc,3, -0x103410,4, -0x103780,5, -0x1037a0,4, -0x1037d8,7, -0x1037f8,2, -0x104020,3, -0x104034,1, -0x104100,1, -0x10410c,17, -0x104158,4, -0x10417c,4, -0x104194,3, -0x104280,16, -0x1042f8,3, -0x104308,1, -0x104390,7, -0x1043cc,4, -0x1043e0,1, -0x1043e8,1, -0x1043fc,3, -0x104410,4, -0x104780,5, -0x1047a0,4, -0x1047d8,7, -0x1047f8,2, -0x104c00,26, -0x104cd0,1, -0x104d00,1, -0x104d0c,5, -0x104d84,10, -0x105020,3, -0x105034,1, -0x105100,1, -0x10510c,17, -0x105158,4, -0x10517c,4, -0x105194,3, -0x105280,16, -0x1052f8,3, -0x105308,1, -0x105390,7, -0x1053cc,4, -0x1053e0,1, -0x1053e8,1, -0x1053fc,3, -0x105410,4, -0x105780,5, -0x1057a0,4, -0x1057d8,7, -0x1057f8,2, -0x106020,3, -0x106034,1, -0x106100,1, -0x10610c,17, -0x106158,4, -0x10617c,4, -0x106194,3, -0x106280,16, -0x1062f8,3, -0x106308,1, -0x106390,7, -0x1063cc,4, -0x1063e0,1, -0x1063e8,1, -0x1063fc,3, -0x106410,4, -0x106780,5, -0x1067a0,4, -0x1067d8,7, -0x1067f8,2, -0x107020,3, -0x107034,1, -0x107100,1, -0x10710c,17, -0x107158,4, -0x10717c,4, -0x107194,3, -0x107280,16, -0x1072f8,3, -0x107308,1, -0x107390,7, -0x1073cc,4, -0x1073e0,1, -0x1073e8,1, -0x1073fc,3, -0x107410,4, -0x107780,5, -0x1077a0,4, -0x1077d8,7, -0x1077f8,2, -0x107c00,26, -0x107cd0,1, -0x107d00,1, -0x107d0c,5, -0x107d84,10, -0x108020,3, -0x108034,1, -0x108100,1, -0x10810c,17, -0x108158,4, -0x10817c,4, -0x108194,3, -0x108280,16, -0x1082f8,3, -0x108308,1, -0x108390,7, -0x1083cc,4, -0x1083e0,1, -0x1083e8,1, -0x1083fc,3, -0x108410,4, -0x108780,5, -0x1087a0,4, -0x1087d8,7, -0x1087f8,2, -0x109020,3, -0x109034,1, -0x109100,1, -0x10910c,17, -0x109158,4, -0x10917c,4, -0x109194,3, -0x109280,16, -0x1092f8,3, -0x109308,1, -0x109390,7, -0x1093cc,4, -0x1093e0,1, -0x1093e8,1, -0x1093fc,3, -0x109410,4, -0x109780,5, -0x1097a0,4, -0x1097d8,7, -0x1097f8,2, -0x10a020,3, -0x10a034,1, -0x10a100,1, -0x10a10c,17, -0x10a158,4, -0x10a17c,4, -0x10a194,3, -0x10a280,16, -0x10a2f8,3, -0x10a308,1, -0x10a390,7, -0x10a3cc,4, -0x10a3e0,1, -0x10a3e8,1, -0x10a3fc,3, -0x10a410,4, -0x10a780,5, -0x10a7a0,4, -0x10a7d8,7, -0x10a7f8,2, -0x10ac00,26, -0x10acd0,1, -0x10ad00,1, -0x10ad0c,5, -0x10ad84,10, -0x10b020,3, -0x10b034,1, -0x10b100,1, -0x10b10c,17, -0x10b158,4, -0x10b17c,4, -0x10b194,3, -0x10b280,16, -0x10b2f8,3, -0x10b308,1, -0x10b390,7, -0x10b3cc,4, -0x10b3e0,1, -0x10b3e8,1, -0x10b3fc,3, -0x10b410,4, -0x10b780,5, -0x10b7a0,4, -0x10b7d8,7, -0x10b7f8,2, -0x10c020,3, -0x10c034,1, -0x10c100,1, -0x10c10c,17, -0x10c158,4, -0x10c17c,4, -0x10c194,3, -0x10c280,16, -0x10c2f8,3, -0x10c308,1, -0x10c390,7, -0x10c3cc,4, -0x10c3e0,1, -0x10c3e8,1, -0x10c3fc,3, -0x10c410,4, -0x10c780,5, -0x10c7a0,4, -0x10c7d8,7, -0x10c7f8,2, -0x10d020,3, -0x10d034,1, -0x10d100,1, -0x10d10c,17, -0x10d158,4, -0x10d17c,4, -0x10d194,3, -0x10d280,16, -0x10d2f8,3, -0x10d308,1, -0x10d390,7, -0x10d3cc,4, -0x10d3e0,1, -0x10d3e8,1, -0x10d3fc,3, -0x10d410,4, -0x10d780,5, -0x10d7a0,4, -0x10d7d8,7, -0x10d7f8,2, -0x10dc00,26, -0x10dcd0,1, -0x10dd00,1, -0x10dd0c,5, -0x10dd84,10, -0x10e020,3, -0x10e034,1, -0x10e100,1, -0x10e10c,17, -0x10e158,4, -0x10e17c,4, -0x10e194,3, -0x10e280,16, -0x10e2f8,3, -0x10e308,1, -0x10e390,7, -0x10e3cc,4, -0x10e3e0,1, -0x10e3e8,1, -0x10e3fc,3, -0x10e410,4, -0x10e780,5, -0x10e7a0,4, -0x10e7d8,7, -0x10e7f8,2, -0x10f020,3, -0x10f034,1, -0x10f100,1, -0x10f10c,17, -0x10f158,4, -0x10f17c,4, -0x10f194,3, -0x10f280,16, -0x10f2f8,3, -0x10f308,1, -0x10f390,7, -0x10f3cc,4, -0x10f3e0,1, -0x10f3e8,1, -0x10f3fc,3, -0x10f410,4, -0x10f780,5, -0x10f7a0,4, -0x10f7d8,7, -0x10f7f8,2, -0x110020,3, -0x110034,1, -0x110100,1, -0x11010c,17, -0x110158,4, -0x11017c,4, -0x110194,3, -0x110280,16, -0x1102f8,3, -0x110308,1, -0x110390,7, -0x1103cc,4, -0x1103e0,1, -0x1103e8,1, -0x1103fc,3, -0x110410,4, -0x110780,5, -0x1107a0,4, -0x1107d8,7, -0x1107f8,2, -0x110c00,26, -0x110cd0,1, -0x110d00,1, -0x110d0c,5, -0x110d84,10, -0x111020,3, -0x111034,1, -0x111100,1, -0x11110c,17, -0x111158,4, -0x11117c,4, -0x111194,3, -0x111280,16, -0x1112f8,3, -0x111308,1, -0x111390,7, -0x1113cc,4, -0x1113e0,1, -0x1113e8,1, -0x1113fc,3, -0x111410,4, -0x111780,5, -0x1117a0,4, -0x1117d8,7, -0x1117f8,2, -0x112020,3, -0x112034,1, -0x112100,1, -0x11210c,17, -0x112158,4, -0x11217c,4, -0x112194,3, -0x112280,16, -0x1122f8,3, -0x112308,1, -0x112390,7, -0x1123cc,4, -0x1123e0,1, -0x1123e8,1, -0x1123fc,3, -0x112410,4, -0x112780,5, -0x1127a0,4, -0x1127d8,7, -0x1127f8,2, -0x113020,3, -0x113034,1, -0x113100,1, -0x11310c,17, -0x113158,4, -0x11317c,4, -0x113194,3, -0x113280,16, -0x1132f8,3, -0x113308,1, -0x113390,7, -0x1133cc,4, -0x1133e0,1, -0x1133e8,1, -0x1133fc,3, -0x113410,4, -0x113780,5, -0x1137a0,4, -0x1137d8,7, -0x1137f8,2, -0x113c00,26, -0x113cd0,1, -0x113d00,1, -0x113d0c,5, -0x113d84,10, -0x114020,3, -0x114034,1, -0x114100,1, -0x11410c,17, -0x114158,4, -0x11417c,4, -0x114194,3, -0x114280,16, -0x1142f8,3, -0x114308,1, -0x114390,7, -0x1143cc,4, -0x1143e0,1, -0x1143e8,1, -0x1143fc,3, -0x114410,4, -0x114780,5, -0x1147a0,4, -0x1147d8,7, -0x1147f8,2, -0x115020,3, -0x115034,1, -0x115100,1, -0x11510c,17, -0x115158,4, -0x11517c,4, -0x115194,3, -0x115280,16, -0x1152f8,3, -0x115308,1, -0x115390,7, -0x1153cc,4, -0x1153e0,1, -0x1153e8,1, -0x1153fc,3, -0x115410,4, -0x115780,5, -0x1157a0,4, -0x1157d8,7, -0x1157f8,2, -0x116020,3, -0x116034,1, -0x116100,1, -0x11610c,17, -0x116158,4, -0x11617c,4, -0x116194,3, -0x116280,16, -0x1162f8,3, -0x116308,1, -0x116390,7, -0x1163cc,4, -0x1163e0,1, -0x1163e8,1, -0x1163fc,3, -0x116410,4, -0x116780,5, -0x1167a0,4, -0x1167d8,7, -0x1167f8,2, -0x116c00,26, -0x116cd0,1, -0x116d00,1, -0x116d0c,5, -0x116d84,10, -0x117020,3, -0x117034,1, -0x117100,1, -0x11710c,17, -0x117158,4, -0x11717c,4, -0x117194,3, -0x117280,16, -0x1172f8,3, -0x117308,1, -0x117390,7, -0x1173cc,4, -0x1173e0,1, -0x1173e8,1, -0x1173fc,3, -0x117410,4, -0x117780,5, -0x1177a0,4, -0x1177d8,7, -0x1177f8,2, -0x118020,3, -0x118034,1, -0x118100,1, -0x11810c,17, -0x118158,4, -0x11817c,4, -0x118194,3, -0x118280,16, -0x1182f8,3, -0x118308,1, -0x118390,7, -0x1183cc,4, -0x1183e0,1, -0x1183e8,1, -0x1183fc,3, -0x118410,4, -0x118780,5, -0x1187a0,4, -0x1187d8,7, -0x1187f8,2, diff --git a/mstdump/mstdump_dbs/Makefile.am b/mstdump/mstdump_dbs/Makefile.am index fd2e593..4e51653 100644 --- a/mstdump/mstdump_dbs/Makefile.am +++ b/mstdump/mstdump_dbs/Makefile.am @@ -29,6 +29,8 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. #-- -mstregdumpdir = $(datadir)/@PACKAGE@ -dist_mstregdump_DATA = *.csv + + +docdir = $(pkgdatadir)/mstdump_dbs +dist_doc_DATA = *.csv diff --git a/mstdump/mstdump_dbs/SwitchX.csv b/mstdump/mstdump_dbs/SwitchX.csv index e9235ad..1501724 100755 --- a/mstdump/mstdump_dbs/SwitchX.csv +++ b/mstdump/mstdump_dbs/SwitchX.csv @@ -1,5 +1,5 @@ -# addr, size, enable addr -0x000000,3, +#Addr, Size, Enable addr +0x000000,1, 0x000010,2, 0x000020,3, 0x000030,7, @@ -14,7 +14,7 @@ 0x000490,7, 0x0004b0,4, 0x0004c4,1, -0x0004cc,8, +0x0004cc,6, 0x0004f0,2, 0x000500,5, 0x000520,33, @@ -23,7 +23,7 @@ 0x000a08,7, 0x000a2c,38, 0x000ac8,12, -0x000b00,3, +0x000b00,1, 0x000b10,2, 0x000b20,8, 0x000b44,1, @@ -40,7 +40,7 @@ 0x000c60,14, 0x000d04,1, 0x000d24,9, -0x000d60,3, +0x000d60,1, 0x000d70,2, 0x000da0,2, 0x000db4,1, @@ -49,7 +49,7 @@ 0x000df0,15, 0x000e30,5, 0x000e60,14, -0x000f60,3, +0x000f60,1, 0x000f70,2, 0x000fa0,2, 0x000fb4,1, @@ -66,7 +66,7 @@ 0x001520,25, 0x001594,13, 0x0015cc,6, -0x0015fc,4, +0x0015fc,2, 0x001610,2, 0x001804,1, 0x001814,3, @@ -76,15 +76,15 @@ 0x001890,7, 0x0018b0,4, 0x0018c4,1, -0x0018cc,8, +0x0018cc,6, 0x0018f0,2, 0x001900,5, 0x001920,49, 0x001c04,1, 0x001c10,24, -0x001c80,3, +0x001c80,1, 0x001c90,2, -0x001ca0,3, +0x001ca0,1, 0x001cb0,2, 0x001cc8,5, 0x001d00,22, @@ -140,14 +140,13 @@ 0x003964,4, 0x003978,5, 0x003990,2, -0x003a00,6, -0x003a24,68, +0x003a00,77, 0x003c00,31, 0x003c80,7, 0x003ca0,33, 0x003d40,6, 0x003d64,1, -0x003d70,17, +0x003d70,16, 0x003dc0,14, 0x003e04,57, 0x004000,2, @@ -157,13 +156,13 @@ 0x004134,2, 0x00414c,1, 0x004170,3, -0x004200,3, +0x004200,1, 0x004210,2, -0x004220,3, +0x004220,1, 0x004230,2, 0x0042c0,1, 0x004400,64, -0x008000,3, +0x008000,1, 0x008010,2, 0x008020,3, 0x008030,7, @@ -178,7 +177,7 @@ 0x008490,7, 0x0084b0,4, 0x0084c4,1, -0x0084cc,8, +0x0084cc,6, 0x0084f0,2, 0x008500,5, 0x008520,33, @@ -187,7 +186,7 @@ 0x008a08,7, 0x008a2c,38, 0x008ac8,12, -0x008b00,3, +0x008b00,1, 0x008b10,2, 0x008b20,8, 0x008b44,1, @@ -204,7 +203,7 @@ 0x008c60,14, 0x008d04,1, 0x008d24,9, -0x008d60,3, +0x008d60,1, 0x008d70,2, 0x008da0,2, 0x008db4,1, @@ -213,7 +212,7 @@ 0x008df0,15, 0x008e30,5, 0x008e60,14, -0x008f60,3, +0x008f60,1, 0x008f70,2, 0x008fa0,2, 0x008fb4,1, @@ -230,7 +229,7 @@ 0x009520,25, 0x009594,13, 0x0095cc,6, -0x0095fc,4, +0x0095fc,2, 0x009610,2, 0x009804,1, 0x009814,3, @@ -240,15 +239,15 @@ 0x009890,7, 0x0098b0,4, 0x0098c4,1, -0x0098cc,8, +0x0098cc,6, 0x0098f0,2, 0x009900,5, 0x009920,49, 0x009c04,1, 0x009c10,24, -0x009c80,3, +0x009c80,1, 0x009c90,2, -0x009ca0,3, +0x009ca0,1, 0x009cb0,2, 0x009cc8,5, 0x009d00,22, @@ -304,14 +303,13 @@ 0x00b964,4, 0x00b978,5, 0x00b990,2, -0x00ba00,6, -0x00ba24,68, +0x00ba00,77, 0x00bc00,31, 0x00bc80,7, 0x00bca0,33, 0x00bd40,6, 0x00bd64,1, -0x00bd70,17, +0x00bd70,16, 0x00bdc0,14, 0x00be04,57, 0x00c000,2, @@ -321,13 +319,13 @@ 0x00c134,2, 0x00c14c,1, 0x00c170,3, -0x00c200,3, +0x00c200,1, 0x00c210,2, -0x00c220,3, +0x00c220,1, 0x00c230,2, 0x00c2c0,1, 0x00c400,64, -0x010000,3, +0x010000,1, 0x010010,2, 0x010020,3, 0x010030,7, @@ -342,7 +340,7 @@ 0x010490,7, 0x0104b0,4, 0x0104c4,1, -0x0104cc,8, +0x0104cc,6, 0x0104f0,2, 0x010500,5, 0x010520,33, @@ -351,7 +349,7 @@ 0x010a08,7, 0x010a2c,38, 0x010ac8,12, -0x010b00,3, +0x010b00,1, 0x010b10,2, 0x010b20,8, 0x010b44,1, @@ -368,7 +366,7 @@ 0x010c60,14, 0x010d04,1, 0x010d24,9, -0x010d60,3, +0x010d60,1, 0x010d70,2, 0x010da0,2, 0x010db4,1, @@ -377,7 +375,7 @@ 0x010df0,15, 0x010e30,5, 0x010e60,14, -0x010f60,3, +0x010f60,1, 0x010f70,2, 0x010fa0,2, 0x010fb4,1, @@ -394,7 +392,7 @@ 0x011520,25, 0x011594,13, 0x0115cc,6, -0x0115fc,4, +0x0115fc,2, 0x011610,2, 0x011804,1, 0x011814,3, @@ -404,15 +402,15 @@ 0x011890,7, 0x0118b0,4, 0x0118c4,1, -0x0118cc,8, +0x0118cc,6, 0x0118f0,2, 0x011900,5, 0x011920,49, 0x011c04,1, 0x011c10,24, -0x011c80,3, +0x011c80,1, 0x011c90,2, -0x011ca0,3, +0x011ca0,1, 0x011cb0,2, 0x011cc8,5, 0x011d00,22, @@ -468,14 +466,13 @@ 0x013964,4, 0x013978,5, 0x013990,2, -0x013a00,6, -0x013a24,68, +0x013a00,77, 0x013c00,31, 0x013c80,7, 0x013ca0,33, 0x013d40,6, 0x013d64,1, -0x013d70,17, +0x013d70,16, 0x013dc0,14, 0x013e04,57, 0x014000,2, @@ -485,13 +482,13 @@ 0x014134,2, 0x01414c,1, 0x014170,3, -0x014200,3, +0x014200,1, 0x014210,2, -0x014220,3, +0x014220,1, 0x014230,2, 0x0142c0,1, 0x014400,64, -0x018000,3, +0x018000,1, 0x018010,2, 0x018020,3, 0x018030,7, @@ -506,7 +503,7 @@ 0x018490,7, 0x0184b0,4, 0x0184c4,1, -0x0184cc,8, +0x0184cc,6, 0x0184f0,2, 0x018500,5, 0x018520,33, @@ -515,7 +512,7 @@ 0x018a08,7, 0x018a2c,38, 0x018ac8,12, -0x018b00,3, +0x018b00,1, 0x018b10,2, 0x018b20,8, 0x018b44,1, @@ -532,7 +529,7 @@ 0x018c60,14, 0x018d04,1, 0x018d24,9, -0x018d60,3, +0x018d60,1, 0x018d70,2, 0x018da0,2, 0x018db4,1, @@ -541,7 +538,7 @@ 0x018df0,15, 0x018e30,5, 0x018e60,14, -0x018f60,3, +0x018f60,1, 0x018f70,2, 0x018fa0,2, 0x018fb4,1, @@ -558,7 +555,7 @@ 0x019520,25, 0x019594,13, 0x0195cc,6, -0x0195fc,4, +0x0195fc,2, 0x019610,2, 0x019804,1, 0x019814,3, @@ -568,15 +565,15 @@ 0x019890,7, 0x0198b0,4, 0x0198c4,1, -0x0198cc,8, +0x0198cc,6, 0x0198f0,2, 0x019900,5, 0x019920,49, 0x019c04,1, 0x019c10,24, -0x019c80,3, +0x019c80,1, 0x019c90,2, -0x019ca0,3, +0x019ca0,1, 0x019cb0,2, 0x019cc8,5, 0x019d00,22, @@ -632,14 +629,13 @@ 0x01b964,4, 0x01b978,5, 0x01b990,2, -0x01ba00,6, -0x01ba24,68, +0x01ba00,77, 0x01bc00,31, 0x01bc80,7, 0x01bca0,33, 0x01bd40,6, 0x01bd64,1, -0x01bd70,17, +0x01bd70,16, 0x01bdc0,14, 0x01be04,57, 0x01c000,2, @@ -649,13 +645,13 @@ 0x01c134,2, 0x01c14c,1, 0x01c170,3, -0x01c200,3, +0x01c200,1, 0x01c210,2, -0x01c220,3, +0x01c220,1, 0x01c230,2, 0x01c2c0,1, 0x01c400,64, -0x020000,3, +0x020000,1, 0x020010,2, 0x020020,3, 0x020030,7, @@ -670,7 +666,7 @@ 0x020490,7, 0x0204b0,4, 0x0204c4,1, -0x0204cc,8, +0x0204cc,6, 0x0204f0,2, 0x020500,5, 0x020520,33, @@ -679,7 +675,7 @@ 0x020a08,7, 0x020a2c,38, 0x020ac8,12, -0x020b00,3, +0x020b00,1, 0x020b10,2, 0x020b20,8, 0x020b44,1, @@ -696,7 +692,7 @@ 0x020c60,14, 0x020d04,1, 0x020d24,9, -0x020d60,3, +0x020d60,1, 0x020d70,2, 0x020da0,2, 0x020db4,1, @@ -705,7 +701,7 @@ 0x020df0,15, 0x020e30,5, 0x020e60,14, -0x020f60,3, +0x020f60,1, 0x020f70,2, 0x020fa0,2, 0x020fb4,1, @@ -722,7 +718,7 @@ 0x021520,25, 0x021594,13, 0x0215cc,6, -0x0215fc,4, +0x0215fc,2, 0x021610,2, 0x021804,1, 0x021814,3, @@ -732,15 +728,15 @@ 0x021890,7, 0x0218b0,4, 0x0218c4,1, -0x0218cc,8, +0x0218cc,6, 0x0218f0,2, 0x021900,5, 0x021920,49, 0x021c04,1, 0x021c10,24, -0x021c80,3, +0x021c80,1, 0x021c90,2, -0x021ca0,3, +0x021ca0,1, 0x021cb0,2, 0x021cc8,5, 0x021d00,22, @@ -796,14 +792,13 @@ 0x023964,4, 0x023978,5, 0x023990,2, -0x023a00,6, -0x023a24,68, +0x023a00,77, 0x023c00,31, 0x023c80,7, 0x023ca0,33, 0x023d40,6, 0x023d64,1, -0x023d70,17, +0x023d70,16, 0x023dc0,14, 0x023e04,57, 0x024000,2, @@ -813,13 +808,13 @@ 0x024134,2, 0x02414c,1, 0x024170,3, -0x024200,3, +0x024200,1, 0x024210,2, -0x024220,3, +0x024220,1, 0x024230,2, 0x0242c0,1, 0x024400,64, -0x028000,3, +0x028000,1, 0x028010,2, 0x028020,3, 0x028030,7, @@ -834,7 +829,7 @@ 0x028490,7, 0x0284b0,4, 0x0284c4,1, -0x0284cc,8, +0x0284cc,6, 0x0284f0,2, 0x028500,5, 0x028520,33, @@ -843,7 +838,7 @@ 0x028a08,7, 0x028a2c,38, 0x028ac8,12, -0x028b00,3, +0x028b00,1, 0x028b10,2, 0x028b20,8, 0x028b44,1, @@ -860,7 +855,7 @@ 0x028c60,14, 0x028d04,1, 0x028d24,9, -0x028d60,3, +0x028d60,1, 0x028d70,2, 0x028da0,2, 0x028db4,1, @@ -869,7 +864,7 @@ 0x028df0,15, 0x028e30,5, 0x028e60,14, -0x028f60,3, +0x028f60,1, 0x028f70,2, 0x028fa0,2, 0x028fb4,1, @@ -886,7 +881,7 @@ 0x029520,25, 0x029594,13, 0x0295cc,6, -0x0295fc,4, +0x0295fc,2, 0x029610,2, 0x029804,1, 0x029814,3, @@ -896,15 +891,15 @@ 0x029890,7, 0x0298b0,4, 0x0298c4,1, -0x0298cc,8, +0x0298cc,6, 0x0298f0,2, 0x029900,5, 0x029920,49, 0x029c04,1, 0x029c10,24, -0x029c80,3, +0x029c80,1, 0x029c90,2, -0x029ca0,3, +0x029ca0,1, 0x029cb0,2, 0x029cc8,5, 0x029d00,22, @@ -960,14 +955,13 @@ 0x02b964,4, 0x02b978,5, 0x02b990,2, -0x02ba00,6, -0x02ba24,68, +0x02ba00,77, 0x02bc00,31, 0x02bc80,7, 0x02bca0,33, 0x02bd40,6, 0x02bd64,1, -0x02bd70,17, +0x02bd70,16, 0x02bdc0,14, 0x02be04,57, 0x02c000,2, @@ -977,9 +971,9 @@ 0x02c134,2, 0x02c14c,1, 0x02c170,3, -0x02c200,3, +0x02c200,1, 0x02c210,2, -0x02c220,3, +0x02c220,1, 0x02c230,2, 0x02c2c0,1, 0x02c400,64, @@ -990,9 +984,9 @@ 0x030134,2, 0x03014c,1, 0x030170,2, -0x030200,3, +0x030200,1, 0x030210,2, -0x030220,3, +0x030220,1, 0x030230,2, 0x030420,3, 0x030430,4, @@ -1031,7 +1025,8 @@ 0x030ddc,9, 0x03100c,12, 0x031040,5, -0x03105c,6, +0x03105c,5, +0x031074,3, 0x031088,42, 0x0311fc,49, 0x031300,3, @@ -1045,15 +1040,15 @@ 0x031890,3, 0x0318a0,3, 0x0318b0,2, -0x031a00,3, +0x031a00,1, 0x031a10,2, -0x031a20,3, +0x031a20,1, 0x031a30,2, -0x031a40,3, +0x031a40,1, 0x031a50,2, -0x031a80,3, +0x031a80,1, 0x031a90,2, -0x031aa0,3, +0x031aa0,1, 0x031ab0,2, 0x031ac0,3, 0x031b04,1, @@ -1173,9 +1168,9 @@ 0x034134,2, 0x03414c,1, 0x034170,2, -0x034200,3, +0x034200,1, 0x034210,2, -0x034220,3, +0x034220,1, 0x034230,2, 0x034420,3, 0x034430,4, @@ -1214,7 +1209,8 @@ 0x034ddc,9, 0x03500c,12, 0x035040,5, -0x03505c,6, +0x03505c,5, +0x035074,3, 0x035088,42, 0x0351fc,49, 0x035300,3, @@ -1228,15 +1224,15 @@ 0x035890,3, 0x0358a0,3, 0x0358b0,2, -0x035a00,3, +0x035a00,1, 0x035a10,2, -0x035a20,3, +0x035a20,1, 0x035a30,2, -0x035a40,3, +0x035a40,1, 0x035a50,2, -0x035a80,3, +0x035a80,1, 0x035a90,2, -0x035aa0,3, +0x035aa0,1, 0x035ab0,2, 0x035ac0,3, 0x035b04,1, @@ -1367,66 +1363,83 @@ 0x038280,9, 0x0382b0,3, 0x0382c0,3, -0x040000,4, +0x040000,3, 0x04001c,2, 0x040030,1, 0x040048,2, 0x040058,2, -0x040068,31, +0x040068,11, +0x04009c,2, +0x0400ac,14, 0x040180,1, -0x0401c0,4, -0x0401e0,5, +0x0401c0,1, +0x0401c8,2, +0x0401e0,1, +0x0401e8,3, 0x0401f8,1, -0x040200,4, +0x040200,3, 0x04021c,2, 0x040230,1, 0x040248,2, 0x040258,2, -0x040268,31, +0x040268,11, +0x04029c,2, +0x0402ac,14, 0x040380,1, -0x0403c0,4, -0x0403e0,5, +0x0403c0,1, +0x0403c8,2, +0x0403e0,1, +0x0403e8,3, 0x0403f8,1, -0x040400,4, +0x040400,3, 0x04041c,2, 0x040430,1, 0x040448,2, 0x040458,2, -0x040468,31, +0x040468,11, +0x04049c,2, +0x0404ac,14, 0x040580,1, -0x0405c0,4, -0x0405e0,5, +0x0405c0,1, +0x0405c8,2, +0x0405e0,1, +0x0405e8,3, 0x0405f8,1, -0x040600,4, +0x040600,3, 0x04061c,2, 0x040630,1, 0x040648,2, 0x040658,2, -0x040668,31, +0x040668,11, +0x04069c,2, +0x0406ac,14, 0x040780,1, -0x0407c0,4, -0x0407e0,5, +0x0407c0,1, +0x0407c8,2, +0x0407e0,1, +0x0407e8,3, 0x0407f8,1, 0x040800,128, 0x040a04,2, 0x040a18,2, 0x040c04,9, -0x040c48,1, +0x040c44,2, 0x040c50,10, 0x040c7c,1, +0x040c84,1, 0x040c8c,6, 0x040cb0,3, -0x040cc0,3, +0x040cc0,1, 0x040cd0,2, -0x040ce0,3, +0x040ce0,1, 0x040cf0,2, -0x040d00,3, +0x040d00,1, 0x040d10,2, -0x040d20,3, +0x040d20,1, 0x040d30,2, -0x040d40,3, +0x040d40,1, 0x040d50,2, -0x040d60,3, +0x040d60,1, 0x040d70,2, 0x040d88,2, 0x040da0,1, @@ -1468,9 +1481,11 @@ 0x0440e8,2, 0x044100,64, 0x050040,4, -0x050060,20, +0x050060,3, +0x050070,16, 0x0500d8,14, -0x050120,33, +0x050120,3, +0x050130,29, 0x0501b8,6, 0x050200,36, 0x051100,14, @@ -1483,15 +1498,14 @@ 0x051900,14, 0x053c00,18, 0x053c60,5, -0x053c8c,3, -0x053c9c,4, +0x053c8c,8, 0x053d00,1, 0x053e00,16, 0x053e60,5, -0x053e8c,3, -0x053e9c,4, +0x053e8c,8, +0x053f04,1, 0x053f0c,7, -0x053f40,2, +0x053f40,1, 0x053ffc,6, 0x054020,1, 0x054030,1, @@ -1747,7 +1761,7 @@ 0x054fd0,1, 0x054fe0,1, 0x054ff0,1, -0x055000,1, +0x055000,8, 0x056000,5, 0x056020,1, 0x056030,1, @@ -2003,11 +2017,10 @@ 0x056fd0,1, 0x056fe0,1, 0x056ff0,1, -0x057000,1, -0x057020,1, -0x057100,1, -0x057120,1, -0x057140,1, +0x057000,16, +0x057100,8, +0x057124,7, +0x057144,7, 0x057200,3, 0x0577f8,2, 0x058000,3, @@ -2017,11 +2030,11 @@ 0x058134,3, 0x05814c,1, 0x058170,3, -0x058200,3, +0x058200,1, 0x058210,2, -0x058220,3, +0x058220,1, 0x058230,2, -0x058240,3, +0x058240,1, 0x058250,2, 0x058400,32, 0x058484,4, @@ -2031,23 +2044,23 @@ 0x070290,4, 0x070300,1, 0x070314,4, -0x070c00,3, +0x070c00,1, 0x070c24,1, 0x070c2c,1, 0x070c40,2, 0x070e00,12, 0x070e34,1, -0x070e40,3, +0x070e40,1, 0x070e50,2, 0x071000,7, 0x072000,7, 0x073000,840, 0x074004,3, -0x074200,3, +0x074200,1, 0x074210,2, -0x074220,3, +0x074220,1, 0x074230,2, -0x074400,48, +0x074480,16, 0x0744c4,35, 0x074560,15, 0x080000,2, @@ -2057,17 +2070,17 @@ 0x080134,2, 0x08014c,1, 0x080170,2, -0x080200,3, +0x080200,1, 0x080210,2, -0x080220,3, +0x080220,1, 0x080230,2, -0x080400,3, +0x080400,1, 0x080410,2, 0x080420,3, 0x080430,22, 0x0804ac,1, 0x0804c0,6, -0x080500,3, +0x080500,1, 0x080510,2, 0x080520,3, 0x080540,8, @@ -2082,110 +2095,134 @@ 0x080800,5, 0x080820,5, 0x080890,10, -0x0808e0,3, +0x0808e0,1, 0x0808f0,2, 0x080900,5, 0x080920,5, 0x080990,10, -0x0809e0,3, +0x0809e0,1, 0x0809f0,2, -0x080a00,3, +0x080a00,1, 0x080a10,2, -0x080a20,3, +0x080a20,1, 0x080a30,2, 0x080a48,3, -0x080a80,18, +0x080a80,3, +0x080a90,1, +0x080a98,12, 0x080b04,2, 0x080b14,3, 0x080b24,2, 0x080b34,3, -0x080b80,11, +0x080b80,5, +0x080b98,3, 0x080bb0,2, -0x080bc0,11, +0x080bc0,5, +0x080bd8,3, 0x080bf0,2, -0x080c00,23, -0x080c80,27, +0x080c00,10, +0x080c2c,12, +0x080c80,26, 0x080d00,2, 0x080d20,1, -0x080e00,23, -0x080e80,27, +0x080e00,10, +0x080e2c,12, +0x080e80,26, 0x080f00,2, 0x080f20,1, 0x081000,5, 0x081020,5, 0x081090,10, -0x0810e0,3, +0x0810e0,1, 0x0810f0,2, 0x081100,5, 0x081120,5, 0x081190,10, -0x0811e0,3, +0x0811e0,1, 0x0811f0,2, -0x081200,3, +0x081200,1, 0x081210,2, -0x081220,3, +0x081220,1, 0x081230,2, 0x081248,3, -0x081280,18, +0x081280,3, +0x081290,1, +0x081298,12, 0x081304,2, 0x081314,3, 0x081324,2, 0x081334,3, -0x081380,11, +0x081380,5, +0x081398,3, 0x0813b0,2, -0x0813c0,11, +0x0813c0,5, +0x0813d8,3, 0x0813f0,2, -0x081400,23, -0x081480,27, +0x081400,10, +0x08142c,12, +0x081480,26, 0x081500,2, 0x081520,1, -0x081600,23, -0x081680,27, +0x081600,10, +0x08162c,12, +0x081680,26, 0x081700,2, 0x081720,1, 0x081800,5, 0x081820,5, 0x081890,10, -0x0818e0,3, +0x0818e0,1, 0x0818f0,2, 0x081900,5, 0x081920,5, 0x081990,10, -0x0819e0,3, +0x0819e0,1, 0x0819f0,2, -0x081a00,3, +0x081a00,1, 0x081a10,2, -0x081a20,3, +0x081a20,1, 0x081a30,2, 0x081a48,3, -0x081a80,18, +0x081a80,3, +0x081a90,1, +0x081a98,12, 0x081b04,2, 0x081b14,3, 0x081b24,2, 0x081b34,3, -0x081b80,11, +0x081b80,5, +0x081b98,3, 0x081bb0,2, -0x081bc0,11, +0x081bc0,5, +0x081bd8,3, 0x081bf0,2, -0x081c00,23, -0x081c80,27, +0x081c00,10, +0x081c2c,12, +0x081c80,26, 0x081d00,2, 0x081d20,1, -0x081e00,23, -0x081e80,27, +0x081e00,10, +0x081e2c,12, +0x081e80,26, 0x081f00,2, 0x081f20,1, -0x082000,16, +0x082000,7, +0x082020,8, 0x082044,8, -0x082080,16, +0x082080,7, +0x0820a0,8, 0x0820c4,8, -0x082100,16, +0x082100,7, +0x082120,8, 0x082144,8, -0x082180,16, +0x082180,7, +0x0821a0,8, 0x0821c4,8, -0x082200,16, +0x082200,7, +0x082220,8, 0x082244,8, -0x082280,16, +0x082280,7, +0x0822a0,8, 0x0822c4,8, 0x082400,1, 0x082418,1, @@ -2194,16 +2231,16 @@ 0x082534,1, 0x08254c,1, 0x082570,2, -0x082600,3, +0x082600,1, 0x082610,2, 0x082804,15, 0x082844,15, 0x082884,15, 0x0828c4,15, 0x082904,15, -0x082944,18, +0x082944,16, 0x082990,2, -0x0829a0,3, +0x0829a0,1, 0x0829b0,2, 0x0829c0,2, 0x082a00,400, @@ -2218,13 +2255,13 @@ 0x0832c0,2, 0x0832cc,2, 0x0832d8,3, -0x083300,3, +0x083300,1, 0x083310,2, -0x083320,3, +0x083320,1, 0x083330,2, -0x083340,3, +0x083340,1, 0x083350,2, -0x083360,3, +0x083360,1, 0x083370,2, 0x083380,1, 0x083400,16, @@ -2239,13 +2276,13 @@ 0x0836c0,2, 0x0836cc,2, 0x0836d8,3, -0x083700,3, +0x083700,1, 0x083710,2, -0x083720,3, +0x083720,1, 0x083730,2, -0x083740,3, +0x083740,1, 0x083750,2, -0x083760,3, +0x083760,1, 0x083770,2, 0x083780,1, 0x083800,16, @@ -2260,13 +2297,13 @@ 0x083ac0,2, 0x083acc,2, 0x083ad8,3, -0x083b00,3, +0x083b00,1, 0x083b10,2, -0x083b20,3, +0x083b20,1, 0x083b30,2, -0x083b40,3, +0x083b40,1, 0x083b50,2, -0x083b60,3, +0x083b60,1, 0x083b70,2, 0x083b80,1, 0x083c00,18, @@ -2296,39 +2333,36 @@ 0x083f44,1, 0x083f50,4, 0x083fa0,3, -0x084000,9, +0x084000,5, +0x084018,3, 0x084080,2, 0x08408c,1, -0x084094,1, -0x0840a0,11, +0x0840a0,9, 0x0840d0,2, 0x0840e0,1, 0x0840e8,1, 0x084100,2, 0x08410c,1, -0x084114,1, -0x084120,11, +0x084120,9, 0x084150,2, 0x084160,1, 0x084168,1, 0x084180,2, 0x08418c,1, -0x084194,1, -0x0841a0,11, +0x0841a0,9, 0x0841d0,2, 0x0841e0,1, 0x0841e8,1, 0x084200,2, 0x08420c,1, -0x084214,1, -0x084220,11, +0x084220,9, 0x084250,2, 0x084260,1, 0x084268,1, -0x084280,3, +0x084284,2, 0x0842a8,2, 0x0842b4,1, -0x0842c0,3, +0x0842c4,2, 0x0842e8,2, 0x0842f4,1, 0x084400,3, @@ -2348,47 +2382,44 @@ 0x084600,15, 0x084640,3, 0x084650,3, -0x084660,3, +0x084660,1, 0x084670,2, -0x084680,3, +0x084680,1, 0x084690,2, 0x0846c0,4, 0x0846d4,8, 0x084700,4, 0x084714,8, -0x084800,9, +0x084800,5, +0x084818,3, 0x084880,2, 0x08488c,1, -0x084894,1, -0x0848a0,11, +0x0848a0,9, 0x0848d0,2, 0x0848e0,1, 0x0848e8,1, 0x084900,2, 0x08490c,1, -0x084914,1, -0x084920,11, +0x084920,9, 0x084950,2, 0x084960,1, 0x084968,1, 0x084980,2, 0x08498c,1, -0x084994,1, -0x0849a0,11, +0x0849a0,9, 0x0849d0,2, 0x0849e0,1, 0x0849e8,1, 0x084a00,2, 0x084a0c,1, -0x084a14,1, -0x084a20,11, +0x084a20,9, 0x084a50,2, 0x084a60,1, 0x084a68,1, -0x084a80,3, +0x084a84,2, 0x084aa8,2, 0x084ab4,1, -0x084ac0,3, +0x084ac4,2, 0x084ae8,2, 0x084af4,1, 0x084c00,3, @@ -2408,47 +2439,44 @@ 0x084e00,15, 0x084e40,3, 0x084e50,3, -0x084e60,3, +0x084e60,1, 0x084e70,2, -0x084e80,3, +0x084e80,1, 0x084e90,2, 0x084ec0,4, 0x084ed4,8, 0x084f00,4, 0x084f14,8, -0x085000,9, +0x085000,5, +0x085018,3, 0x085080,2, 0x08508c,1, -0x085094,1, -0x0850a0,11, +0x0850a0,9, 0x0850d0,2, 0x0850e0,1, 0x0850e8,1, 0x085100,2, 0x08510c,1, -0x085114,1, -0x085120,11, +0x085120,9, 0x085150,2, 0x085160,1, 0x085168,1, 0x085180,2, 0x08518c,1, -0x085194,1, -0x0851a0,11, +0x0851a0,9, 0x0851d0,2, 0x0851e0,1, 0x0851e8,1, 0x085200,2, 0x08520c,1, -0x085214,1, -0x085220,11, +0x085220,9, 0x085250,2, 0x085260,1, 0x085268,1, -0x085280,3, +0x085284,2, 0x0852a8,2, 0x0852b4,1, -0x0852c0,3, +0x0852c4,2, 0x0852e8,2, 0x0852f4,1, 0x085400,3, @@ -2468,9 +2496,9 @@ 0x085600,15, 0x085640,3, 0x085650,3, -0x085660,3, +0x085660,1, 0x085670,2, -0x085680,3, +0x085680,1, 0x085690,2, 0x0856c0,4, 0x0856d4,8, @@ -2479,29 +2507,35 @@ 0x085800,31, 0x085880,8, 0x0858a4,1, -0x0858b4,22, +0x0858b4,20, 0x085910,2, 0x085920,3, 0x085934,1, -0x08593c,4, +0x08593c,2, 0x085950,2, 0x085a00,11, 0x085a4c,8, 0x085a70,2, 0x085a7c,33, 0x085c00,8, -0x085c40,14, +0x085c40,2, +0x085c4c,11, 0x085c80,8, -0x085cc0,14, +0x085cc0,2, +0x085ccc,11, 0x085d00,8, -0x085d40,14, +0x085d40,2, +0x085d4c,11, 0x085d80,8, -0x085dc0,14, +0x085dc0,2, +0x085dcc,11, 0x085e00,8, -0x085e40,14, +0x085e40,2, +0x085e4c,11, 0x085e80,8, -0x085ec0,14, -0x085f00,11, +0x085ec0,2, +0x085ecc,11, +0x085f00,9, 0x085f30,2, 0x085f40,49, 0x086018,1, @@ -2510,120 +2544,132 @@ 0x086134,1, 0x08614c,1, 0x086170,2, -0x086200,3, +0x086200,1, 0x086210,2, 0x086400,5, 0x086418,9, 0x086440,5, -0x086460,3, +0x086460,1, 0x086470,2, 0x086500,5, 0x086518,9, 0x086540,5, -0x086560,3, +0x086560,1, 0x086570,2, 0x086600,5, 0x086618,9, 0x086640,5, -0x086660,3, +0x086660,1, 0x086670,2, 0x086700,1, 0x086800,6, 0x08681c,3, -0x08682c,12, +0x08682c,3, +0x08683c,8, 0x086860,1, 0x086868,1, 0x086870,2, -0x086880,3, +0x086880,1, 0x086890,2, -0x0868a0,3, +0x0868a0,1, 0x0868b0,2, -0x0868c0,3, +0x0868c0,1, 0x0868d0,2, -0x0868e0,3, +0x0868e0,1, 0x0868f0,2, 0x086900,29, -0x086980,29, +0x086980,27, +0x0869f0,1, 0x086c00,6, 0x086c1c,3, -0x086c2c,12, +0x086c2c,3, +0x086c3c,8, 0x086c60,1, 0x086c68,1, 0x086c70,2, -0x086c80,3, +0x086c80,1, 0x086c90,2, -0x086ca0,3, +0x086ca0,1, 0x086cb0,2, -0x086cc0,3, +0x086cc0,1, 0x086cd0,2, -0x086ce0,3, +0x086ce0,1, 0x086cf0,2, 0x086d00,29, -0x086d80,29, +0x086d80,27, +0x086df0,1, 0x087000,6, 0x08701c,3, -0x08702c,12, +0x08702c,3, +0x08703c,8, 0x087060,1, 0x087068,1, 0x087070,2, -0x087080,3, +0x087080,1, 0x087090,2, -0x0870a0,3, +0x0870a0,1, 0x0870b0,2, -0x0870c0,3, +0x0870c0,1, 0x0870d0,2, -0x0870e0,3, +0x0870e0,1, 0x0870f0,2, 0x087100,29, -0x087180,29, +0x087180,27, +0x0871f0,1, 0x087400,6, 0x08741c,3, -0x08742c,12, +0x08742c,3, +0x08743c,8, 0x087460,1, 0x087468,1, 0x087470,2, -0x087480,3, +0x087480,1, 0x087490,2, -0x0874a0,3, +0x0874a0,1, 0x0874b0,2, -0x0874c0,3, +0x0874c0,1, 0x0874d0,2, -0x0874e0,3, +0x0874e0,1, 0x0874f0,2, 0x087500,29, -0x087580,29, +0x087580,27, +0x0875f0,1, 0x087800,6, 0x08781c,3, -0x08782c,12, +0x08782c,3, +0x08783c,8, 0x087860,1, 0x087868,1, 0x087870,2, -0x087880,3, +0x087880,1, 0x087890,2, -0x0878a0,3, +0x0878a0,1, 0x0878b0,2, -0x0878c0,3, +0x0878c0,1, 0x0878d0,2, -0x0878e0,3, +0x0878e0,1, 0x0878f0,2, 0x087900,29, -0x087980,29, +0x087980,27, +0x0879f0,1, 0x087c00,6, 0x087c1c,3, -0x087c2c,12, +0x087c2c,3, +0x087c3c,8, 0x087c60,1, 0x087c68,1, 0x087c70,2, -0x087c80,3, +0x087c80,1, 0x087c90,2, -0x087ca0,3, +0x087ca0,1, 0x087cb0,2, -0x087cc0,3, +0x087cc0,1, 0x087cd0,2, -0x087ce0,3, +0x087ce0,1, 0x087cf0,2, 0x087d00,29, -0x087d80,29, +0x087d80,27, +0x087df0,1, 0x088000,2, 0x088018,2, 0x088034,2, @@ -2631,17 +2677,17 @@ 0x088134,2, 0x08814c,1, 0x088170,2, -0x088200,3, +0x088200,1, 0x088210,2, -0x088220,3, +0x088220,1, 0x088230,2, -0x088400,3, +0x088400,1, 0x088410,2, 0x088420,3, 0x088430,22, 0x0884ac,1, 0x0884c0,6, -0x088500,3, +0x088500,1, 0x088510,2, 0x088520,3, 0x088540,8, @@ -2656,110 +2702,134 @@ 0x088800,5, 0x088820,5, 0x088890,10, -0x0888e0,3, +0x0888e0,1, 0x0888f0,2, 0x088900,5, 0x088920,5, 0x088990,10, -0x0889e0,3, +0x0889e0,1, 0x0889f0,2, -0x088a00,3, +0x088a00,1, 0x088a10,2, -0x088a20,3, +0x088a20,1, 0x088a30,2, 0x088a48,3, -0x088a80,18, +0x088a80,3, +0x088a90,1, +0x088a98,12, 0x088b04,2, 0x088b14,3, 0x088b24,2, 0x088b34,3, -0x088b80,11, +0x088b80,5, +0x088b98,3, 0x088bb0,2, -0x088bc0,11, +0x088bc0,5, +0x088bd8,3, 0x088bf0,2, -0x088c00,23, -0x088c80,27, +0x088c00,10, +0x088c2c,12, +0x088c80,26, 0x088d00,2, 0x088d20,1, -0x088e00,23, -0x088e80,27, +0x088e00,10, +0x088e2c,12, +0x088e80,26, 0x088f00,2, 0x088f20,1, 0x089000,5, 0x089020,5, 0x089090,10, -0x0890e0,3, +0x0890e0,1, 0x0890f0,2, 0x089100,5, 0x089120,5, 0x089190,10, -0x0891e0,3, +0x0891e0,1, 0x0891f0,2, -0x089200,3, +0x089200,1, 0x089210,2, -0x089220,3, +0x089220,1, 0x089230,2, 0x089248,3, -0x089280,18, +0x089280,3, +0x089290,1, +0x089298,12, 0x089304,2, 0x089314,3, 0x089324,2, 0x089334,3, -0x089380,11, +0x089380,5, +0x089398,3, 0x0893b0,2, -0x0893c0,11, +0x0893c0,5, +0x0893d8,3, 0x0893f0,2, -0x089400,23, -0x089480,27, +0x089400,10, +0x08942c,12, +0x089480,26, 0x089500,2, 0x089520,1, -0x089600,23, -0x089680,27, +0x089600,10, +0x08962c,12, +0x089680,26, 0x089700,2, 0x089720,1, 0x089800,5, 0x089820,5, 0x089890,10, -0x0898e0,3, +0x0898e0,1, 0x0898f0,2, 0x089900,5, 0x089920,5, 0x089990,10, -0x0899e0,3, +0x0899e0,1, 0x0899f0,2, -0x089a00,3, +0x089a00,1, 0x089a10,2, -0x089a20,3, +0x089a20,1, 0x089a30,2, 0x089a48,3, -0x089a80,18, +0x089a80,3, +0x089a90,1, +0x089a98,12, 0x089b04,2, 0x089b14,3, 0x089b24,2, 0x089b34,3, -0x089b80,11, +0x089b80,5, +0x089b98,3, 0x089bb0,2, -0x089bc0,11, +0x089bc0,5, +0x089bd8,3, 0x089bf0,2, -0x089c00,23, -0x089c80,27, +0x089c00,10, +0x089c2c,12, +0x089c80,26, 0x089d00,2, 0x089d20,1, -0x089e00,23, -0x089e80,27, +0x089e00,10, +0x089e2c,12, +0x089e80,26, 0x089f00,2, 0x089f20,1, -0x08a000,16, +0x08a000,7, +0x08a020,8, 0x08a044,8, -0x08a080,16, +0x08a080,7, +0x08a0a0,8, 0x08a0c4,8, -0x08a100,16, +0x08a100,7, +0x08a120,8, 0x08a144,8, -0x08a180,16, +0x08a180,7, +0x08a1a0,8, 0x08a1c4,8, -0x08a200,16, +0x08a200,7, +0x08a220,8, 0x08a244,8, -0x08a280,16, +0x08a280,7, +0x08a2a0,8, 0x08a2c4,8, 0x08a400,1, 0x08a418,1, @@ -2768,16 +2838,16 @@ 0x08a534,1, 0x08a54c,1, 0x08a570,2, -0x08a600,3, +0x08a600,1, 0x08a610,2, 0x08a804,15, 0x08a844,15, 0x08a884,15, 0x08a8c4,15, 0x08a904,15, -0x08a944,18, +0x08a944,16, 0x08a990,2, -0x08a9a0,3, +0x08a9a0,1, 0x08a9b0,2, 0x08a9c0,2, 0x08aa00,400, @@ -2792,13 +2862,13 @@ 0x08b2c0,2, 0x08b2cc,2, 0x08b2d8,3, -0x08b300,3, +0x08b300,1, 0x08b310,2, -0x08b320,3, +0x08b320,1, 0x08b330,2, -0x08b340,3, +0x08b340,1, 0x08b350,2, -0x08b360,3, +0x08b360,1, 0x08b370,2, 0x08b380,1, 0x08b400,16, @@ -2813,13 +2883,13 @@ 0x08b6c0,2, 0x08b6cc,2, 0x08b6d8,3, -0x08b700,3, +0x08b700,1, 0x08b710,2, -0x08b720,3, +0x08b720,1, 0x08b730,2, -0x08b740,3, +0x08b740,1, 0x08b750,2, -0x08b760,3, +0x08b760,1, 0x08b770,2, 0x08b780,1, 0x08b800,16, @@ -2834,13 +2904,13 @@ 0x08bac0,2, 0x08bacc,2, 0x08bad8,3, -0x08bb00,3, +0x08bb00,1, 0x08bb10,2, -0x08bb20,3, +0x08bb20,1, 0x08bb30,2, -0x08bb40,3, +0x08bb40,1, 0x08bb50,2, -0x08bb60,3, +0x08bb60,1, 0x08bb70,2, 0x08bb80,1, 0x08bc00,18, @@ -2870,39 +2940,36 @@ 0x08bf44,1, 0x08bf50,4, 0x08bfa0,3, -0x08c000,9, +0x08c000,5, +0x08c018,3, 0x08c080,2, 0x08c08c,1, -0x08c094,1, -0x08c0a0,11, +0x08c0a0,9, 0x08c0d0,2, 0x08c0e0,1, 0x08c0e8,1, 0x08c100,2, 0x08c10c,1, -0x08c114,1, -0x08c120,11, +0x08c120,9, 0x08c150,2, 0x08c160,1, 0x08c168,1, 0x08c180,2, 0x08c18c,1, -0x08c194,1, -0x08c1a0,11, +0x08c1a0,9, 0x08c1d0,2, 0x08c1e0,1, 0x08c1e8,1, 0x08c200,2, 0x08c20c,1, -0x08c214,1, -0x08c220,11, +0x08c220,9, 0x08c250,2, 0x08c260,1, 0x08c268,1, -0x08c280,3, +0x08c284,2, 0x08c2a8,2, 0x08c2b4,1, -0x08c2c0,3, +0x08c2c4,2, 0x08c2e8,2, 0x08c2f4,1, 0x08c400,3, @@ -2922,47 +2989,44 @@ 0x08c600,15, 0x08c640,3, 0x08c650,3, -0x08c660,3, +0x08c660,1, 0x08c670,2, -0x08c680,3, +0x08c680,1, 0x08c690,2, 0x08c6c0,4, 0x08c6d4,8, 0x08c700,4, 0x08c714,8, -0x08c800,9, +0x08c800,5, +0x08c818,3, 0x08c880,2, 0x08c88c,1, -0x08c894,1, -0x08c8a0,11, +0x08c8a0,9, 0x08c8d0,2, 0x08c8e0,1, 0x08c8e8,1, 0x08c900,2, 0x08c90c,1, -0x08c914,1, -0x08c920,11, +0x08c920,9, 0x08c950,2, 0x08c960,1, 0x08c968,1, 0x08c980,2, 0x08c98c,1, -0x08c994,1, -0x08c9a0,11, +0x08c9a0,9, 0x08c9d0,2, 0x08c9e0,1, 0x08c9e8,1, 0x08ca00,2, 0x08ca0c,1, -0x08ca14,1, -0x08ca20,11, +0x08ca20,9, 0x08ca50,2, 0x08ca60,1, 0x08ca68,1, -0x08ca80,3, +0x08ca84,2, 0x08caa8,2, 0x08cab4,1, -0x08cac0,3, +0x08cac4,2, 0x08cae8,2, 0x08caf4,1, 0x08cc00,3, @@ -2982,47 +3046,44 @@ 0x08ce00,15, 0x08ce40,3, 0x08ce50,3, -0x08ce60,3, +0x08ce60,1, 0x08ce70,2, -0x08ce80,3, +0x08ce80,1, 0x08ce90,2, 0x08cec0,4, 0x08ced4,8, 0x08cf00,4, 0x08cf14,8, -0x08d000,9, +0x08d000,5, +0x08d018,3, 0x08d080,2, 0x08d08c,1, -0x08d094,1, -0x08d0a0,11, +0x08d0a0,9, 0x08d0d0,2, 0x08d0e0,1, 0x08d0e8,1, 0x08d100,2, 0x08d10c,1, -0x08d114,1, -0x08d120,11, +0x08d120,9, 0x08d150,2, 0x08d160,1, 0x08d168,1, 0x08d180,2, 0x08d18c,1, -0x08d194,1, -0x08d1a0,11, +0x08d1a0,9, 0x08d1d0,2, 0x08d1e0,1, 0x08d1e8,1, 0x08d200,2, 0x08d20c,1, -0x08d214,1, -0x08d220,11, +0x08d220,9, 0x08d250,2, 0x08d260,1, 0x08d268,1, -0x08d280,3, +0x08d284,2, 0x08d2a8,2, 0x08d2b4,1, -0x08d2c0,3, +0x08d2c4,2, 0x08d2e8,2, 0x08d2f4,1, 0x08d400,3, @@ -3042,9 +3103,9 @@ 0x08d600,15, 0x08d640,3, 0x08d650,3, -0x08d660,3, +0x08d660,1, 0x08d670,2, -0x08d680,3, +0x08d680,1, 0x08d690,2, 0x08d6c0,4, 0x08d6d4,8, @@ -3053,29 +3114,35 @@ 0x08d800,31, 0x08d880,8, 0x08d8a4,1, -0x08d8b4,22, +0x08d8b4,20, 0x08d910,2, 0x08d920,3, 0x08d934,1, -0x08d93c,4, +0x08d93c,2, 0x08d950,2, 0x08da00,11, 0x08da4c,8, 0x08da70,2, 0x08da7c,33, 0x08dc00,8, -0x08dc40,14, +0x08dc40,2, +0x08dc4c,11, 0x08dc80,8, -0x08dcc0,14, +0x08dcc0,2, +0x08dccc,11, 0x08dd00,8, -0x08dd40,14, +0x08dd40,2, +0x08dd4c,11, 0x08dd80,8, -0x08ddc0,14, +0x08ddc0,2, +0x08ddcc,11, 0x08de00,8, -0x08de40,14, +0x08de40,2, +0x08de4c,11, 0x08de80,8, -0x08dec0,14, -0x08df00,11, +0x08dec0,2, +0x08decc,11, +0x08df00,9, 0x08df30,2, 0x08df40,49, 0x08e018,1, @@ -3084,120 +3151,132 @@ 0x08e134,1, 0x08e14c,1, 0x08e170,2, -0x08e200,3, +0x08e200,1, 0x08e210,2, 0x08e400,5, 0x08e418,9, 0x08e440,5, -0x08e460,3, +0x08e460,1, 0x08e470,2, 0x08e500,5, 0x08e518,9, 0x08e540,5, -0x08e560,3, +0x08e560,1, 0x08e570,2, 0x08e600,5, 0x08e618,9, 0x08e640,5, -0x08e660,3, +0x08e660,1, 0x08e670,2, 0x08e700,1, 0x08e800,6, 0x08e81c,3, -0x08e82c,12, +0x08e82c,3, +0x08e83c,8, 0x08e860,1, 0x08e868,1, 0x08e870,2, -0x08e880,3, +0x08e880,1, 0x08e890,2, -0x08e8a0,3, +0x08e8a0,1, 0x08e8b0,2, -0x08e8c0,3, +0x08e8c0,1, 0x08e8d0,2, -0x08e8e0,3, +0x08e8e0,1, 0x08e8f0,2, 0x08e900,29, -0x08e980,29, +0x08e980,27, +0x08e9f0,1, 0x08ec00,6, 0x08ec1c,3, -0x08ec2c,12, +0x08ec2c,3, +0x08ec3c,8, 0x08ec60,1, 0x08ec68,1, 0x08ec70,2, -0x08ec80,3, +0x08ec80,1, 0x08ec90,2, -0x08eca0,3, +0x08eca0,1, 0x08ecb0,2, -0x08ecc0,3, +0x08ecc0,1, 0x08ecd0,2, -0x08ece0,3, +0x08ece0,1, 0x08ecf0,2, 0x08ed00,29, -0x08ed80,29, +0x08ed80,27, +0x08edf0,1, 0x08f000,6, 0x08f01c,3, -0x08f02c,12, +0x08f02c,3, +0x08f03c,8, 0x08f060,1, 0x08f068,1, 0x08f070,2, -0x08f080,3, +0x08f080,1, 0x08f090,2, -0x08f0a0,3, +0x08f0a0,1, 0x08f0b0,2, -0x08f0c0,3, +0x08f0c0,1, 0x08f0d0,2, -0x08f0e0,3, +0x08f0e0,1, 0x08f0f0,2, 0x08f100,29, -0x08f180,29, +0x08f180,27, +0x08f1f0,1, 0x08f400,6, 0x08f41c,3, -0x08f42c,12, +0x08f42c,3, +0x08f43c,8, 0x08f460,1, 0x08f468,1, 0x08f470,2, -0x08f480,3, +0x08f480,1, 0x08f490,2, -0x08f4a0,3, +0x08f4a0,1, 0x08f4b0,2, -0x08f4c0,3, +0x08f4c0,1, 0x08f4d0,2, -0x08f4e0,3, +0x08f4e0,1, 0x08f4f0,2, 0x08f500,29, -0x08f580,29, +0x08f580,27, +0x08f5f0,1, 0x08f800,6, 0x08f81c,3, -0x08f82c,12, +0x08f82c,3, +0x08f83c,8, 0x08f860,1, 0x08f868,1, 0x08f870,2, -0x08f880,3, +0x08f880,1, 0x08f890,2, -0x08f8a0,3, +0x08f8a0,1, 0x08f8b0,2, -0x08f8c0,3, +0x08f8c0,1, 0x08f8d0,2, -0x08f8e0,3, +0x08f8e0,1, 0x08f8f0,2, 0x08f900,29, -0x08f980,29, +0x08f980,27, +0x08f9f0,1, 0x08fc00,6, 0x08fc1c,3, -0x08fc2c,12, +0x08fc2c,3, +0x08fc3c,8, 0x08fc60,1, 0x08fc68,1, 0x08fc70,2, -0x08fc80,3, +0x08fc80,1, 0x08fc90,2, -0x08fca0,3, +0x08fca0,1, 0x08fcb0,2, -0x08fcc0,3, +0x08fcc0,1, 0x08fcd0,2, -0x08fce0,3, +0x08fce0,1, 0x08fcf0,2, 0x08fd00,29, -0x08fd80,29, +0x08fd80,27, +0x08fdf0,1, 0x090000,2, 0x090018,2, 0x090034,2, @@ -3205,17 +3284,17 @@ 0x090134,2, 0x09014c,1, 0x090170,2, -0x090200,3, +0x090200,1, 0x090210,2, -0x090220,3, +0x090220,1, 0x090230,2, -0x090400,3, +0x090400,1, 0x090410,2, 0x090420,3, 0x090430,22, 0x0904ac,1, 0x0904c0,6, -0x090500,3, +0x090500,1, 0x090510,2, 0x090520,3, 0x090540,8, @@ -3230,110 +3309,134 @@ 0x090800,5, 0x090820,5, 0x090890,10, -0x0908e0,3, +0x0908e0,1, 0x0908f0,2, 0x090900,5, 0x090920,5, 0x090990,10, -0x0909e0,3, +0x0909e0,1, 0x0909f0,2, -0x090a00,3, +0x090a00,1, 0x090a10,2, -0x090a20,3, +0x090a20,1, 0x090a30,2, 0x090a48,3, -0x090a80,18, +0x090a80,3, +0x090a90,1, +0x090a98,12, 0x090b04,2, 0x090b14,3, 0x090b24,2, 0x090b34,3, -0x090b80,11, +0x090b80,5, +0x090b98,3, 0x090bb0,2, -0x090bc0,11, +0x090bc0,5, +0x090bd8,3, 0x090bf0,2, -0x090c00,23, -0x090c80,27, +0x090c00,10, +0x090c2c,12, +0x090c80,26, 0x090d00,2, 0x090d20,1, -0x090e00,23, -0x090e80,27, +0x090e00,10, +0x090e2c,12, +0x090e80,26, 0x090f00,2, 0x090f20,1, 0x091000,5, 0x091020,5, 0x091090,10, -0x0910e0,3, +0x0910e0,1, 0x0910f0,2, 0x091100,5, 0x091120,5, 0x091190,10, -0x0911e0,3, +0x0911e0,1, 0x0911f0,2, -0x091200,3, +0x091200,1, 0x091210,2, -0x091220,3, +0x091220,1, 0x091230,2, 0x091248,3, -0x091280,18, +0x091280,3, +0x091290,1, +0x091298,12, 0x091304,2, 0x091314,3, 0x091324,2, 0x091334,3, -0x091380,11, +0x091380,5, +0x091398,3, 0x0913b0,2, -0x0913c0,11, +0x0913c0,5, +0x0913d8,3, 0x0913f0,2, -0x091400,23, -0x091480,27, +0x091400,10, +0x09142c,12, +0x091480,26, 0x091500,2, 0x091520,1, -0x091600,23, -0x091680,27, +0x091600,10, +0x09162c,12, +0x091680,26, 0x091700,2, 0x091720,1, 0x091800,5, 0x091820,5, 0x091890,10, -0x0918e0,3, +0x0918e0,1, 0x0918f0,2, 0x091900,5, 0x091920,5, 0x091990,10, -0x0919e0,3, +0x0919e0,1, 0x0919f0,2, -0x091a00,3, +0x091a00,1, 0x091a10,2, -0x091a20,3, +0x091a20,1, 0x091a30,2, 0x091a48,3, -0x091a80,18, +0x091a80,3, +0x091a90,1, +0x091a98,12, 0x091b04,2, 0x091b14,3, 0x091b24,2, 0x091b34,3, -0x091b80,11, +0x091b80,5, +0x091b98,3, 0x091bb0,2, -0x091bc0,11, +0x091bc0,5, +0x091bd8,3, 0x091bf0,2, -0x091c00,23, -0x091c80,27, +0x091c00,10, +0x091c2c,12, +0x091c80,26, 0x091d00,2, 0x091d20,1, -0x091e00,23, -0x091e80,27, +0x091e00,10, +0x091e2c,12, +0x091e80,26, 0x091f00,2, 0x091f20,1, -0x092000,16, +0x092000,7, +0x092020,8, 0x092044,8, -0x092080,16, +0x092080,7, +0x0920a0,8, 0x0920c4,8, -0x092100,16, +0x092100,7, +0x092120,8, 0x092144,8, -0x092180,16, +0x092180,7, +0x0921a0,8, 0x0921c4,8, -0x092200,16, +0x092200,7, +0x092220,8, 0x092244,8, -0x092280,16, +0x092280,7, +0x0922a0,8, 0x0922c4,8, 0x092400,1, 0x092418,1, @@ -3342,16 +3445,16 @@ 0x092534,1, 0x09254c,1, 0x092570,2, -0x092600,3, +0x092600,1, 0x092610,2, 0x092804,15, 0x092844,15, 0x092884,15, 0x0928c4,15, 0x092904,15, -0x092944,18, +0x092944,16, 0x092990,2, -0x0929a0,3, +0x0929a0,1, 0x0929b0,2, 0x0929c0,2, 0x092a00,400, @@ -3366,13 +3469,13 @@ 0x0932c0,2, 0x0932cc,2, 0x0932d8,3, -0x093300,3, +0x093300,1, 0x093310,2, -0x093320,3, +0x093320,1, 0x093330,2, -0x093340,3, +0x093340,1, 0x093350,2, -0x093360,3, +0x093360,1, 0x093370,2, 0x093380,1, 0x093400,16, @@ -3387,13 +3490,13 @@ 0x0936c0,2, 0x0936cc,2, 0x0936d8,3, -0x093700,3, +0x093700,1, 0x093710,2, -0x093720,3, +0x093720,1, 0x093730,2, -0x093740,3, +0x093740,1, 0x093750,2, -0x093760,3, +0x093760,1, 0x093770,2, 0x093780,1, 0x093800,16, @@ -3408,13 +3511,13 @@ 0x093ac0,2, 0x093acc,2, 0x093ad8,3, -0x093b00,3, +0x093b00,1, 0x093b10,2, -0x093b20,3, +0x093b20,1, 0x093b30,2, -0x093b40,3, +0x093b40,1, 0x093b50,2, -0x093b60,3, +0x093b60,1, 0x093b70,2, 0x093b80,1, 0x093c00,18, @@ -3444,39 +3547,36 @@ 0x093f44,1, 0x093f50,4, 0x093fa0,3, -0x094000,9, +0x094000,5, +0x094018,3, 0x094080,2, 0x09408c,1, -0x094094,1, -0x0940a0,11, +0x0940a0,9, 0x0940d0,2, 0x0940e0,1, 0x0940e8,1, 0x094100,2, 0x09410c,1, -0x094114,1, -0x094120,11, +0x094120,9, 0x094150,2, 0x094160,1, 0x094168,1, 0x094180,2, 0x09418c,1, -0x094194,1, -0x0941a0,11, +0x0941a0,9, 0x0941d0,2, 0x0941e0,1, 0x0941e8,1, 0x094200,2, 0x09420c,1, -0x094214,1, -0x094220,11, +0x094220,9, 0x094250,2, 0x094260,1, 0x094268,1, -0x094280,3, +0x094284,2, 0x0942a8,2, 0x0942b4,1, -0x0942c0,3, +0x0942c4,2, 0x0942e8,2, 0x0942f4,1, 0x094400,3, @@ -3496,47 +3596,44 @@ 0x094600,15, 0x094640,3, 0x094650,3, -0x094660,3, +0x094660,1, 0x094670,2, -0x094680,3, +0x094680,1, 0x094690,2, 0x0946c0,4, 0x0946d4,8, 0x094700,4, 0x094714,8, -0x094800,9, +0x094800,5, +0x094818,3, 0x094880,2, 0x09488c,1, -0x094894,1, -0x0948a0,11, +0x0948a0,9, 0x0948d0,2, 0x0948e0,1, 0x0948e8,1, 0x094900,2, 0x09490c,1, -0x094914,1, -0x094920,11, +0x094920,9, 0x094950,2, 0x094960,1, 0x094968,1, 0x094980,2, 0x09498c,1, -0x094994,1, -0x0949a0,11, +0x0949a0,9, 0x0949d0,2, 0x0949e0,1, 0x0949e8,1, 0x094a00,2, 0x094a0c,1, -0x094a14,1, -0x094a20,11, +0x094a20,9, 0x094a50,2, 0x094a60,1, 0x094a68,1, -0x094a80,3, +0x094a84,2, 0x094aa8,2, 0x094ab4,1, -0x094ac0,3, +0x094ac4,2, 0x094ae8,2, 0x094af4,1, 0x094c00,3, @@ -3556,47 +3653,44 @@ 0x094e00,15, 0x094e40,3, 0x094e50,3, -0x094e60,3, +0x094e60,1, 0x094e70,2, -0x094e80,3, +0x094e80,1, 0x094e90,2, 0x094ec0,4, 0x094ed4,8, 0x094f00,4, 0x094f14,8, -0x095000,9, +0x095000,5, +0x095018,3, 0x095080,2, 0x09508c,1, -0x095094,1, -0x0950a0,11, +0x0950a0,9, 0x0950d0,2, 0x0950e0,1, 0x0950e8,1, 0x095100,2, 0x09510c,1, -0x095114,1, -0x095120,11, +0x095120,9, 0x095150,2, 0x095160,1, 0x095168,1, 0x095180,2, 0x09518c,1, -0x095194,1, -0x0951a0,11, +0x0951a0,9, 0x0951d0,2, 0x0951e0,1, 0x0951e8,1, 0x095200,2, 0x09520c,1, -0x095214,1, -0x095220,11, +0x095220,9, 0x095250,2, 0x095260,1, 0x095268,1, -0x095280,3, +0x095284,2, 0x0952a8,2, 0x0952b4,1, -0x0952c0,3, +0x0952c4,2, 0x0952e8,2, 0x0952f4,1, 0x095400,3, @@ -3616,9 +3710,9 @@ 0x095600,15, 0x095640,3, 0x095650,3, -0x095660,3, +0x095660,1, 0x095670,2, -0x095680,3, +0x095680,1, 0x095690,2, 0x0956c0,4, 0x0956d4,8, @@ -3627,29 +3721,35 @@ 0x095800,31, 0x095880,8, 0x0958a4,1, -0x0958b4,22, +0x0958b4,20, 0x095910,2, 0x095920,3, 0x095934,1, -0x09593c,4, +0x09593c,2, 0x095950,2, 0x095a00,11, 0x095a4c,8, 0x095a70,2, 0x095a7c,33, 0x095c00,8, -0x095c40,14, +0x095c40,2, +0x095c4c,11, 0x095c80,8, -0x095cc0,14, +0x095cc0,2, +0x095ccc,11, 0x095d00,8, -0x095d40,14, +0x095d40,2, +0x095d4c,11, 0x095d80,8, -0x095dc0,14, +0x095dc0,2, +0x095dcc,11, 0x095e00,8, -0x095e40,14, +0x095e40,2, +0x095e4c,11, 0x095e80,8, -0x095ec0,14, -0x095f00,11, +0x095ec0,2, +0x095ecc,11, +0x095f00,9, 0x095f30,2, 0x095f40,49, 0x096018,1, @@ -3658,120 +3758,132 @@ 0x096134,1, 0x09614c,1, 0x096170,2, -0x096200,3, +0x096200,1, 0x096210,2, 0x096400,5, 0x096418,9, 0x096440,5, -0x096460,3, +0x096460,1, 0x096470,2, 0x096500,5, 0x096518,9, 0x096540,5, -0x096560,3, +0x096560,1, 0x096570,2, 0x096600,5, 0x096618,9, 0x096640,5, -0x096660,3, +0x096660,1, 0x096670,2, 0x096700,1, 0x096800,6, 0x09681c,3, -0x09682c,12, +0x09682c,3, +0x09683c,8, 0x096860,1, 0x096868,1, 0x096870,2, -0x096880,3, +0x096880,1, 0x096890,2, -0x0968a0,3, +0x0968a0,1, 0x0968b0,2, -0x0968c0,3, +0x0968c0,1, 0x0968d0,2, -0x0968e0,3, +0x0968e0,1, 0x0968f0,2, 0x096900,29, -0x096980,29, +0x096980,27, +0x0969f0,1, 0x096c00,6, 0x096c1c,3, -0x096c2c,12, +0x096c2c,3, +0x096c3c,8, 0x096c60,1, 0x096c68,1, 0x096c70,2, -0x096c80,3, +0x096c80,1, 0x096c90,2, -0x096ca0,3, +0x096ca0,1, 0x096cb0,2, -0x096cc0,3, +0x096cc0,1, 0x096cd0,2, -0x096ce0,3, +0x096ce0,1, 0x096cf0,2, 0x096d00,29, -0x096d80,29, +0x096d80,27, +0x096df0,1, 0x097000,6, 0x09701c,3, -0x09702c,12, +0x09702c,3, +0x09703c,8, 0x097060,1, 0x097068,1, 0x097070,2, -0x097080,3, +0x097080,1, 0x097090,2, -0x0970a0,3, +0x0970a0,1, 0x0970b0,2, -0x0970c0,3, +0x0970c0,1, 0x0970d0,2, -0x0970e0,3, +0x0970e0,1, 0x0970f0,2, 0x097100,29, -0x097180,29, +0x097180,27, +0x0971f0,1, 0x097400,6, 0x09741c,3, -0x09742c,12, +0x09742c,3, +0x09743c,8, 0x097460,1, 0x097468,1, 0x097470,2, -0x097480,3, +0x097480,1, 0x097490,2, -0x0974a0,3, +0x0974a0,1, 0x0974b0,2, -0x0974c0,3, +0x0974c0,1, 0x0974d0,2, -0x0974e0,3, +0x0974e0,1, 0x0974f0,2, 0x097500,29, -0x097580,29, +0x097580,27, +0x0975f0,1, 0x097800,6, 0x09781c,3, -0x09782c,12, +0x09782c,3, +0x09783c,8, 0x097860,1, 0x097868,1, 0x097870,2, -0x097880,3, +0x097880,1, 0x097890,2, -0x0978a0,3, +0x0978a0,1, 0x0978b0,2, -0x0978c0,3, +0x0978c0,1, 0x0978d0,2, -0x0978e0,3, +0x0978e0,1, 0x0978f0,2, 0x097900,29, -0x097980,29, +0x097980,27, +0x0979f0,1, 0x097c00,6, 0x097c1c,3, -0x097c2c,12, +0x097c2c,3, +0x097c3c,8, 0x097c60,1, 0x097c68,1, 0x097c70,2, -0x097c80,3, +0x097c80,1, 0x097c90,2, -0x097ca0,3, +0x097ca0,1, 0x097cb0,2, -0x097cc0,3, +0x097cc0,1, 0x097cd0,2, -0x097ce0,3, +0x097ce0,1, 0x097cf0,2, 0x097d00,29, -0x097d80,29, +0x097d80,27, +0x097df0,1, 0x098000,2, 0x098018,2, 0x098034,2, @@ -3779,17 +3891,17 @@ 0x098134,2, 0x09814c,1, 0x098170,2, -0x098200,3, +0x098200,1, 0x098210,2, -0x098220,3, +0x098220,1, 0x098230,2, -0x098400,3, +0x098400,1, 0x098410,2, 0x098420,3, 0x098430,22, 0x0984ac,1, 0x0984c0,6, -0x098500,3, +0x098500,1, 0x098510,2, 0x098520,3, 0x098540,8, @@ -3804,110 +3916,134 @@ 0x098800,5, 0x098820,5, 0x098890,10, -0x0988e0,3, +0x0988e0,1, 0x0988f0,2, 0x098900,5, 0x098920,5, 0x098990,10, -0x0989e0,3, +0x0989e0,1, 0x0989f0,2, -0x098a00,3, +0x098a00,1, 0x098a10,2, -0x098a20,3, +0x098a20,1, 0x098a30,2, 0x098a48,3, -0x098a80,18, +0x098a80,3, +0x098a90,1, +0x098a98,12, 0x098b04,2, 0x098b14,3, 0x098b24,2, 0x098b34,3, -0x098b80,11, +0x098b80,5, +0x098b98,3, 0x098bb0,2, -0x098bc0,11, +0x098bc0,5, +0x098bd8,3, 0x098bf0,2, -0x098c00,23, -0x098c80,27, +0x098c00,10, +0x098c2c,12, +0x098c80,26, 0x098d00,2, 0x098d20,1, -0x098e00,23, -0x098e80,27, +0x098e00,10, +0x098e2c,12, +0x098e80,26, 0x098f00,2, 0x098f20,1, 0x099000,5, 0x099020,5, 0x099090,10, -0x0990e0,3, +0x0990e0,1, 0x0990f0,2, 0x099100,5, 0x099120,5, 0x099190,10, -0x0991e0,3, +0x0991e0,1, 0x0991f0,2, -0x099200,3, +0x099200,1, 0x099210,2, -0x099220,3, +0x099220,1, 0x099230,2, 0x099248,3, -0x099280,18, +0x099280,3, +0x099290,1, +0x099298,12, 0x099304,2, 0x099314,3, 0x099324,2, 0x099334,3, -0x099380,11, +0x099380,5, +0x099398,3, 0x0993b0,2, -0x0993c0,11, +0x0993c0,5, +0x0993d8,3, 0x0993f0,2, -0x099400,23, -0x099480,27, +0x099400,10, +0x09942c,12, +0x099480,26, 0x099500,2, 0x099520,1, -0x099600,23, -0x099680,27, +0x099600,10, +0x09962c,12, +0x099680,26, 0x099700,2, 0x099720,1, 0x099800,5, 0x099820,5, 0x099890,10, -0x0998e0,3, +0x0998e0,1, 0x0998f0,2, 0x099900,5, 0x099920,5, 0x099990,10, -0x0999e0,3, +0x0999e0,1, 0x0999f0,2, -0x099a00,3, +0x099a00,1, 0x099a10,2, -0x099a20,3, +0x099a20,1, 0x099a30,2, 0x099a48,3, -0x099a80,18, +0x099a80,3, +0x099a90,1, +0x099a98,12, 0x099b04,2, 0x099b14,3, 0x099b24,2, 0x099b34,3, -0x099b80,11, +0x099b80,5, +0x099b98,3, 0x099bb0,2, -0x099bc0,11, +0x099bc0,5, +0x099bd8,3, 0x099bf0,2, -0x099c00,23, -0x099c80,27, +0x099c00,10, +0x099c2c,12, +0x099c80,26, 0x099d00,2, 0x099d20,1, -0x099e00,23, -0x099e80,27, +0x099e00,10, +0x099e2c,12, +0x099e80,26, 0x099f00,2, 0x099f20,1, -0x09a000,16, +0x09a000,7, +0x09a020,8, 0x09a044,8, -0x09a080,16, +0x09a080,7, +0x09a0a0,8, 0x09a0c4,8, -0x09a100,16, +0x09a100,7, +0x09a120,8, 0x09a144,8, -0x09a180,16, +0x09a180,7, +0x09a1a0,8, 0x09a1c4,8, -0x09a200,16, +0x09a200,7, +0x09a220,8, 0x09a244,8, -0x09a280,16, +0x09a280,7, +0x09a2a0,8, 0x09a2c4,8, 0x09a400,1, 0x09a418,1, @@ -3916,16 +4052,16 @@ 0x09a534,1, 0x09a54c,1, 0x09a570,2, -0x09a600,3, +0x09a600,1, 0x09a610,2, 0x09a804,15, 0x09a844,15, 0x09a884,15, 0x09a8c4,15, 0x09a904,15, -0x09a944,18, +0x09a944,16, 0x09a990,2, -0x09a9a0,3, +0x09a9a0,1, 0x09a9b0,2, 0x09a9c0,2, 0x09aa00,400, @@ -3940,13 +4076,13 @@ 0x09b2c0,2, 0x09b2cc,2, 0x09b2d8,3, -0x09b300,3, +0x09b300,1, 0x09b310,2, -0x09b320,3, +0x09b320,1, 0x09b330,2, -0x09b340,3, +0x09b340,1, 0x09b350,2, -0x09b360,3, +0x09b360,1, 0x09b370,2, 0x09b380,1, 0x09b400,16, @@ -3961,13 +4097,13 @@ 0x09b6c0,2, 0x09b6cc,2, 0x09b6d8,3, -0x09b700,3, +0x09b700,1, 0x09b710,2, -0x09b720,3, +0x09b720,1, 0x09b730,2, -0x09b740,3, +0x09b740,1, 0x09b750,2, -0x09b760,3, +0x09b760,1, 0x09b770,2, 0x09b780,1, 0x09b800,16, @@ -3982,13 +4118,13 @@ 0x09bac0,2, 0x09bacc,2, 0x09bad8,3, -0x09bb00,3, +0x09bb00,1, 0x09bb10,2, -0x09bb20,3, +0x09bb20,1, 0x09bb30,2, -0x09bb40,3, +0x09bb40,1, 0x09bb50,2, -0x09bb60,3, +0x09bb60,1, 0x09bb70,2, 0x09bb80,1, 0x09bc00,18, @@ -4018,39 +4154,36 @@ 0x09bf44,1, 0x09bf50,4, 0x09bfa0,3, -0x09c000,9, +0x09c000,5, +0x09c018,3, 0x09c080,2, 0x09c08c,1, -0x09c094,1, -0x09c0a0,11, +0x09c0a0,9, 0x09c0d0,2, 0x09c0e0,1, 0x09c0e8,1, 0x09c100,2, 0x09c10c,1, -0x09c114,1, -0x09c120,11, +0x09c120,9, 0x09c150,2, 0x09c160,1, 0x09c168,1, 0x09c180,2, 0x09c18c,1, -0x09c194,1, -0x09c1a0,11, +0x09c1a0,9, 0x09c1d0,2, 0x09c1e0,1, 0x09c1e8,1, 0x09c200,2, 0x09c20c,1, -0x09c214,1, -0x09c220,11, +0x09c220,9, 0x09c250,2, 0x09c260,1, 0x09c268,1, -0x09c280,3, +0x09c284,2, 0x09c2a8,2, 0x09c2b4,1, -0x09c2c0,3, +0x09c2c4,2, 0x09c2e8,2, 0x09c2f4,1, 0x09c400,3, @@ -4070,47 +4203,44 @@ 0x09c600,15, 0x09c640,3, 0x09c650,3, -0x09c660,3, +0x09c660,1, 0x09c670,2, -0x09c680,3, +0x09c680,1, 0x09c690,2, 0x09c6c0,4, 0x09c6d4,8, 0x09c700,4, 0x09c714,8, -0x09c800,9, +0x09c800,5, +0x09c818,3, 0x09c880,2, 0x09c88c,1, -0x09c894,1, -0x09c8a0,11, +0x09c8a0,9, 0x09c8d0,2, 0x09c8e0,1, 0x09c8e8,1, 0x09c900,2, 0x09c90c,1, -0x09c914,1, -0x09c920,11, +0x09c920,9, 0x09c950,2, 0x09c960,1, 0x09c968,1, 0x09c980,2, 0x09c98c,1, -0x09c994,1, -0x09c9a0,11, +0x09c9a0,9, 0x09c9d0,2, 0x09c9e0,1, 0x09c9e8,1, 0x09ca00,2, 0x09ca0c,1, -0x09ca14,1, -0x09ca20,11, +0x09ca20,9, 0x09ca50,2, 0x09ca60,1, 0x09ca68,1, -0x09ca80,3, +0x09ca84,2, 0x09caa8,2, 0x09cab4,1, -0x09cac0,3, +0x09cac4,2, 0x09cae8,2, 0x09caf4,1, 0x09cc00,3, @@ -4130,47 +4260,44 @@ 0x09ce00,15, 0x09ce40,3, 0x09ce50,3, -0x09ce60,3, +0x09ce60,1, 0x09ce70,2, -0x09ce80,3, +0x09ce80,1, 0x09ce90,2, 0x09cec0,4, 0x09ced4,8, 0x09cf00,4, 0x09cf14,8, -0x09d000,9, +0x09d000,5, +0x09d018,3, 0x09d080,2, 0x09d08c,1, -0x09d094,1, -0x09d0a0,11, +0x09d0a0,9, 0x09d0d0,2, 0x09d0e0,1, 0x09d0e8,1, 0x09d100,2, 0x09d10c,1, -0x09d114,1, -0x09d120,11, +0x09d120,9, 0x09d150,2, 0x09d160,1, 0x09d168,1, 0x09d180,2, 0x09d18c,1, -0x09d194,1, -0x09d1a0,11, +0x09d1a0,9, 0x09d1d0,2, 0x09d1e0,1, 0x09d1e8,1, 0x09d200,2, 0x09d20c,1, -0x09d214,1, -0x09d220,11, +0x09d220,9, 0x09d250,2, 0x09d260,1, 0x09d268,1, -0x09d280,3, +0x09d284,2, 0x09d2a8,2, 0x09d2b4,1, -0x09d2c0,3, +0x09d2c4,2, 0x09d2e8,2, 0x09d2f4,1, 0x09d400,3, @@ -4190,9 +4317,9 @@ 0x09d600,15, 0x09d640,3, 0x09d650,3, -0x09d660,3, +0x09d660,1, 0x09d670,2, -0x09d680,3, +0x09d680,1, 0x09d690,2, 0x09d6c0,4, 0x09d6d4,8, @@ -4201,29 +4328,35 @@ 0x09d800,31, 0x09d880,8, 0x09d8a4,1, -0x09d8b4,22, +0x09d8b4,20, 0x09d910,2, 0x09d920,3, 0x09d934,1, -0x09d93c,4, +0x09d93c,2, 0x09d950,2, 0x09da00,11, 0x09da4c,8, 0x09da70,2, 0x09da7c,33, 0x09dc00,8, -0x09dc40,14, +0x09dc40,2, +0x09dc4c,11, 0x09dc80,8, -0x09dcc0,14, +0x09dcc0,2, +0x09dccc,11, 0x09dd00,8, -0x09dd40,14, +0x09dd40,2, +0x09dd4c,11, 0x09dd80,8, -0x09ddc0,14, +0x09ddc0,2, +0x09ddcc,11, 0x09de00,8, -0x09de40,14, +0x09de40,2, +0x09de4c,11, 0x09de80,8, -0x09dec0,14, -0x09df00,11, +0x09dec0,2, +0x09decc,11, +0x09df00,9, 0x09df30,2, 0x09df40,49, 0x09e018,1, @@ -4232,120 +4365,132 @@ 0x09e134,1, 0x09e14c,1, 0x09e170,2, -0x09e200,3, +0x09e200,1, 0x09e210,2, 0x09e400,5, 0x09e418,9, 0x09e440,5, -0x09e460,3, +0x09e460,1, 0x09e470,2, 0x09e500,5, 0x09e518,9, 0x09e540,5, -0x09e560,3, +0x09e560,1, 0x09e570,2, 0x09e600,5, 0x09e618,9, 0x09e640,5, -0x09e660,3, +0x09e660,1, 0x09e670,2, 0x09e700,1, 0x09e800,6, 0x09e81c,3, -0x09e82c,12, +0x09e82c,3, +0x09e83c,8, 0x09e860,1, 0x09e868,1, 0x09e870,2, -0x09e880,3, +0x09e880,1, 0x09e890,2, -0x09e8a0,3, +0x09e8a0,1, 0x09e8b0,2, -0x09e8c0,3, +0x09e8c0,1, 0x09e8d0,2, -0x09e8e0,3, +0x09e8e0,1, 0x09e8f0,2, 0x09e900,29, -0x09e980,29, +0x09e980,27, +0x09e9f0,1, 0x09ec00,6, 0x09ec1c,3, -0x09ec2c,12, +0x09ec2c,3, +0x09ec3c,8, 0x09ec60,1, 0x09ec68,1, 0x09ec70,2, -0x09ec80,3, +0x09ec80,1, 0x09ec90,2, -0x09eca0,3, +0x09eca0,1, 0x09ecb0,2, -0x09ecc0,3, +0x09ecc0,1, 0x09ecd0,2, -0x09ece0,3, +0x09ece0,1, 0x09ecf0,2, 0x09ed00,29, -0x09ed80,29, +0x09ed80,27, +0x09edf0,1, 0x09f000,6, 0x09f01c,3, -0x09f02c,12, +0x09f02c,3, +0x09f03c,8, 0x09f060,1, 0x09f068,1, 0x09f070,2, -0x09f080,3, +0x09f080,1, 0x09f090,2, -0x09f0a0,3, +0x09f0a0,1, 0x09f0b0,2, -0x09f0c0,3, +0x09f0c0,1, 0x09f0d0,2, -0x09f0e0,3, +0x09f0e0,1, 0x09f0f0,2, 0x09f100,29, -0x09f180,29, +0x09f180,27, +0x09f1f0,1, 0x09f400,6, 0x09f41c,3, -0x09f42c,12, +0x09f42c,3, +0x09f43c,8, 0x09f460,1, 0x09f468,1, 0x09f470,2, -0x09f480,3, +0x09f480,1, 0x09f490,2, -0x09f4a0,3, +0x09f4a0,1, 0x09f4b0,2, -0x09f4c0,3, +0x09f4c0,1, 0x09f4d0,2, -0x09f4e0,3, +0x09f4e0,1, 0x09f4f0,2, 0x09f500,29, -0x09f580,29, +0x09f580,27, +0x09f5f0,1, 0x09f800,6, 0x09f81c,3, -0x09f82c,12, +0x09f82c,3, +0x09f83c,8, 0x09f860,1, 0x09f868,1, 0x09f870,2, -0x09f880,3, +0x09f880,1, 0x09f890,2, -0x09f8a0,3, +0x09f8a0,1, 0x09f8b0,2, -0x09f8c0,3, +0x09f8c0,1, 0x09f8d0,2, -0x09f8e0,3, +0x09f8e0,1, 0x09f8f0,2, 0x09f900,29, -0x09f980,29, +0x09f980,27, +0x09f9f0,1, 0x09fc00,6, 0x09fc1c,3, -0x09fc2c,12, +0x09fc2c,3, +0x09fc3c,8, 0x09fc60,1, 0x09fc68,1, 0x09fc70,2, -0x09fc80,3, +0x09fc80,1, 0x09fc90,2, -0x09fca0,3, +0x09fca0,1, 0x09fcb0,2, -0x09fcc0,3, +0x09fcc0,1, 0x09fcd0,2, -0x09fce0,3, +0x09fce0,1, 0x09fcf0,2, 0x09fd00,29, -0x09fd80,29, +0x09fd80,27, +0x09fdf0,1, 0x0a0000,2, 0x0a0018,2, 0x0a0034,2, @@ -4353,17 +4498,17 @@ 0x0a0134,2, 0x0a014c,1, 0x0a0170,2, -0x0a0200,3, +0x0a0200,1, 0x0a0210,2, -0x0a0220,3, +0x0a0220,1, 0x0a0230,2, -0x0a0400,3, +0x0a0400,1, 0x0a0410,2, 0x0a0420,3, 0x0a0430,22, 0x0a04ac,1, 0x0a04c0,6, -0x0a0500,3, +0x0a0500,1, 0x0a0510,2, 0x0a0520,3, 0x0a0540,8, @@ -4378,110 +4523,134 @@ 0x0a0800,5, 0x0a0820,5, 0x0a0890,10, -0x0a08e0,3, +0x0a08e0,1, 0x0a08f0,2, 0x0a0900,5, 0x0a0920,5, 0x0a0990,10, -0x0a09e0,3, +0x0a09e0,1, 0x0a09f0,2, -0x0a0a00,3, +0x0a0a00,1, 0x0a0a10,2, -0x0a0a20,3, +0x0a0a20,1, 0x0a0a30,2, 0x0a0a48,3, -0x0a0a80,18, +0x0a0a80,3, +0x0a0a90,1, +0x0a0a98,12, 0x0a0b04,2, 0x0a0b14,3, 0x0a0b24,2, 0x0a0b34,3, -0x0a0b80,11, +0x0a0b80,5, +0x0a0b98,3, 0x0a0bb0,2, -0x0a0bc0,11, +0x0a0bc0,5, +0x0a0bd8,3, 0x0a0bf0,2, -0x0a0c00,23, -0x0a0c80,27, +0x0a0c00,10, +0x0a0c2c,12, +0x0a0c80,26, 0x0a0d00,2, 0x0a0d20,1, -0x0a0e00,23, -0x0a0e80,27, +0x0a0e00,10, +0x0a0e2c,12, +0x0a0e80,26, 0x0a0f00,2, 0x0a0f20,1, 0x0a1000,5, 0x0a1020,5, 0x0a1090,10, -0x0a10e0,3, +0x0a10e0,1, 0x0a10f0,2, 0x0a1100,5, 0x0a1120,5, 0x0a1190,10, -0x0a11e0,3, +0x0a11e0,1, 0x0a11f0,2, -0x0a1200,3, +0x0a1200,1, 0x0a1210,2, -0x0a1220,3, +0x0a1220,1, 0x0a1230,2, 0x0a1248,3, -0x0a1280,18, +0x0a1280,3, +0x0a1290,1, +0x0a1298,12, 0x0a1304,2, 0x0a1314,3, 0x0a1324,2, 0x0a1334,3, -0x0a1380,11, +0x0a1380,5, +0x0a1398,3, 0x0a13b0,2, -0x0a13c0,11, +0x0a13c0,5, +0x0a13d8,3, 0x0a13f0,2, -0x0a1400,23, -0x0a1480,27, +0x0a1400,10, +0x0a142c,12, +0x0a1480,26, 0x0a1500,2, 0x0a1520,1, -0x0a1600,23, -0x0a1680,27, +0x0a1600,10, +0x0a162c,12, +0x0a1680,26, 0x0a1700,2, 0x0a1720,1, 0x0a1800,5, 0x0a1820,5, 0x0a1890,10, -0x0a18e0,3, +0x0a18e0,1, 0x0a18f0,2, 0x0a1900,5, 0x0a1920,5, 0x0a1990,10, -0x0a19e0,3, +0x0a19e0,1, 0x0a19f0,2, -0x0a1a00,3, +0x0a1a00,1, 0x0a1a10,2, -0x0a1a20,3, +0x0a1a20,1, 0x0a1a30,2, 0x0a1a48,3, -0x0a1a80,18, +0x0a1a80,3, +0x0a1a90,1, +0x0a1a98,12, 0x0a1b04,2, 0x0a1b14,3, 0x0a1b24,2, 0x0a1b34,3, -0x0a1b80,11, +0x0a1b80,5, +0x0a1b98,3, 0x0a1bb0,2, -0x0a1bc0,11, +0x0a1bc0,5, +0x0a1bd8,3, 0x0a1bf0,2, -0x0a1c00,23, -0x0a1c80,27, +0x0a1c00,10, +0x0a1c2c,12, +0x0a1c80,26, 0x0a1d00,2, 0x0a1d20,1, -0x0a1e00,23, -0x0a1e80,27, +0x0a1e00,10, +0x0a1e2c,12, +0x0a1e80,26, 0x0a1f00,2, 0x0a1f20,1, -0x0a2000,16, +0x0a2000,7, +0x0a2020,8, 0x0a2044,8, -0x0a2080,16, +0x0a2080,7, +0x0a20a0,8, 0x0a20c4,8, -0x0a2100,16, +0x0a2100,7, +0x0a2120,8, 0x0a2144,8, -0x0a2180,16, +0x0a2180,7, +0x0a21a0,8, 0x0a21c4,8, -0x0a2200,16, +0x0a2200,7, +0x0a2220,8, 0x0a2244,8, -0x0a2280,16, +0x0a2280,7, +0x0a22a0,8, 0x0a22c4,8, 0x0a2400,1, 0x0a2418,1, @@ -4490,16 +4659,16 @@ 0x0a2534,1, 0x0a254c,1, 0x0a2570,2, -0x0a2600,3, +0x0a2600,1, 0x0a2610,2, 0x0a2804,15, 0x0a2844,15, 0x0a2884,15, 0x0a28c4,15, 0x0a2904,15, -0x0a2944,18, +0x0a2944,16, 0x0a2990,2, -0x0a29a0,3, +0x0a29a0,1, 0x0a29b0,2, 0x0a29c0,2, 0x0a2a00,400, @@ -4514,13 +4683,13 @@ 0x0a32c0,2, 0x0a32cc,2, 0x0a32d8,3, -0x0a3300,3, +0x0a3300,1, 0x0a3310,2, -0x0a3320,3, +0x0a3320,1, 0x0a3330,2, -0x0a3340,3, +0x0a3340,1, 0x0a3350,2, -0x0a3360,3, +0x0a3360,1, 0x0a3370,2, 0x0a3380,1, 0x0a3400,16, @@ -4535,13 +4704,13 @@ 0x0a36c0,2, 0x0a36cc,2, 0x0a36d8,3, -0x0a3700,3, +0x0a3700,1, 0x0a3710,2, -0x0a3720,3, +0x0a3720,1, 0x0a3730,2, -0x0a3740,3, +0x0a3740,1, 0x0a3750,2, -0x0a3760,3, +0x0a3760,1, 0x0a3770,2, 0x0a3780,1, 0x0a3800,16, @@ -4556,13 +4725,13 @@ 0x0a3ac0,2, 0x0a3acc,2, 0x0a3ad8,3, -0x0a3b00,3, +0x0a3b00,1, 0x0a3b10,2, -0x0a3b20,3, +0x0a3b20,1, 0x0a3b30,2, -0x0a3b40,3, +0x0a3b40,1, 0x0a3b50,2, -0x0a3b60,3, +0x0a3b60,1, 0x0a3b70,2, 0x0a3b80,1, 0x0a3c00,18, @@ -4592,39 +4761,36 @@ 0x0a3f44,1, 0x0a3f50,4, 0x0a3fa0,3, -0x0a4000,9, +0x0a4000,5, +0x0a4018,3, 0x0a4080,2, 0x0a408c,1, -0x0a4094,1, -0x0a40a0,11, +0x0a40a0,9, 0x0a40d0,2, 0x0a40e0,1, 0x0a40e8,1, 0x0a4100,2, 0x0a410c,1, -0x0a4114,1, -0x0a4120,11, +0x0a4120,9, 0x0a4150,2, 0x0a4160,1, 0x0a4168,1, 0x0a4180,2, 0x0a418c,1, -0x0a4194,1, -0x0a41a0,11, +0x0a41a0,9, 0x0a41d0,2, 0x0a41e0,1, 0x0a41e8,1, 0x0a4200,2, 0x0a420c,1, -0x0a4214,1, -0x0a4220,11, +0x0a4220,9, 0x0a4250,2, 0x0a4260,1, 0x0a4268,1, -0x0a4280,3, +0x0a4284,2, 0x0a42a8,2, 0x0a42b4,1, -0x0a42c0,3, +0x0a42c4,2, 0x0a42e8,2, 0x0a42f4,1, 0x0a4400,3, @@ -4644,47 +4810,44 @@ 0x0a4600,15, 0x0a4640,3, 0x0a4650,3, -0x0a4660,3, +0x0a4660,1, 0x0a4670,2, -0x0a4680,3, +0x0a4680,1, 0x0a4690,2, 0x0a46c0,4, 0x0a46d4,8, 0x0a4700,4, 0x0a4714,8, -0x0a4800,9, +0x0a4800,5, +0x0a4818,3, 0x0a4880,2, 0x0a488c,1, -0x0a4894,1, -0x0a48a0,11, +0x0a48a0,9, 0x0a48d0,2, 0x0a48e0,1, 0x0a48e8,1, 0x0a4900,2, 0x0a490c,1, -0x0a4914,1, -0x0a4920,11, +0x0a4920,9, 0x0a4950,2, 0x0a4960,1, 0x0a4968,1, 0x0a4980,2, 0x0a498c,1, -0x0a4994,1, -0x0a49a0,11, +0x0a49a0,9, 0x0a49d0,2, 0x0a49e0,1, 0x0a49e8,1, 0x0a4a00,2, 0x0a4a0c,1, -0x0a4a14,1, -0x0a4a20,11, +0x0a4a20,9, 0x0a4a50,2, 0x0a4a60,1, 0x0a4a68,1, -0x0a4a80,3, +0x0a4a84,2, 0x0a4aa8,2, 0x0a4ab4,1, -0x0a4ac0,3, +0x0a4ac4,2, 0x0a4ae8,2, 0x0a4af4,1, 0x0a4c00,3, @@ -4704,47 +4867,44 @@ 0x0a4e00,15, 0x0a4e40,3, 0x0a4e50,3, -0x0a4e60,3, +0x0a4e60,1, 0x0a4e70,2, -0x0a4e80,3, +0x0a4e80,1, 0x0a4e90,2, 0x0a4ec0,4, 0x0a4ed4,8, 0x0a4f00,4, 0x0a4f14,8, -0x0a5000,9, +0x0a5000,5, +0x0a5018,3, 0x0a5080,2, 0x0a508c,1, -0x0a5094,1, -0x0a50a0,11, +0x0a50a0,9, 0x0a50d0,2, 0x0a50e0,1, 0x0a50e8,1, 0x0a5100,2, 0x0a510c,1, -0x0a5114,1, -0x0a5120,11, +0x0a5120,9, 0x0a5150,2, 0x0a5160,1, 0x0a5168,1, 0x0a5180,2, 0x0a518c,1, -0x0a5194,1, -0x0a51a0,11, +0x0a51a0,9, 0x0a51d0,2, 0x0a51e0,1, 0x0a51e8,1, 0x0a5200,2, 0x0a520c,1, -0x0a5214,1, -0x0a5220,11, +0x0a5220,9, 0x0a5250,2, 0x0a5260,1, 0x0a5268,1, -0x0a5280,3, +0x0a5284,2, 0x0a52a8,2, 0x0a52b4,1, -0x0a52c0,3, +0x0a52c4,2, 0x0a52e8,2, 0x0a52f4,1, 0x0a5400,3, @@ -4764,9 +4924,9 @@ 0x0a5600,15, 0x0a5640,3, 0x0a5650,3, -0x0a5660,3, +0x0a5660,1, 0x0a5670,2, -0x0a5680,3, +0x0a5680,1, 0x0a5690,2, 0x0a56c0,4, 0x0a56d4,8, @@ -4775,29 +4935,35 @@ 0x0a5800,31, 0x0a5880,8, 0x0a58a4,1, -0x0a58b4,22, +0x0a58b4,20, 0x0a5910,2, 0x0a5920,3, 0x0a5934,1, -0x0a593c,4, +0x0a593c,2, 0x0a5950,2, 0x0a5a00,11, 0x0a5a4c,8, 0x0a5a70,2, 0x0a5a7c,33, 0x0a5c00,8, -0x0a5c40,14, +0x0a5c40,2, +0x0a5c4c,11, 0x0a5c80,8, -0x0a5cc0,14, +0x0a5cc0,2, +0x0a5ccc,11, 0x0a5d00,8, -0x0a5d40,14, +0x0a5d40,2, +0x0a5d4c,11, 0x0a5d80,8, -0x0a5dc0,14, +0x0a5dc0,2, +0x0a5dcc,11, 0x0a5e00,8, -0x0a5e40,14, +0x0a5e40,2, +0x0a5e4c,11, 0x0a5e80,8, -0x0a5ec0,14, -0x0a5f00,11, +0x0a5ec0,2, +0x0a5ecc,11, +0x0a5f00,9, 0x0a5f30,2, 0x0a5f40,49, 0x0a6018,1, @@ -4806,120 +4972,132 @@ 0x0a6134,1, 0x0a614c,1, 0x0a6170,2, -0x0a6200,3, +0x0a6200,1, 0x0a6210,2, 0x0a6400,5, 0x0a6418,9, 0x0a6440,5, -0x0a6460,3, +0x0a6460,1, 0x0a6470,2, 0x0a6500,5, 0x0a6518,9, 0x0a6540,5, -0x0a6560,3, +0x0a6560,1, 0x0a6570,2, 0x0a6600,5, 0x0a6618,9, 0x0a6640,5, -0x0a6660,3, +0x0a6660,1, 0x0a6670,2, 0x0a6700,1, 0x0a6800,6, 0x0a681c,3, -0x0a682c,12, +0x0a682c,3, +0x0a683c,8, 0x0a6860,1, 0x0a6868,1, 0x0a6870,2, -0x0a6880,3, +0x0a6880,1, 0x0a6890,2, -0x0a68a0,3, +0x0a68a0,1, 0x0a68b0,2, -0x0a68c0,3, +0x0a68c0,1, 0x0a68d0,2, -0x0a68e0,3, +0x0a68e0,1, 0x0a68f0,2, 0x0a6900,29, -0x0a6980,29, +0x0a6980,27, +0x0a69f0,1, 0x0a6c00,6, 0x0a6c1c,3, -0x0a6c2c,12, +0x0a6c2c,3, +0x0a6c3c,8, 0x0a6c60,1, 0x0a6c68,1, 0x0a6c70,2, -0x0a6c80,3, +0x0a6c80,1, 0x0a6c90,2, -0x0a6ca0,3, +0x0a6ca0,1, 0x0a6cb0,2, -0x0a6cc0,3, +0x0a6cc0,1, 0x0a6cd0,2, -0x0a6ce0,3, +0x0a6ce0,1, 0x0a6cf0,2, 0x0a6d00,29, -0x0a6d80,29, +0x0a6d80,27, +0x0a6df0,1, 0x0a7000,6, 0x0a701c,3, -0x0a702c,12, +0x0a702c,3, +0x0a703c,8, 0x0a7060,1, 0x0a7068,1, 0x0a7070,2, -0x0a7080,3, +0x0a7080,1, 0x0a7090,2, -0x0a70a0,3, +0x0a70a0,1, 0x0a70b0,2, -0x0a70c0,3, +0x0a70c0,1, 0x0a70d0,2, -0x0a70e0,3, +0x0a70e0,1, 0x0a70f0,2, 0x0a7100,29, -0x0a7180,29, +0x0a7180,27, +0x0a71f0,1, 0x0a7400,6, 0x0a741c,3, -0x0a742c,12, +0x0a742c,3, +0x0a743c,8, 0x0a7460,1, 0x0a7468,1, 0x0a7470,2, -0x0a7480,3, +0x0a7480,1, 0x0a7490,2, -0x0a74a0,3, +0x0a74a0,1, 0x0a74b0,2, -0x0a74c0,3, +0x0a74c0,1, 0x0a74d0,2, -0x0a74e0,3, +0x0a74e0,1, 0x0a74f0,2, 0x0a7500,29, -0x0a7580,29, +0x0a7580,27, +0x0a75f0,1, 0x0a7800,6, 0x0a781c,3, -0x0a782c,12, +0x0a782c,3, +0x0a783c,8, 0x0a7860,1, 0x0a7868,1, 0x0a7870,2, -0x0a7880,3, +0x0a7880,1, 0x0a7890,2, -0x0a78a0,3, +0x0a78a0,1, 0x0a78b0,2, -0x0a78c0,3, +0x0a78c0,1, 0x0a78d0,2, -0x0a78e0,3, +0x0a78e0,1, 0x0a78f0,2, 0x0a7900,29, -0x0a7980,29, +0x0a7980,27, +0x0a79f0,1, 0x0a7c00,6, 0x0a7c1c,3, -0x0a7c2c,12, +0x0a7c2c,3, +0x0a7c3c,8, 0x0a7c60,1, 0x0a7c68,1, 0x0a7c70,2, -0x0a7c80,3, +0x0a7c80,1, 0x0a7c90,2, -0x0a7ca0,3, +0x0a7ca0,1, 0x0a7cb0,2, -0x0a7cc0,3, +0x0a7cc0,1, 0x0a7cd0,2, -0x0a7ce0,3, +0x0a7ce0,1, 0x0a7cf0,2, 0x0a7d00,29, -0x0a7d80,29, +0x0a7d80,27, +0x0a7df0,1, 0x0a8000,2, 0x0a8018,2, 0x0a8034,2, @@ -4927,17 +5105,17 @@ 0x0a8134,2, 0x0a814c,1, 0x0a8170,2, -0x0a8200,3, +0x0a8200,1, 0x0a8210,2, -0x0a8220,3, +0x0a8220,1, 0x0a8230,2, -0x0a8400,3, +0x0a8400,1, 0x0a8410,2, 0x0a8420,3, 0x0a8430,22, 0x0a84ac,1, 0x0a84c0,6, -0x0a8500,3, +0x0a8500,1, 0x0a8510,2, 0x0a8520,3, 0x0a8540,8, @@ -4952,110 +5130,134 @@ 0x0a8800,5, 0x0a8820,5, 0x0a8890,10, -0x0a88e0,3, +0x0a88e0,1, 0x0a88f0,2, 0x0a8900,5, 0x0a8920,5, 0x0a8990,10, -0x0a89e0,3, +0x0a89e0,1, 0x0a89f0,2, -0x0a8a00,3, +0x0a8a00,1, 0x0a8a10,2, -0x0a8a20,3, +0x0a8a20,1, 0x0a8a30,2, 0x0a8a48,3, -0x0a8a80,18, +0x0a8a80,3, +0x0a8a90,1, +0x0a8a98,12, 0x0a8b04,2, 0x0a8b14,3, 0x0a8b24,2, 0x0a8b34,3, -0x0a8b80,11, +0x0a8b80,5, +0x0a8b98,3, 0x0a8bb0,2, -0x0a8bc0,11, +0x0a8bc0,5, +0x0a8bd8,3, 0x0a8bf0,2, -0x0a8c00,23, -0x0a8c80,27, +0x0a8c00,10, +0x0a8c2c,12, +0x0a8c80,26, 0x0a8d00,2, 0x0a8d20,1, -0x0a8e00,23, -0x0a8e80,27, +0x0a8e00,10, +0x0a8e2c,12, +0x0a8e80,26, 0x0a8f00,2, 0x0a8f20,1, 0x0a9000,5, 0x0a9020,5, 0x0a9090,10, -0x0a90e0,3, +0x0a90e0,1, 0x0a90f0,2, 0x0a9100,5, 0x0a9120,5, 0x0a9190,10, -0x0a91e0,3, +0x0a91e0,1, 0x0a91f0,2, -0x0a9200,3, +0x0a9200,1, 0x0a9210,2, -0x0a9220,3, +0x0a9220,1, 0x0a9230,2, 0x0a9248,3, -0x0a9280,18, +0x0a9280,3, +0x0a9290,1, +0x0a9298,12, 0x0a9304,2, 0x0a9314,3, 0x0a9324,2, 0x0a9334,3, -0x0a9380,11, +0x0a9380,5, +0x0a9398,3, 0x0a93b0,2, -0x0a93c0,11, +0x0a93c0,5, +0x0a93d8,3, 0x0a93f0,2, -0x0a9400,23, -0x0a9480,27, +0x0a9400,10, +0x0a942c,12, +0x0a9480,26, 0x0a9500,2, 0x0a9520,1, -0x0a9600,23, -0x0a9680,27, +0x0a9600,10, +0x0a962c,12, +0x0a9680,26, 0x0a9700,2, 0x0a9720,1, 0x0a9800,5, 0x0a9820,5, 0x0a9890,10, -0x0a98e0,3, +0x0a98e0,1, 0x0a98f0,2, 0x0a9900,5, 0x0a9920,5, 0x0a9990,10, -0x0a99e0,3, +0x0a99e0,1, 0x0a99f0,2, -0x0a9a00,3, +0x0a9a00,1, 0x0a9a10,2, -0x0a9a20,3, +0x0a9a20,1, 0x0a9a30,2, 0x0a9a48,3, -0x0a9a80,18, +0x0a9a80,3, +0x0a9a90,1, +0x0a9a98,12, 0x0a9b04,2, 0x0a9b14,3, 0x0a9b24,2, 0x0a9b34,3, -0x0a9b80,11, +0x0a9b80,5, +0x0a9b98,3, 0x0a9bb0,2, -0x0a9bc0,11, +0x0a9bc0,5, +0x0a9bd8,3, 0x0a9bf0,2, -0x0a9c00,23, -0x0a9c80,27, +0x0a9c00,10, +0x0a9c2c,12, +0x0a9c80,26, 0x0a9d00,2, 0x0a9d20,1, -0x0a9e00,23, -0x0a9e80,27, +0x0a9e00,10, +0x0a9e2c,12, +0x0a9e80,26, 0x0a9f00,2, 0x0a9f20,1, -0x0aa000,16, +0x0aa000,7, +0x0aa020,8, 0x0aa044,8, -0x0aa080,16, +0x0aa080,7, +0x0aa0a0,8, 0x0aa0c4,8, -0x0aa100,16, +0x0aa100,7, +0x0aa120,8, 0x0aa144,8, -0x0aa180,16, +0x0aa180,7, +0x0aa1a0,8, 0x0aa1c4,8, -0x0aa200,16, +0x0aa200,7, +0x0aa220,8, 0x0aa244,8, -0x0aa280,16, +0x0aa280,7, +0x0aa2a0,8, 0x0aa2c4,8, 0x0aa400,1, 0x0aa418,1, @@ -5064,16 +5266,16 @@ 0x0aa534,1, 0x0aa54c,1, 0x0aa570,2, -0x0aa600,3, +0x0aa600,1, 0x0aa610,2, 0x0aa804,15, 0x0aa844,15, 0x0aa884,15, 0x0aa8c4,15, 0x0aa904,15, -0x0aa944,18, +0x0aa944,16, 0x0aa990,2, -0x0aa9a0,3, +0x0aa9a0,1, 0x0aa9b0,2, 0x0aa9c0,2, 0x0aaa00,400, @@ -5088,13 +5290,13 @@ 0x0ab2c0,2, 0x0ab2cc,2, 0x0ab2d8,3, -0x0ab300,3, +0x0ab300,1, 0x0ab310,2, -0x0ab320,3, +0x0ab320,1, 0x0ab330,2, -0x0ab340,3, +0x0ab340,1, 0x0ab350,2, -0x0ab360,3, +0x0ab360,1, 0x0ab370,2, 0x0ab380,1, 0x0ab400,16, @@ -5109,13 +5311,13 @@ 0x0ab6c0,2, 0x0ab6cc,2, 0x0ab6d8,3, -0x0ab700,3, +0x0ab700,1, 0x0ab710,2, -0x0ab720,3, +0x0ab720,1, 0x0ab730,2, -0x0ab740,3, +0x0ab740,1, 0x0ab750,2, -0x0ab760,3, +0x0ab760,1, 0x0ab770,2, 0x0ab780,1, 0x0ab800,16, @@ -5130,13 +5332,13 @@ 0x0abac0,2, 0x0abacc,2, 0x0abad8,3, -0x0abb00,3, +0x0abb00,1, 0x0abb10,2, -0x0abb20,3, +0x0abb20,1, 0x0abb30,2, -0x0abb40,3, +0x0abb40,1, 0x0abb50,2, -0x0abb60,3, +0x0abb60,1, 0x0abb70,2, 0x0abb80,1, 0x0abc00,18, @@ -5166,39 +5368,36 @@ 0x0abf44,1, 0x0abf50,4, 0x0abfa0,3, -0x0ac000,9, +0x0ac000,5, +0x0ac018,3, 0x0ac080,2, 0x0ac08c,1, -0x0ac094,1, -0x0ac0a0,11, +0x0ac0a0,9, 0x0ac0d0,2, 0x0ac0e0,1, 0x0ac0e8,1, 0x0ac100,2, 0x0ac10c,1, -0x0ac114,1, -0x0ac120,11, +0x0ac120,9, 0x0ac150,2, 0x0ac160,1, 0x0ac168,1, 0x0ac180,2, 0x0ac18c,1, -0x0ac194,1, -0x0ac1a0,11, +0x0ac1a0,9, 0x0ac1d0,2, 0x0ac1e0,1, 0x0ac1e8,1, 0x0ac200,2, 0x0ac20c,1, -0x0ac214,1, -0x0ac220,11, +0x0ac220,9, 0x0ac250,2, 0x0ac260,1, 0x0ac268,1, -0x0ac280,3, +0x0ac284,2, 0x0ac2a8,2, 0x0ac2b4,1, -0x0ac2c0,3, +0x0ac2c4,2, 0x0ac2e8,2, 0x0ac2f4,1, 0x0ac400,3, @@ -5218,47 +5417,44 @@ 0x0ac600,15, 0x0ac640,3, 0x0ac650,3, -0x0ac660,3, +0x0ac660,1, 0x0ac670,2, -0x0ac680,3, +0x0ac680,1, 0x0ac690,2, 0x0ac6c0,4, 0x0ac6d4,8, 0x0ac700,4, 0x0ac714,8, -0x0ac800,9, +0x0ac800,5, +0x0ac818,3, 0x0ac880,2, 0x0ac88c,1, -0x0ac894,1, -0x0ac8a0,11, +0x0ac8a0,9, 0x0ac8d0,2, 0x0ac8e0,1, 0x0ac8e8,1, 0x0ac900,2, 0x0ac90c,1, -0x0ac914,1, -0x0ac920,11, +0x0ac920,9, 0x0ac950,2, 0x0ac960,1, 0x0ac968,1, 0x0ac980,2, 0x0ac98c,1, -0x0ac994,1, -0x0ac9a0,11, +0x0ac9a0,9, 0x0ac9d0,2, 0x0ac9e0,1, 0x0ac9e8,1, 0x0aca00,2, 0x0aca0c,1, -0x0aca14,1, -0x0aca20,11, +0x0aca20,9, 0x0aca50,2, 0x0aca60,1, 0x0aca68,1, -0x0aca80,3, +0x0aca84,2, 0x0acaa8,2, 0x0acab4,1, -0x0acac0,3, +0x0acac4,2, 0x0acae8,2, 0x0acaf4,1, 0x0acc00,3, @@ -5278,47 +5474,44 @@ 0x0ace00,15, 0x0ace40,3, 0x0ace50,3, -0x0ace60,3, +0x0ace60,1, 0x0ace70,2, -0x0ace80,3, +0x0ace80,1, 0x0ace90,2, 0x0acec0,4, 0x0aced4,8, 0x0acf00,4, 0x0acf14,8, -0x0ad000,9, +0x0ad000,5, +0x0ad018,3, 0x0ad080,2, 0x0ad08c,1, -0x0ad094,1, -0x0ad0a0,11, +0x0ad0a0,9, 0x0ad0d0,2, 0x0ad0e0,1, 0x0ad0e8,1, 0x0ad100,2, 0x0ad10c,1, -0x0ad114,1, -0x0ad120,11, +0x0ad120,9, 0x0ad150,2, 0x0ad160,1, 0x0ad168,1, 0x0ad180,2, 0x0ad18c,1, -0x0ad194,1, -0x0ad1a0,11, +0x0ad1a0,9, 0x0ad1d0,2, 0x0ad1e0,1, 0x0ad1e8,1, 0x0ad200,2, 0x0ad20c,1, -0x0ad214,1, -0x0ad220,11, +0x0ad220,9, 0x0ad250,2, 0x0ad260,1, 0x0ad268,1, -0x0ad280,3, +0x0ad284,2, 0x0ad2a8,2, 0x0ad2b4,1, -0x0ad2c0,3, +0x0ad2c4,2, 0x0ad2e8,2, 0x0ad2f4,1, 0x0ad400,3, @@ -5338,9 +5531,9 @@ 0x0ad600,15, 0x0ad640,3, 0x0ad650,3, -0x0ad660,3, +0x0ad660,1, 0x0ad670,2, -0x0ad680,3, +0x0ad680,1, 0x0ad690,2, 0x0ad6c0,4, 0x0ad6d4,8, @@ -5349,29 +5542,35 @@ 0x0ad800,31, 0x0ad880,8, 0x0ad8a4,1, -0x0ad8b4,22, +0x0ad8b4,20, 0x0ad910,2, 0x0ad920,3, 0x0ad934,1, -0x0ad93c,4, +0x0ad93c,2, 0x0ad950,2, 0x0ada00,11, 0x0ada4c,8, 0x0ada70,2, 0x0ada7c,33, 0x0adc00,8, -0x0adc40,14, +0x0adc40,2, +0x0adc4c,11, 0x0adc80,8, -0x0adcc0,14, +0x0adcc0,2, +0x0adccc,11, 0x0add00,8, -0x0add40,14, +0x0add40,2, +0x0add4c,11, 0x0add80,8, -0x0addc0,14, +0x0addc0,2, +0x0addcc,11, 0x0ade00,8, -0x0ade40,14, +0x0ade40,2, +0x0ade4c,11, 0x0ade80,8, -0x0adec0,14, -0x0adf00,11, +0x0adec0,2, +0x0adecc,11, +0x0adf00,9, 0x0adf30,2, 0x0adf40,49, 0x0ae018,1, @@ -5380,120 +5579,132 @@ 0x0ae134,1, 0x0ae14c,1, 0x0ae170,2, -0x0ae200,3, +0x0ae200,1, 0x0ae210,2, 0x0ae400,5, 0x0ae418,9, 0x0ae440,5, -0x0ae460,3, +0x0ae460,1, 0x0ae470,2, 0x0ae500,5, 0x0ae518,9, 0x0ae540,5, -0x0ae560,3, +0x0ae560,1, 0x0ae570,2, 0x0ae600,5, 0x0ae618,9, 0x0ae640,5, -0x0ae660,3, +0x0ae660,1, 0x0ae670,2, 0x0ae700,1, 0x0ae800,6, 0x0ae81c,3, -0x0ae82c,12, +0x0ae82c,3, +0x0ae83c,8, 0x0ae860,1, 0x0ae868,1, 0x0ae870,2, -0x0ae880,3, +0x0ae880,1, 0x0ae890,2, -0x0ae8a0,3, +0x0ae8a0,1, 0x0ae8b0,2, -0x0ae8c0,3, +0x0ae8c0,1, 0x0ae8d0,2, -0x0ae8e0,3, +0x0ae8e0,1, 0x0ae8f0,2, 0x0ae900,29, -0x0ae980,29, +0x0ae980,27, +0x0ae9f0,1, 0x0aec00,6, 0x0aec1c,3, -0x0aec2c,12, +0x0aec2c,3, +0x0aec3c,8, 0x0aec60,1, 0x0aec68,1, 0x0aec70,2, -0x0aec80,3, +0x0aec80,1, 0x0aec90,2, -0x0aeca0,3, +0x0aeca0,1, 0x0aecb0,2, -0x0aecc0,3, +0x0aecc0,1, 0x0aecd0,2, -0x0aece0,3, +0x0aece0,1, 0x0aecf0,2, 0x0aed00,29, -0x0aed80,29, +0x0aed80,27, +0x0aedf0,1, 0x0af000,6, 0x0af01c,3, -0x0af02c,12, +0x0af02c,3, +0x0af03c,8, 0x0af060,1, 0x0af068,1, 0x0af070,2, -0x0af080,3, +0x0af080,1, 0x0af090,2, -0x0af0a0,3, +0x0af0a0,1, 0x0af0b0,2, -0x0af0c0,3, +0x0af0c0,1, 0x0af0d0,2, -0x0af0e0,3, +0x0af0e0,1, 0x0af0f0,2, 0x0af100,29, -0x0af180,29, +0x0af180,27, +0x0af1f0,1, 0x0af400,6, 0x0af41c,3, -0x0af42c,12, +0x0af42c,3, +0x0af43c,8, 0x0af460,1, 0x0af468,1, 0x0af470,2, -0x0af480,3, +0x0af480,1, 0x0af490,2, -0x0af4a0,3, +0x0af4a0,1, 0x0af4b0,2, -0x0af4c0,3, +0x0af4c0,1, 0x0af4d0,2, -0x0af4e0,3, +0x0af4e0,1, 0x0af4f0,2, 0x0af500,29, -0x0af580,29, +0x0af580,27, +0x0af5f0,1, 0x0af800,6, 0x0af81c,3, -0x0af82c,12, +0x0af82c,3, +0x0af83c,8, 0x0af860,1, 0x0af868,1, 0x0af870,2, -0x0af880,3, +0x0af880,1, 0x0af890,2, -0x0af8a0,3, +0x0af8a0,1, 0x0af8b0,2, -0x0af8c0,3, +0x0af8c0,1, 0x0af8d0,2, -0x0af8e0,3, +0x0af8e0,1, 0x0af8f0,2, 0x0af900,29, -0x0af980,29, +0x0af980,27, +0x0af9f0,1, 0x0afc00,6, 0x0afc1c,3, -0x0afc2c,12, +0x0afc2c,3, +0x0afc3c,8, 0x0afc60,1, 0x0afc68,1, 0x0afc70,2, -0x0afc80,3, +0x0afc80,1, 0x0afc90,2, -0x0afca0,3, +0x0afca0,1, 0x0afcb0,2, -0x0afcc0,3, +0x0afcc0,1, 0x0afcd0,2, -0x0afce0,3, +0x0afce0,1, 0x0afcf0,2, 0x0afd00,29, -0x0afd80,29, +0x0afd80,27, +0x0afdf0,1, 0x0b0000,2, 0x0b0018,2, 0x0b0034,2, @@ -5501,17 +5712,17 @@ 0x0b0134,2, 0x0b014c,1, 0x0b0170,2, -0x0b0200,3, +0x0b0200,1, 0x0b0210,2, -0x0b0220,3, +0x0b0220,1, 0x0b0230,2, -0x0b0400,3, +0x0b0400,1, 0x0b0410,2, 0x0b0420,3, 0x0b0430,22, 0x0b04ac,1, 0x0b04c0,6, -0x0b0500,3, +0x0b0500,1, 0x0b0510,2, 0x0b0520,3, 0x0b0540,8, @@ -5526,110 +5737,134 @@ 0x0b0800,5, 0x0b0820,5, 0x0b0890,10, -0x0b08e0,3, +0x0b08e0,1, 0x0b08f0,2, 0x0b0900,5, 0x0b0920,5, 0x0b0990,10, -0x0b09e0,3, +0x0b09e0,1, 0x0b09f0,2, -0x0b0a00,3, +0x0b0a00,1, 0x0b0a10,2, -0x0b0a20,3, +0x0b0a20,1, 0x0b0a30,2, 0x0b0a48,3, -0x0b0a80,18, +0x0b0a80,3, +0x0b0a90,1, +0x0b0a98,12, 0x0b0b04,2, 0x0b0b14,3, 0x0b0b24,2, 0x0b0b34,3, -0x0b0b80,11, +0x0b0b80,5, +0x0b0b98,3, 0x0b0bb0,2, -0x0b0bc0,11, +0x0b0bc0,5, +0x0b0bd8,3, 0x0b0bf0,2, -0x0b0c00,23, -0x0b0c80,27, +0x0b0c00,10, +0x0b0c2c,12, +0x0b0c80,26, 0x0b0d00,2, 0x0b0d20,1, -0x0b0e00,23, -0x0b0e80,27, +0x0b0e00,10, +0x0b0e2c,12, +0x0b0e80,26, 0x0b0f00,2, 0x0b0f20,1, 0x0b1000,5, 0x0b1020,5, 0x0b1090,10, -0x0b10e0,3, +0x0b10e0,1, 0x0b10f0,2, 0x0b1100,5, 0x0b1120,5, 0x0b1190,10, -0x0b11e0,3, +0x0b11e0,1, 0x0b11f0,2, -0x0b1200,3, +0x0b1200,1, 0x0b1210,2, -0x0b1220,3, +0x0b1220,1, 0x0b1230,2, 0x0b1248,3, -0x0b1280,18, +0x0b1280,3, +0x0b1290,1, +0x0b1298,12, 0x0b1304,2, 0x0b1314,3, 0x0b1324,2, 0x0b1334,3, -0x0b1380,11, +0x0b1380,5, +0x0b1398,3, 0x0b13b0,2, -0x0b13c0,11, +0x0b13c0,5, +0x0b13d8,3, 0x0b13f0,2, -0x0b1400,23, -0x0b1480,27, +0x0b1400,10, +0x0b142c,12, +0x0b1480,26, 0x0b1500,2, 0x0b1520,1, -0x0b1600,23, -0x0b1680,27, +0x0b1600,10, +0x0b162c,12, +0x0b1680,26, 0x0b1700,2, 0x0b1720,1, 0x0b1800,5, 0x0b1820,5, 0x0b1890,10, -0x0b18e0,3, +0x0b18e0,1, 0x0b18f0,2, 0x0b1900,5, 0x0b1920,5, 0x0b1990,10, -0x0b19e0,3, +0x0b19e0,1, 0x0b19f0,2, -0x0b1a00,3, +0x0b1a00,1, 0x0b1a10,2, -0x0b1a20,3, +0x0b1a20,1, 0x0b1a30,2, 0x0b1a48,3, -0x0b1a80,18, +0x0b1a80,3, +0x0b1a90,1, +0x0b1a98,12, 0x0b1b04,2, 0x0b1b14,3, 0x0b1b24,2, 0x0b1b34,3, -0x0b1b80,11, +0x0b1b80,5, +0x0b1b98,3, 0x0b1bb0,2, -0x0b1bc0,11, +0x0b1bc0,5, +0x0b1bd8,3, 0x0b1bf0,2, -0x0b1c00,23, -0x0b1c80,27, +0x0b1c00,10, +0x0b1c2c,12, +0x0b1c80,26, 0x0b1d00,2, 0x0b1d20,1, -0x0b1e00,23, -0x0b1e80,27, +0x0b1e00,10, +0x0b1e2c,12, +0x0b1e80,26, 0x0b1f00,2, 0x0b1f20,1, -0x0b2000,16, +0x0b2000,7, +0x0b2020,8, 0x0b2044,8, -0x0b2080,16, +0x0b2080,7, +0x0b20a0,8, 0x0b20c4,8, -0x0b2100,16, +0x0b2100,7, +0x0b2120,8, 0x0b2144,8, -0x0b2180,16, +0x0b2180,7, +0x0b21a0,8, 0x0b21c4,8, -0x0b2200,16, +0x0b2200,7, +0x0b2220,8, 0x0b2244,8, -0x0b2280,16, +0x0b2280,7, +0x0b22a0,8, 0x0b22c4,8, 0x0b2400,1, 0x0b2418,1, @@ -5638,16 +5873,16 @@ 0x0b2534,1, 0x0b254c,1, 0x0b2570,2, -0x0b2600,3, +0x0b2600,1, 0x0b2610,2, 0x0b2804,15, 0x0b2844,15, 0x0b2884,15, 0x0b28c4,15, 0x0b2904,15, -0x0b2944,18, +0x0b2944,16, 0x0b2990,2, -0x0b29a0,3, +0x0b29a0,1, 0x0b29b0,2, 0x0b29c0,2, 0x0b2a00,400, @@ -5662,13 +5897,13 @@ 0x0b32c0,2, 0x0b32cc,2, 0x0b32d8,3, -0x0b3300,3, +0x0b3300,1, 0x0b3310,2, -0x0b3320,3, +0x0b3320,1, 0x0b3330,2, -0x0b3340,3, +0x0b3340,1, 0x0b3350,2, -0x0b3360,3, +0x0b3360,1, 0x0b3370,2, 0x0b3380,1, 0x0b3400,16, @@ -5683,13 +5918,13 @@ 0x0b36c0,2, 0x0b36cc,2, 0x0b36d8,3, -0x0b3700,3, +0x0b3700,1, 0x0b3710,2, -0x0b3720,3, +0x0b3720,1, 0x0b3730,2, -0x0b3740,3, +0x0b3740,1, 0x0b3750,2, -0x0b3760,3, +0x0b3760,1, 0x0b3770,2, 0x0b3780,1, 0x0b3800,16, @@ -5704,13 +5939,13 @@ 0x0b3ac0,2, 0x0b3acc,2, 0x0b3ad8,3, -0x0b3b00,3, +0x0b3b00,1, 0x0b3b10,2, -0x0b3b20,3, +0x0b3b20,1, 0x0b3b30,2, -0x0b3b40,3, +0x0b3b40,1, 0x0b3b50,2, -0x0b3b60,3, +0x0b3b60,1, 0x0b3b70,2, 0x0b3b80,1, 0x0b3c00,18, @@ -5740,39 +5975,36 @@ 0x0b3f44,1, 0x0b3f50,4, 0x0b3fa0,3, -0x0b4000,9, +0x0b4000,5, +0x0b4018,3, 0x0b4080,2, 0x0b408c,1, -0x0b4094,1, -0x0b40a0,11, +0x0b40a0,9, 0x0b40d0,2, 0x0b40e0,1, 0x0b40e8,1, 0x0b4100,2, 0x0b410c,1, -0x0b4114,1, -0x0b4120,11, +0x0b4120,9, 0x0b4150,2, 0x0b4160,1, 0x0b4168,1, 0x0b4180,2, 0x0b418c,1, -0x0b4194,1, -0x0b41a0,11, +0x0b41a0,9, 0x0b41d0,2, 0x0b41e0,1, 0x0b41e8,1, 0x0b4200,2, 0x0b420c,1, -0x0b4214,1, -0x0b4220,11, +0x0b4220,9, 0x0b4250,2, 0x0b4260,1, 0x0b4268,1, -0x0b4280,3, +0x0b4284,2, 0x0b42a8,2, 0x0b42b4,1, -0x0b42c0,3, +0x0b42c4,2, 0x0b42e8,2, 0x0b42f4,1, 0x0b4400,3, @@ -5792,47 +6024,44 @@ 0x0b4600,15, 0x0b4640,3, 0x0b4650,3, -0x0b4660,3, +0x0b4660,1, 0x0b4670,2, -0x0b4680,3, +0x0b4680,1, 0x0b4690,2, 0x0b46c0,4, 0x0b46d4,8, 0x0b4700,4, 0x0b4714,8, -0x0b4800,9, +0x0b4800,5, +0x0b4818,3, 0x0b4880,2, 0x0b488c,1, -0x0b4894,1, -0x0b48a0,11, +0x0b48a0,9, 0x0b48d0,2, 0x0b48e0,1, 0x0b48e8,1, 0x0b4900,2, 0x0b490c,1, -0x0b4914,1, -0x0b4920,11, +0x0b4920,9, 0x0b4950,2, 0x0b4960,1, 0x0b4968,1, 0x0b4980,2, 0x0b498c,1, -0x0b4994,1, -0x0b49a0,11, +0x0b49a0,9, 0x0b49d0,2, 0x0b49e0,1, 0x0b49e8,1, 0x0b4a00,2, 0x0b4a0c,1, -0x0b4a14,1, -0x0b4a20,11, +0x0b4a20,9, 0x0b4a50,2, 0x0b4a60,1, 0x0b4a68,1, -0x0b4a80,3, +0x0b4a84,2, 0x0b4aa8,2, 0x0b4ab4,1, -0x0b4ac0,3, +0x0b4ac4,2, 0x0b4ae8,2, 0x0b4af4,1, 0x0b4c00,3, @@ -5852,47 +6081,44 @@ 0x0b4e00,15, 0x0b4e40,3, 0x0b4e50,3, -0x0b4e60,3, +0x0b4e60,1, 0x0b4e70,2, -0x0b4e80,3, +0x0b4e80,1, 0x0b4e90,2, 0x0b4ec0,4, 0x0b4ed4,8, 0x0b4f00,4, 0x0b4f14,8, -0x0b5000,9, +0x0b5000,5, +0x0b5018,3, 0x0b5080,2, 0x0b508c,1, -0x0b5094,1, -0x0b50a0,11, +0x0b50a0,9, 0x0b50d0,2, 0x0b50e0,1, 0x0b50e8,1, 0x0b5100,2, 0x0b510c,1, -0x0b5114,1, -0x0b5120,11, +0x0b5120,9, 0x0b5150,2, 0x0b5160,1, 0x0b5168,1, 0x0b5180,2, 0x0b518c,1, -0x0b5194,1, -0x0b51a0,11, +0x0b51a0,9, 0x0b51d0,2, 0x0b51e0,1, 0x0b51e8,1, 0x0b5200,2, 0x0b520c,1, -0x0b5214,1, -0x0b5220,11, +0x0b5220,9, 0x0b5250,2, 0x0b5260,1, 0x0b5268,1, -0x0b5280,3, +0x0b5284,2, 0x0b52a8,2, 0x0b52b4,1, -0x0b52c0,3, +0x0b52c4,2, 0x0b52e8,2, 0x0b52f4,1, 0x0b5400,3, @@ -5912,9 +6138,9 @@ 0x0b5600,15, 0x0b5640,3, 0x0b5650,3, -0x0b5660,3, +0x0b5660,1, 0x0b5670,2, -0x0b5680,3, +0x0b5680,1, 0x0b5690,2, 0x0b56c0,4, 0x0b56d4,8, @@ -5923,29 +6149,35 @@ 0x0b5800,31, 0x0b5880,8, 0x0b58a4,1, -0x0b58b4,22, +0x0b58b4,20, 0x0b5910,2, 0x0b5920,3, 0x0b5934,1, -0x0b593c,4, +0x0b593c,2, 0x0b5950,2, 0x0b5a00,11, 0x0b5a4c,8, 0x0b5a70,2, 0x0b5a7c,33, 0x0b5c00,8, -0x0b5c40,14, +0x0b5c40,2, +0x0b5c4c,11, 0x0b5c80,8, -0x0b5cc0,14, +0x0b5cc0,2, +0x0b5ccc,11, 0x0b5d00,8, -0x0b5d40,14, +0x0b5d40,2, +0x0b5d4c,11, 0x0b5d80,8, -0x0b5dc0,14, +0x0b5dc0,2, +0x0b5dcc,11, 0x0b5e00,8, -0x0b5e40,14, +0x0b5e40,2, +0x0b5e4c,11, 0x0b5e80,8, -0x0b5ec0,14, -0x0b5f00,11, +0x0b5ec0,2, +0x0b5ecc,11, +0x0b5f00,9, 0x0b5f30,2, 0x0b5f40,49, 0x0b6018,1, @@ -5954,120 +6186,132 @@ 0x0b6134,1, 0x0b614c,1, 0x0b6170,2, -0x0b6200,3, +0x0b6200,1, 0x0b6210,2, 0x0b6400,5, 0x0b6418,9, 0x0b6440,5, -0x0b6460,3, +0x0b6460,1, 0x0b6470,2, 0x0b6500,5, 0x0b6518,9, 0x0b6540,5, -0x0b6560,3, +0x0b6560,1, 0x0b6570,2, 0x0b6600,5, 0x0b6618,9, 0x0b6640,5, -0x0b6660,3, +0x0b6660,1, 0x0b6670,2, 0x0b6700,1, 0x0b6800,6, 0x0b681c,3, -0x0b682c,12, +0x0b682c,3, +0x0b683c,8, 0x0b6860,1, 0x0b6868,1, 0x0b6870,2, -0x0b6880,3, +0x0b6880,1, 0x0b6890,2, -0x0b68a0,3, +0x0b68a0,1, 0x0b68b0,2, -0x0b68c0,3, +0x0b68c0,1, 0x0b68d0,2, -0x0b68e0,3, +0x0b68e0,1, 0x0b68f0,2, 0x0b6900,29, -0x0b6980,29, +0x0b6980,27, +0x0b69f0,1, 0x0b6c00,6, 0x0b6c1c,3, -0x0b6c2c,12, +0x0b6c2c,3, +0x0b6c3c,8, 0x0b6c60,1, 0x0b6c68,1, 0x0b6c70,2, -0x0b6c80,3, +0x0b6c80,1, 0x0b6c90,2, -0x0b6ca0,3, +0x0b6ca0,1, 0x0b6cb0,2, -0x0b6cc0,3, +0x0b6cc0,1, 0x0b6cd0,2, -0x0b6ce0,3, +0x0b6ce0,1, 0x0b6cf0,2, 0x0b6d00,29, -0x0b6d80,29, +0x0b6d80,27, +0x0b6df0,1, 0x0b7000,6, 0x0b701c,3, -0x0b702c,12, +0x0b702c,3, +0x0b703c,8, 0x0b7060,1, 0x0b7068,1, 0x0b7070,2, -0x0b7080,3, +0x0b7080,1, 0x0b7090,2, -0x0b70a0,3, +0x0b70a0,1, 0x0b70b0,2, -0x0b70c0,3, +0x0b70c0,1, 0x0b70d0,2, -0x0b70e0,3, +0x0b70e0,1, 0x0b70f0,2, 0x0b7100,29, -0x0b7180,29, +0x0b7180,27, +0x0b71f0,1, 0x0b7400,6, 0x0b741c,3, -0x0b742c,12, +0x0b742c,3, +0x0b743c,8, 0x0b7460,1, 0x0b7468,1, 0x0b7470,2, -0x0b7480,3, +0x0b7480,1, 0x0b7490,2, -0x0b74a0,3, +0x0b74a0,1, 0x0b74b0,2, -0x0b74c0,3, +0x0b74c0,1, 0x0b74d0,2, -0x0b74e0,3, +0x0b74e0,1, 0x0b74f0,2, 0x0b7500,29, -0x0b7580,29, +0x0b7580,27, +0x0b75f0,1, 0x0b7800,6, 0x0b781c,3, -0x0b782c,12, +0x0b782c,3, +0x0b783c,8, 0x0b7860,1, 0x0b7868,1, 0x0b7870,2, -0x0b7880,3, +0x0b7880,1, 0x0b7890,2, -0x0b78a0,3, +0x0b78a0,1, 0x0b78b0,2, -0x0b78c0,3, +0x0b78c0,1, 0x0b78d0,2, -0x0b78e0,3, +0x0b78e0,1, 0x0b78f0,2, 0x0b7900,29, -0x0b7980,29, +0x0b7980,27, +0x0b79f0,1, 0x0b7c00,6, 0x0b7c1c,3, -0x0b7c2c,12, +0x0b7c2c,3, +0x0b7c3c,8, 0x0b7c60,1, 0x0b7c68,1, 0x0b7c70,2, -0x0b7c80,3, +0x0b7c80,1, 0x0b7c90,2, -0x0b7ca0,3, +0x0b7ca0,1, 0x0b7cb0,2, -0x0b7cc0,3, +0x0b7cc0,1, 0x0b7cd0,2, -0x0b7ce0,3, +0x0b7ce0,1, 0x0b7cf0,2, 0x0b7d00,29, -0x0b7d80,29, +0x0b7d80,27, +0x0b7df0,1, 0x0b8000,2, 0x0b8018,2, 0x0b8034,2, @@ -6075,17 +6319,17 @@ 0x0b8134,2, 0x0b814c,1, 0x0b8170,2, -0x0b8200,3, +0x0b8200,1, 0x0b8210,2, -0x0b8220,3, +0x0b8220,1, 0x0b8230,2, -0x0b8400,3, +0x0b8400,1, 0x0b8410,2, 0x0b8420,3, 0x0b8430,22, 0x0b84ac,1, 0x0b84c0,6, -0x0b8500,3, +0x0b8500,1, 0x0b8510,2, 0x0b8520,3, 0x0b8540,8, @@ -6100,110 +6344,134 @@ 0x0b8800,5, 0x0b8820,5, 0x0b8890,10, -0x0b88e0,3, +0x0b88e0,1, 0x0b88f0,2, 0x0b8900,5, 0x0b8920,5, 0x0b8990,10, -0x0b89e0,3, +0x0b89e0,1, 0x0b89f0,2, -0x0b8a00,3, +0x0b8a00,1, 0x0b8a10,2, -0x0b8a20,3, +0x0b8a20,1, 0x0b8a30,2, 0x0b8a48,3, -0x0b8a80,18, +0x0b8a80,3, +0x0b8a90,1, +0x0b8a98,12, 0x0b8b04,2, 0x0b8b14,3, 0x0b8b24,2, 0x0b8b34,3, -0x0b8b80,11, +0x0b8b80,5, +0x0b8b98,3, 0x0b8bb0,2, -0x0b8bc0,11, +0x0b8bc0,5, +0x0b8bd8,3, 0x0b8bf0,2, -0x0b8c00,23, -0x0b8c80,27, +0x0b8c00,10, +0x0b8c2c,12, +0x0b8c80,26, 0x0b8d00,2, 0x0b8d20,1, -0x0b8e00,23, -0x0b8e80,27, +0x0b8e00,10, +0x0b8e2c,12, +0x0b8e80,26, 0x0b8f00,2, 0x0b8f20,1, 0x0b9000,5, 0x0b9020,5, 0x0b9090,10, -0x0b90e0,3, +0x0b90e0,1, 0x0b90f0,2, 0x0b9100,5, 0x0b9120,5, 0x0b9190,10, -0x0b91e0,3, +0x0b91e0,1, 0x0b91f0,2, -0x0b9200,3, +0x0b9200,1, 0x0b9210,2, -0x0b9220,3, +0x0b9220,1, 0x0b9230,2, 0x0b9248,3, -0x0b9280,18, +0x0b9280,3, +0x0b9290,1, +0x0b9298,12, 0x0b9304,2, 0x0b9314,3, 0x0b9324,2, 0x0b9334,3, -0x0b9380,11, +0x0b9380,5, +0x0b9398,3, 0x0b93b0,2, -0x0b93c0,11, +0x0b93c0,5, +0x0b93d8,3, 0x0b93f0,2, -0x0b9400,23, -0x0b9480,27, +0x0b9400,10, +0x0b942c,12, +0x0b9480,26, 0x0b9500,2, 0x0b9520,1, -0x0b9600,23, -0x0b9680,27, +0x0b9600,10, +0x0b962c,12, +0x0b9680,26, 0x0b9700,2, 0x0b9720,1, 0x0b9800,5, 0x0b9820,5, 0x0b9890,10, -0x0b98e0,3, +0x0b98e0,1, 0x0b98f0,2, 0x0b9900,5, 0x0b9920,5, 0x0b9990,10, -0x0b99e0,3, +0x0b99e0,1, 0x0b99f0,2, -0x0b9a00,3, +0x0b9a00,1, 0x0b9a10,2, -0x0b9a20,3, +0x0b9a20,1, 0x0b9a30,2, 0x0b9a48,3, -0x0b9a80,18, +0x0b9a80,3, +0x0b9a90,1, +0x0b9a98,12, 0x0b9b04,2, 0x0b9b14,3, 0x0b9b24,2, 0x0b9b34,3, -0x0b9b80,11, +0x0b9b80,5, +0x0b9b98,3, 0x0b9bb0,2, -0x0b9bc0,11, +0x0b9bc0,5, +0x0b9bd8,3, 0x0b9bf0,2, -0x0b9c00,23, -0x0b9c80,27, +0x0b9c00,10, +0x0b9c2c,12, +0x0b9c80,26, 0x0b9d00,2, 0x0b9d20,1, -0x0b9e00,23, -0x0b9e80,27, +0x0b9e00,10, +0x0b9e2c,12, +0x0b9e80,26, 0x0b9f00,2, 0x0b9f20,1, -0x0ba000,16, +0x0ba000,7, +0x0ba020,8, 0x0ba044,8, -0x0ba080,16, +0x0ba080,7, +0x0ba0a0,8, 0x0ba0c4,8, -0x0ba100,16, +0x0ba100,7, +0x0ba120,8, 0x0ba144,8, -0x0ba180,16, +0x0ba180,7, +0x0ba1a0,8, 0x0ba1c4,8, -0x0ba200,16, +0x0ba200,7, +0x0ba220,8, 0x0ba244,8, -0x0ba280,16, +0x0ba280,7, +0x0ba2a0,8, 0x0ba2c4,8, 0x0ba400,1, 0x0ba418,1, @@ -6212,16 +6480,16 @@ 0x0ba534,1, 0x0ba54c,1, 0x0ba570,2, -0x0ba600,3, +0x0ba600,1, 0x0ba610,2, 0x0ba804,15, 0x0ba844,15, 0x0ba884,15, 0x0ba8c4,15, 0x0ba904,15, -0x0ba944,18, +0x0ba944,16, 0x0ba990,2, -0x0ba9a0,3, +0x0ba9a0,1, 0x0ba9b0,2, 0x0ba9c0,2, 0x0baa00,400, @@ -6236,13 +6504,13 @@ 0x0bb2c0,2, 0x0bb2cc,2, 0x0bb2d8,3, -0x0bb300,3, +0x0bb300,1, 0x0bb310,2, -0x0bb320,3, +0x0bb320,1, 0x0bb330,2, -0x0bb340,3, +0x0bb340,1, 0x0bb350,2, -0x0bb360,3, +0x0bb360,1, 0x0bb370,2, 0x0bb380,1, 0x0bb400,16, @@ -6257,13 +6525,13 @@ 0x0bb6c0,2, 0x0bb6cc,2, 0x0bb6d8,3, -0x0bb700,3, +0x0bb700,1, 0x0bb710,2, -0x0bb720,3, +0x0bb720,1, 0x0bb730,2, -0x0bb740,3, +0x0bb740,1, 0x0bb750,2, -0x0bb760,3, +0x0bb760,1, 0x0bb770,2, 0x0bb780,1, 0x0bb800,16, @@ -6278,13 +6546,13 @@ 0x0bbac0,2, 0x0bbacc,2, 0x0bbad8,3, -0x0bbb00,3, +0x0bbb00,1, 0x0bbb10,2, -0x0bbb20,3, +0x0bbb20,1, 0x0bbb30,2, -0x0bbb40,3, +0x0bbb40,1, 0x0bbb50,2, -0x0bbb60,3, +0x0bbb60,1, 0x0bbb70,2, 0x0bbb80,1, 0x0bbc00,18, @@ -6314,39 +6582,36 @@ 0x0bbf44,1, 0x0bbf50,4, 0x0bbfa0,3, -0x0bc000,9, +0x0bc000,5, +0x0bc018,3, 0x0bc080,2, 0x0bc08c,1, -0x0bc094,1, -0x0bc0a0,11, +0x0bc0a0,9, 0x0bc0d0,2, 0x0bc0e0,1, 0x0bc0e8,1, 0x0bc100,2, 0x0bc10c,1, -0x0bc114,1, -0x0bc120,11, +0x0bc120,9, 0x0bc150,2, 0x0bc160,1, 0x0bc168,1, 0x0bc180,2, 0x0bc18c,1, -0x0bc194,1, -0x0bc1a0,11, +0x0bc1a0,9, 0x0bc1d0,2, 0x0bc1e0,1, 0x0bc1e8,1, 0x0bc200,2, 0x0bc20c,1, -0x0bc214,1, -0x0bc220,11, +0x0bc220,9, 0x0bc250,2, 0x0bc260,1, 0x0bc268,1, -0x0bc280,3, +0x0bc284,2, 0x0bc2a8,2, 0x0bc2b4,1, -0x0bc2c0,3, +0x0bc2c4,2, 0x0bc2e8,2, 0x0bc2f4,1, 0x0bc400,3, @@ -6366,47 +6631,44 @@ 0x0bc600,15, 0x0bc640,3, 0x0bc650,3, -0x0bc660,3, +0x0bc660,1, 0x0bc670,2, -0x0bc680,3, +0x0bc680,1, 0x0bc690,2, 0x0bc6c0,4, 0x0bc6d4,8, 0x0bc700,4, 0x0bc714,8, -0x0bc800,9, +0x0bc800,5, +0x0bc818,3, 0x0bc880,2, 0x0bc88c,1, -0x0bc894,1, -0x0bc8a0,11, +0x0bc8a0,9, 0x0bc8d0,2, 0x0bc8e0,1, 0x0bc8e8,1, 0x0bc900,2, 0x0bc90c,1, -0x0bc914,1, -0x0bc920,11, +0x0bc920,9, 0x0bc950,2, 0x0bc960,1, 0x0bc968,1, 0x0bc980,2, 0x0bc98c,1, -0x0bc994,1, -0x0bc9a0,11, +0x0bc9a0,9, 0x0bc9d0,2, 0x0bc9e0,1, 0x0bc9e8,1, 0x0bca00,2, 0x0bca0c,1, -0x0bca14,1, -0x0bca20,11, +0x0bca20,9, 0x0bca50,2, 0x0bca60,1, 0x0bca68,1, -0x0bca80,3, +0x0bca84,2, 0x0bcaa8,2, 0x0bcab4,1, -0x0bcac0,3, +0x0bcac4,2, 0x0bcae8,2, 0x0bcaf4,1, 0x0bcc00,3, @@ -6426,47 +6688,44 @@ 0x0bce00,15, 0x0bce40,3, 0x0bce50,3, -0x0bce60,3, +0x0bce60,1, 0x0bce70,2, -0x0bce80,3, +0x0bce80,1, 0x0bce90,2, 0x0bcec0,4, 0x0bced4,8, 0x0bcf00,4, 0x0bcf14,8, -0x0bd000,9, +0x0bd000,5, +0x0bd018,3, 0x0bd080,2, 0x0bd08c,1, -0x0bd094,1, -0x0bd0a0,11, +0x0bd0a0,9, 0x0bd0d0,2, 0x0bd0e0,1, 0x0bd0e8,1, 0x0bd100,2, 0x0bd10c,1, -0x0bd114,1, -0x0bd120,11, +0x0bd120,9, 0x0bd150,2, 0x0bd160,1, 0x0bd168,1, 0x0bd180,2, 0x0bd18c,1, -0x0bd194,1, -0x0bd1a0,11, +0x0bd1a0,9, 0x0bd1d0,2, 0x0bd1e0,1, 0x0bd1e8,1, 0x0bd200,2, 0x0bd20c,1, -0x0bd214,1, -0x0bd220,11, +0x0bd220,9, 0x0bd250,2, 0x0bd260,1, 0x0bd268,1, -0x0bd280,3, +0x0bd284,2, 0x0bd2a8,2, 0x0bd2b4,1, -0x0bd2c0,3, +0x0bd2c4,2, 0x0bd2e8,2, 0x0bd2f4,1, 0x0bd400,3, @@ -6486,9 +6745,9 @@ 0x0bd600,15, 0x0bd640,3, 0x0bd650,3, -0x0bd660,3, +0x0bd660,1, 0x0bd670,2, -0x0bd680,3, +0x0bd680,1, 0x0bd690,2, 0x0bd6c0,4, 0x0bd6d4,8, @@ -6497,29 +6756,35 @@ 0x0bd800,31, 0x0bd880,8, 0x0bd8a4,1, -0x0bd8b4,22, +0x0bd8b4,20, 0x0bd910,2, 0x0bd920,3, 0x0bd934,1, -0x0bd93c,4, +0x0bd93c,2, 0x0bd950,2, 0x0bda00,11, 0x0bda4c,8, 0x0bda70,2, 0x0bda7c,33, 0x0bdc00,8, -0x0bdc40,14, +0x0bdc40,2, +0x0bdc4c,11, 0x0bdc80,8, -0x0bdcc0,14, +0x0bdcc0,2, +0x0bdccc,11, 0x0bdd00,8, -0x0bdd40,14, +0x0bdd40,2, +0x0bdd4c,11, 0x0bdd80,8, -0x0bddc0,14, +0x0bddc0,2, +0x0bddcc,11, 0x0bde00,8, -0x0bde40,14, +0x0bde40,2, +0x0bde4c,11, 0x0bde80,8, -0x0bdec0,14, -0x0bdf00,11, +0x0bdec0,2, +0x0bdecc,11, +0x0bdf00,9, 0x0bdf30,2, 0x0bdf40,49, 0x0be018,1, @@ -6528,120 +6793,132 @@ 0x0be134,1, 0x0be14c,1, 0x0be170,2, -0x0be200,3, +0x0be200,1, 0x0be210,2, 0x0be400,5, 0x0be418,9, 0x0be440,5, -0x0be460,3, +0x0be460,1, 0x0be470,2, 0x0be500,5, 0x0be518,9, 0x0be540,5, -0x0be560,3, +0x0be560,1, 0x0be570,2, 0x0be600,5, 0x0be618,9, 0x0be640,5, -0x0be660,3, +0x0be660,1, 0x0be670,2, 0x0be700,1, 0x0be800,6, 0x0be81c,3, -0x0be82c,12, +0x0be82c,3, +0x0be83c,8, 0x0be860,1, 0x0be868,1, 0x0be870,2, -0x0be880,3, +0x0be880,1, 0x0be890,2, -0x0be8a0,3, +0x0be8a0,1, 0x0be8b0,2, -0x0be8c0,3, +0x0be8c0,1, 0x0be8d0,2, -0x0be8e0,3, +0x0be8e0,1, 0x0be8f0,2, 0x0be900,29, -0x0be980,29, +0x0be980,27, +0x0be9f0,1, 0x0bec00,6, 0x0bec1c,3, -0x0bec2c,12, +0x0bec2c,3, +0x0bec3c,8, 0x0bec60,1, 0x0bec68,1, 0x0bec70,2, -0x0bec80,3, +0x0bec80,1, 0x0bec90,2, -0x0beca0,3, +0x0beca0,1, 0x0becb0,2, -0x0becc0,3, +0x0becc0,1, 0x0becd0,2, -0x0bece0,3, +0x0bece0,1, 0x0becf0,2, 0x0bed00,29, -0x0bed80,29, +0x0bed80,27, +0x0bedf0,1, 0x0bf000,6, 0x0bf01c,3, -0x0bf02c,12, +0x0bf02c,3, +0x0bf03c,8, 0x0bf060,1, 0x0bf068,1, 0x0bf070,2, -0x0bf080,3, +0x0bf080,1, 0x0bf090,2, -0x0bf0a0,3, +0x0bf0a0,1, 0x0bf0b0,2, -0x0bf0c0,3, +0x0bf0c0,1, 0x0bf0d0,2, -0x0bf0e0,3, +0x0bf0e0,1, 0x0bf0f0,2, 0x0bf100,29, -0x0bf180,29, +0x0bf180,27, +0x0bf1f0,1, 0x0bf400,6, 0x0bf41c,3, -0x0bf42c,12, +0x0bf42c,3, +0x0bf43c,8, 0x0bf460,1, 0x0bf468,1, 0x0bf470,2, -0x0bf480,3, +0x0bf480,1, 0x0bf490,2, -0x0bf4a0,3, +0x0bf4a0,1, 0x0bf4b0,2, -0x0bf4c0,3, +0x0bf4c0,1, 0x0bf4d0,2, -0x0bf4e0,3, +0x0bf4e0,1, 0x0bf4f0,2, 0x0bf500,29, -0x0bf580,29, +0x0bf580,27, +0x0bf5f0,1, 0x0bf800,6, 0x0bf81c,3, -0x0bf82c,12, +0x0bf82c,3, +0x0bf83c,8, 0x0bf860,1, 0x0bf868,1, 0x0bf870,2, -0x0bf880,3, +0x0bf880,1, 0x0bf890,2, -0x0bf8a0,3, +0x0bf8a0,1, 0x0bf8b0,2, -0x0bf8c0,3, +0x0bf8c0,1, 0x0bf8d0,2, -0x0bf8e0,3, +0x0bf8e0,1, 0x0bf8f0,2, 0x0bf900,29, -0x0bf980,29, +0x0bf980,27, +0x0bf9f0,1, 0x0bfc00,6, 0x0bfc1c,3, -0x0bfc2c,12, +0x0bfc2c,3, +0x0bfc3c,8, 0x0bfc60,1, 0x0bfc68,1, 0x0bfc70,2, -0x0bfc80,3, +0x0bfc80,1, 0x0bfc90,2, -0x0bfca0,3, +0x0bfca0,1, 0x0bfcb0,2, -0x0bfcc0,3, +0x0bfcc0,1, 0x0bfcd0,2, -0x0bfce0,3, +0x0bfce0,1, 0x0bfcf0,2, 0x0bfd00,29, -0x0bfd80,29, +0x0bfd80,27, +0x0bfdf0,1, 0x0c0000,2, 0x0c0018,2, 0x0c0034,2, @@ -6649,17 +6926,17 @@ 0x0c0134,2, 0x0c014c,1, 0x0c0170,2, -0x0c0200,3, +0x0c0200,1, 0x0c0210,2, -0x0c0220,3, +0x0c0220,1, 0x0c0230,2, -0x0c0400,3, +0x0c0400,1, 0x0c0410,2, 0x0c0420,3, 0x0c0430,22, 0x0c04ac,1, 0x0c04c0,6, -0x0c0500,3, +0x0c0500,1, 0x0c0510,2, 0x0c0520,3, 0x0c0540,8, @@ -6674,110 +6951,134 @@ 0x0c0800,5, 0x0c0820,5, 0x0c0890,10, -0x0c08e0,3, +0x0c08e0,1, 0x0c08f0,2, 0x0c0900,5, 0x0c0920,5, 0x0c0990,10, -0x0c09e0,3, +0x0c09e0,1, 0x0c09f0,2, -0x0c0a00,3, +0x0c0a00,1, 0x0c0a10,2, -0x0c0a20,3, +0x0c0a20,1, 0x0c0a30,2, 0x0c0a48,3, -0x0c0a80,18, +0x0c0a80,3, +0x0c0a90,1, +0x0c0a98,12, 0x0c0b04,2, 0x0c0b14,3, 0x0c0b24,2, 0x0c0b34,3, -0x0c0b80,11, +0x0c0b80,5, +0x0c0b98,3, 0x0c0bb0,2, -0x0c0bc0,11, +0x0c0bc0,5, +0x0c0bd8,3, 0x0c0bf0,2, -0x0c0c00,23, -0x0c0c80,27, +0x0c0c00,10, +0x0c0c2c,12, +0x0c0c80,26, 0x0c0d00,2, 0x0c0d20,1, -0x0c0e00,23, -0x0c0e80,27, +0x0c0e00,10, +0x0c0e2c,12, +0x0c0e80,26, 0x0c0f00,2, 0x0c0f20,1, 0x0c1000,5, 0x0c1020,5, 0x0c1090,10, -0x0c10e0,3, +0x0c10e0,1, 0x0c10f0,2, 0x0c1100,5, 0x0c1120,5, 0x0c1190,10, -0x0c11e0,3, +0x0c11e0,1, 0x0c11f0,2, -0x0c1200,3, +0x0c1200,1, 0x0c1210,2, -0x0c1220,3, +0x0c1220,1, 0x0c1230,2, 0x0c1248,3, -0x0c1280,18, +0x0c1280,3, +0x0c1290,1, +0x0c1298,12, 0x0c1304,2, 0x0c1314,3, 0x0c1324,2, 0x0c1334,3, -0x0c1380,11, +0x0c1380,5, +0x0c1398,3, 0x0c13b0,2, -0x0c13c0,11, +0x0c13c0,5, +0x0c13d8,3, 0x0c13f0,2, -0x0c1400,23, -0x0c1480,27, +0x0c1400,10, +0x0c142c,12, +0x0c1480,26, 0x0c1500,2, 0x0c1520,1, -0x0c1600,23, -0x0c1680,27, +0x0c1600,10, +0x0c162c,12, +0x0c1680,26, 0x0c1700,2, 0x0c1720,1, 0x0c1800,5, 0x0c1820,5, 0x0c1890,10, -0x0c18e0,3, +0x0c18e0,1, 0x0c18f0,2, 0x0c1900,5, 0x0c1920,5, 0x0c1990,10, -0x0c19e0,3, +0x0c19e0,1, 0x0c19f0,2, -0x0c1a00,3, +0x0c1a00,1, 0x0c1a10,2, -0x0c1a20,3, +0x0c1a20,1, 0x0c1a30,2, 0x0c1a48,3, -0x0c1a80,18, +0x0c1a80,3, +0x0c1a90,1, +0x0c1a98,12, 0x0c1b04,2, 0x0c1b14,3, 0x0c1b24,2, 0x0c1b34,3, -0x0c1b80,11, +0x0c1b80,5, +0x0c1b98,3, 0x0c1bb0,2, -0x0c1bc0,11, +0x0c1bc0,5, +0x0c1bd8,3, 0x0c1bf0,2, -0x0c1c00,23, -0x0c1c80,27, +0x0c1c00,10, +0x0c1c2c,12, +0x0c1c80,26, 0x0c1d00,2, 0x0c1d20,1, -0x0c1e00,23, -0x0c1e80,27, +0x0c1e00,10, +0x0c1e2c,12, +0x0c1e80,26, 0x0c1f00,2, 0x0c1f20,1, -0x0c2000,16, +0x0c2000,7, +0x0c2020,8, 0x0c2044,8, -0x0c2080,16, +0x0c2080,7, +0x0c20a0,8, 0x0c20c4,8, -0x0c2100,16, +0x0c2100,7, +0x0c2120,8, 0x0c2144,8, -0x0c2180,16, +0x0c2180,7, +0x0c21a0,8, 0x0c21c4,8, -0x0c2200,16, +0x0c2200,7, +0x0c2220,8, 0x0c2244,8, -0x0c2280,16, +0x0c2280,7, +0x0c22a0,8, 0x0c22c4,8, 0x0c2400,1, 0x0c2418,1, @@ -6786,16 +7087,16 @@ 0x0c2534,1, 0x0c254c,1, 0x0c2570,2, -0x0c2600,3, +0x0c2600,1, 0x0c2610,2, 0x0c2804,15, 0x0c2844,15, 0x0c2884,15, 0x0c28c4,15, 0x0c2904,15, -0x0c2944,18, +0x0c2944,16, 0x0c2990,2, -0x0c29a0,3, +0x0c29a0,1, 0x0c29b0,2, 0x0c29c0,2, 0x0c2a00,400, @@ -6810,13 +7111,13 @@ 0x0c32c0,2, 0x0c32cc,2, 0x0c32d8,3, -0x0c3300,3, +0x0c3300,1, 0x0c3310,2, -0x0c3320,3, +0x0c3320,1, 0x0c3330,2, -0x0c3340,3, +0x0c3340,1, 0x0c3350,2, -0x0c3360,3, +0x0c3360,1, 0x0c3370,2, 0x0c3380,1, 0x0c3400,16, @@ -6831,13 +7132,13 @@ 0x0c36c0,2, 0x0c36cc,2, 0x0c36d8,3, -0x0c3700,3, +0x0c3700,1, 0x0c3710,2, -0x0c3720,3, +0x0c3720,1, 0x0c3730,2, -0x0c3740,3, +0x0c3740,1, 0x0c3750,2, -0x0c3760,3, +0x0c3760,1, 0x0c3770,2, 0x0c3780,1, 0x0c3800,16, @@ -6852,13 +7153,13 @@ 0x0c3ac0,2, 0x0c3acc,2, 0x0c3ad8,3, -0x0c3b00,3, +0x0c3b00,1, 0x0c3b10,2, -0x0c3b20,3, +0x0c3b20,1, 0x0c3b30,2, -0x0c3b40,3, +0x0c3b40,1, 0x0c3b50,2, -0x0c3b60,3, +0x0c3b60,1, 0x0c3b70,2, 0x0c3b80,1, 0x0c3c00,18, @@ -6888,39 +7189,36 @@ 0x0c3f44,1, 0x0c3f50,4, 0x0c3fa0,3, -0x0c4000,9, +0x0c4000,5, +0x0c4018,3, 0x0c4080,2, 0x0c408c,1, -0x0c4094,1, -0x0c40a0,11, +0x0c40a0,9, 0x0c40d0,2, 0x0c40e0,1, 0x0c40e8,1, 0x0c4100,2, 0x0c410c,1, -0x0c4114,1, -0x0c4120,11, +0x0c4120,9, 0x0c4150,2, 0x0c4160,1, 0x0c4168,1, 0x0c4180,2, 0x0c418c,1, -0x0c4194,1, -0x0c41a0,11, +0x0c41a0,9, 0x0c41d0,2, 0x0c41e0,1, 0x0c41e8,1, 0x0c4200,2, 0x0c420c,1, -0x0c4214,1, -0x0c4220,11, +0x0c4220,9, 0x0c4250,2, 0x0c4260,1, 0x0c4268,1, -0x0c4280,3, +0x0c4284,2, 0x0c42a8,2, 0x0c42b4,1, -0x0c42c0,3, +0x0c42c4,2, 0x0c42e8,2, 0x0c42f4,1, 0x0c4400,3, @@ -6940,47 +7238,44 @@ 0x0c4600,15, 0x0c4640,3, 0x0c4650,3, -0x0c4660,3, +0x0c4660,1, 0x0c4670,2, -0x0c4680,3, +0x0c4680,1, 0x0c4690,2, 0x0c46c0,4, 0x0c46d4,8, 0x0c4700,4, 0x0c4714,8, -0x0c4800,9, +0x0c4800,5, +0x0c4818,3, 0x0c4880,2, 0x0c488c,1, -0x0c4894,1, -0x0c48a0,11, +0x0c48a0,9, 0x0c48d0,2, 0x0c48e0,1, 0x0c48e8,1, 0x0c4900,2, 0x0c490c,1, -0x0c4914,1, -0x0c4920,11, +0x0c4920,9, 0x0c4950,2, 0x0c4960,1, 0x0c4968,1, 0x0c4980,2, 0x0c498c,1, -0x0c4994,1, -0x0c49a0,11, +0x0c49a0,9, 0x0c49d0,2, 0x0c49e0,1, 0x0c49e8,1, 0x0c4a00,2, 0x0c4a0c,1, -0x0c4a14,1, -0x0c4a20,11, +0x0c4a20,9, 0x0c4a50,2, 0x0c4a60,1, 0x0c4a68,1, -0x0c4a80,3, +0x0c4a84,2, 0x0c4aa8,2, 0x0c4ab4,1, -0x0c4ac0,3, +0x0c4ac4,2, 0x0c4ae8,2, 0x0c4af4,1, 0x0c4c00,3, @@ -7000,47 +7295,44 @@ 0x0c4e00,15, 0x0c4e40,3, 0x0c4e50,3, -0x0c4e60,3, +0x0c4e60,1, 0x0c4e70,2, -0x0c4e80,3, +0x0c4e80,1, 0x0c4e90,2, 0x0c4ec0,4, 0x0c4ed4,8, 0x0c4f00,4, 0x0c4f14,8, -0x0c5000,9, +0x0c5000,5, +0x0c5018,3, 0x0c5080,2, 0x0c508c,1, -0x0c5094,1, -0x0c50a0,11, +0x0c50a0,9, 0x0c50d0,2, 0x0c50e0,1, 0x0c50e8,1, 0x0c5100,2, 0x0c510c,1, -0x0c5114,1, -0x0c5120,11, +0x0c5120,9, 0x0c5150,2, 0x0c5160,1, 0x0c5168,1, 0x0c5180,2, 0x0c518c,1, -0x0c5194,1, -0x0c51a0,11, +0x0c51a0,9, 0x0c51d0,2, 0x0c51e0,1, 0x0c51e8,1, 0x0c5200,2, 0x0c520c,1, -0x0c5214,1, -0x0c5220,11, +0x0c5220,9, 0x0c5250,2, 0x0c5260,1, 0x0c5268,1, -0x0c5280,3, +0x0c5284,2, 0x0c52a8,2, 0x0c52b4,1, -0x0c52c0,3, +0x0c52c4,2, 0x0c52e8,2, 0x0c52f4,1, 0x0c5400,3, @@ -7060,9 +7352,9 @@ 0x0c5600,15, 0x0c5640,3, 0x0c5650,3, -0x0c5660,3, +0x0c5660,1, 0x0c5670,2, -0x0c5680,3, +0x0c5680,1, 0x0c5690,2, 0x0c56c0,4, 0x0c56d4,8, @@ -7071,29 +7363,35 @@ 0x0c5800,31, 0x0c5880,8, 0x0c58a4,1, -0x0c58b4,22, +0x0c58b4,20, 0x0c5910,2, 0x0c5920,3, 0x0c5934,1, -0x0c593c,4, +0x0c593c,2, 0x0c5950,2, 0x0c5a00,11, 0x0c5a4c,8, 0x0c5a70,2, 0x0c5a7c,33, 0x0c5c00,8, -0x0c5c40,14, +0x0c5c40,2, +0x0c5c4c,11, 0x0c5c80,8, -0x0c5cc0,14, +0x0c5cc0,2, +0x0c5ccc,11, 0x0c5d00,8, -0x0c5d40,14, +0x0c5d40,2, +0x0c5d4c,11, 0x0c5d80,8, -0x0c5dc0,14, +0x0c5dc0,2, +0x0c5dcc,11, 0x0c5e00,8, -0x0c5e40,14, +0x0c5e40,2, +0x0c5e4c,11, 0x0c5e80,8, -0x0c5ec0,14, -0x0c5f00,11, +0x0c5ec0,2, +0x0c5ecc,11, +0x0c5f00,9, 0x0c5f30,2, 0x0c5f40,49, 0x0c6018,1, @@ -7102,120 +7400,132 @@ 0x0c6134,1, 0x0c614c,1, 0x0c6170,2, -0x0c6200,3, +0x0c6200,1, 0x0c6210,2, 0x0c6400,5, 0x0c6418,9, 0x0c6440,5, -0x0c6460,3, +0x0c6460,1, 0x0c6470,2, 0x0c6500,5, 0x0c6518,9, 0x0c6540,5, -0x0c6560,3, +0x0c6560,1, 0x0c6570,2, 0x0c6600,5, 0x0c6618,9, 0x0c6640,5, -0x0c6660,3, +0x0c6660,1, 0x0c6670,2, 0x0c6700,1, 0x0c6800,6, 0x0c681c,3, -0x0c682c,12, +0x0c682c,3, +0x0c683c,8, 0x0c6860,1, 0x0c6868,1, 0x0c6870,2, -0x0c6880,3, +0x0c6880,1, 0x0c6890,2, -0x0c68a0,3, +0x0c68a0,1, 0x0c68b0,2, -0x0c68c0,3, +0x0c68c0,1, 0x0c68d0,2, -0x0c68e0,3, +0x0c68e0,1, 0x0c68f0,2, 0x0c6900,29, -0x0c6980,29, +0x0c6980,27, +0x0c69f0,1, 0x0c6c00,6, 0x0c6c1c,3, -0x0c6c2c,12, +0x0c6c2c,3, +0x0c6c3c,8, 0x0c6c60,1, 0x0c6c68,1, 0x0c6c70,2, -0x0c6c80,3, +0x0c6c80,1, 0x0c6c90,2, -0x0c6ca0,3, +0x0c6ca0,1, 0x0c6cb0,2, -0x0c6cc0,3, +0x0c6cc0,1, 0x0c6cd0,2, -0x0c6ce0,3, +0x0c6ce0,1, 0x0c6cf0,2, 0x0c6d00,29, -0x0c6d80,29, +0x0c6d80,27, +0x0c6df0,1, 0x0c7000,6, 0x0c701c,3, -0x0c702c,12, +0x0c702c,3, +0x0c703c,8, 0x0c7060,1, 0x0c7068,1, 0x0c7070,2, -0x0c7080,3, +0x0c7080,1, 0x0c7090,2, -0x0c70a0,3, +0x0c70a0,1, 0x0c70b0,2, -0x0c70c0,3, +0x0c70c0,1, 0x0c70d0,2, -0x0c70e0,3, +0x0c70e0,1, 0x0c70f0,2, 0x0c7100,29, -0x0c7180,29, +0x0c7180,27, +0x0c71f0,1, 0x0c7400,6, 0x0c741c,3, -0x0c742c,12, +0x0c742c,3, +0x0c743c,8, 0x0c7460,1, 0x0c7468,1, 0x0c7470,2, -0x0c7480,3, +0x0c7480,1, 0x0c7490,2, -0x0c74a0,3, +0x0c74a0,1, 0x0c74b0,2, -0x0c74c0,3, +0x0c74c0,1, 0x0c74d0,2, -0x0c74e0,3, +0x0c74e0,1, 0x0c74f0,2, 0x0c7500,29, -0x0c7580,29, +0x0c7580,27, +0x0c75f0,1, 0x0c7800,6, 0x0c781c,3, -0x0c782c,12, +0x0c782c,3, +0x0c783c,8, 0x0c7860,1, 0x0c7868,1, 0x0c7870,2, -0x0c7880,3, +0x0c7880,1, 0x0c7890,2, -0x0c78a0,3, +0x0c78a0,1, 0x0c78b0,2, -0x0c78c0,3, +0x0c78c0,1, 0x0c78d0,2, -0x0c78e0,3, +0x0c78e0,1, 0x0c78f0,2, 0x0c7900,29, -0x0c7980,29, +0x0c7980,27, +0x0c79f0,1, 0x0c7c00,6, 0x0c7c1c,3, -0x0c7c2c,12, +0x0c7c2c,3, +0x0c7c3c,8, 0x0c7c60,1, 0x0c7c68,1, 0x0c7c70,2, -0x0c7c80,3, +0x0c7c80,1, 0x0c7c90,2, -0x0c7ca0,3, +0x0c7ca0,1, 0x0c7cb0,2, -0x0c7cc0,3, +0x0c7cc0,1, 0x0c7cd0,2, -0x0c7ce0,3, +0x0c7ce0,1, 0x0c7cf0,2, 0x0c7d00,29, -0x0c7d80,29, +0x0c7d80,27, +0x0c7df0,1, 0x0c8000,2, 0x0c8018,2, 0x0c8034,2, @@ -7223,17 +7533,17 @@ 0x0c8134,2, 0x0c814c,1, 0x0c8170,2, -0x0c8200,3, +0x0c8200,1, 0x0c8210,2, -0x0c8220,3, +0x0c8220,1, 0x0c8230,2, -0x0c8400,3, +0x0c8400,1, 0x0c8410,2, 0x0c8420,3, 0x0c8430,22, 0x0c84ac,1, 0x0c84c0,6, -0x0c8500,3, +0x0c8500,1, 0x0c8510,2, 0x0c8520,3, 0x0c8540,8, @@ -7248,110 +7558,134 @@ 0x0c8800,5, 0x0c8820,5, 0x0c8890,10, -0x0c88e0,3, +0x0c88e0,1, 0x0c88f0,2, 0x0c8900,5, 0x0c8920,5, 0x0c8990,10, -0x0c89e0,3, +0x0c89e0,1, 0x0c89f0,2, -0x0c8a00,3, +0x0c8a00,1, 0x0c8a10,2, -0x0c8a20,3, +0x0c8a20,1, 0x0c8a30,2, 0x0c8a48,3, -0x0c8a80,18, +0x0c8a80,3, +0x0c8a90,1, +0x0c8a98,12, 0x0c8b04,2, 0x0c8b14,3, 0x0c8b24,2, 0x0c8b34,3, -0x0c8b80,11, +0x0c8b80,5, +0x0c8b98,3, 0x0c8bb0,2, -0x0c8bc0,11, +0x0c8bc0,5, +0x0c8bd8,3, 0x0c8bf0,2, -0x0c8c00,23, -0x0c8c80,27, +0x0c8c00,10, +0x0c8c2c,12, +0x0c8c80,26, 0x0c8d00,2, 0x0c8d20,1, -0x0c8e00,23, -0x0c8e80,27, +0x0c8e00,10, +0x0c8e2c,12, +0x0c8e80,26, 0x0c8f00,2, 0x0c8f20,1, 0x0c9000,5, 0x0c9020,5, 0x0c9090,10, -0x0c90e0,3, +0x0c90e0,1, 0x0c90f0,2, 0x0c9100,5, 0x0c9120,5, 0x0c9190,10, -0x0c91e0,3, +0x0c91e0,1, 0x0c91f0,2, -0x0c9200,3, +0x0c9200,1, 0x0c9210,2, -0x0c9220,3, +0x0c9220,1, 0x0c9230,2, 0x0c9248,3, -0x0c9280,18, +0x0c9280,3, +0x0c9290,1, +0x0c9298,12, 0x0c9304,2, 0x0c9314,3, 0x0c9324,2, 0x0c9334,3, -0x0c9380,11, +0x0c9380,5, +0x0c9398,3, 0x0c93b0,2, -0x0c93c0,11, +0x0c93c0,5, +0x0c93d8,3, 0x0c93f0,2, -0x0c9400,23, -0x0c9480,27, +0x0c9400,10, +0x0c942c,12, +0x0c9480,26, 0x0c9500,2, 0x0c9520,1, -0x0c9600,23, -0x0c9680,27, +0x0c9600,10, +0x0c962c,12, +0x0c9680,26, 0x0c9700,2, 0x0c9720,1, 0x0c9800,5, 0x0c9820,5, 0x0c9890,10, -0x0c98e0,3, +0x0c98e0,1, 0x0c98f0,2, 0x0c9900,5, 0x0c9920,5, 0x0c9990,10, -0x0c99e0,3, +0x0c99e0,1, 0x0c99f0,2, -0x0c9a00,3, +0x0c9a00,1, 0x0c9a10,2, -0x0c9a20,3, +0x0c9a20,1, 0x0c9a30,2, 0x0c9a48,3, -0x0c9a80,18, +0x0c9a80,3, +0x0c9a90,1, +0x0c9a98,12, 0x0c9b04,2, 0x0c9b14,3, 0x0c9b24,2, 0x0c9b34,3, -0x0c9b80,11, +0x0c9b80,5, +0x0c9b98,3, 0x0c9bb0,2, -0x0c9bc0,11, +0x0c9bc0,5, +0x0c9bd8,3, 0x0c9bf0,2, -0x0c9c00,23, -0x0c9c80,27, +0x0c9c00,10, +0x0c9c2c,12, +0x0c9c80,26, 0x0c9d00,2, 0x0c9d20,1, -0x0c9e00,23, -0x0c9e80,27, +0x0c9e00,10, +0x0c9e2c,12, +0x0c9e80,26, 0x0c9f00,2, 0x0c9f20,1, -0x0ca000,16, +0x0ca000,7, +0x0ca020,8, 0x0ca044,8, -0x0ca080,16, +0x0ca080,7, +0x0ca0a0,8, 0x0ca0c4,8, -0x0ca100,16, +0x0ca100,7, +0x0ca120,8, 0x0ca144,8, -0x0ca180,16, +0x0ca180,7, +0x0ca1a0,8, 0x0ca1c4,8, -0x0ca200,16, +0x0ca200,7, +0x0ca220,8, 0x0ca244,8, -0x0ca280,16, +0x0ca280,7, +0x0ca2a0,8, 0x0ca2c4,8, 0x0ca400,1, 0x0ca418,1, @@ -7360,16 +7694,16 @@ 0x0ca534,1, 0x0ca54c,1, 0x0ca570,2, -0x0ca600,3, +0x0ca600,1, 0x0ca610,2, 0x0ca804,15, 0x0ca844,15, 0x0ca884,15, 0x0ca8c4,15, 0x0ca904,15, -0x0ca944,18, +0x0ca944,16, 0x0ca990,2, -0x0ca9a0,3, +0x0ca9a0,1, 0x0ca9b0,2, 0x0ca9c0,2, 0x0caa00,400, @@ -7384,13 +7718,13 @@ 0x0cb2c0,2, 0x0cb2cc,2, 0x0cb2d8,3, -0x0cb300,3, +0x0cb300,1, 0x0cb310,2, -0x0cb320,3, +0x0cb320,1, 0x0cb330,2, -0x0cb340,3, +0x0cb340,1, 0x0cb350,2, -0x0cb360,3, +0x0cb360,1, 0x0cb370,2, 0x0cb380,1, 0x0cb400,16, @@ -7405,13 +7739,13 @@ 0x0cb6c0,2, 0x0cb6cc,2, 0x0cb6d8,3, -0x0cb700,3, +0x0cb700,1, 0x0cb710,2, -0x0cb720,3, +0x0cb720,1, 0x0cb730,2, -0x0cb740,3, +0x0cb740,1, 0x0cb750,2, -0x0cb760,3, +0x0cb760,1, 0x0cb770,2, 0x0cb780,1, 0x0cb800,16, @@ -7426,13 +7760,13 @@ 0x0cbac0,2, 0x0cbacc,2, 0x0cbad8,3, -0x0cbb00,3, +0x0cbb00,1, 0x0cbb10,2, -0x0cbb20,3, +0x0cbb20,1, 0x0cbb30,2, -0x0cbb40,3, +0x0cbb40,1, 0x0cbb50,2, -0x0cbb60,3, +0x0cbb60,1, 0x0cbb70,2, 0x0cbb80,1, 0x0cbc00,18, @@ -7462,39 +7796,36 @@ 0x0cbf44,1, 0x0cbf50,4, 0x0cbfa0,3, -0x0cc000,9, +0x0cc000,5, +0x0cc018,3, 0x0cc080,2, 0x0cc08c,1, -0x0cc094,1, -0x0cc0a0,11, +0x0cc0a0,9, 0x0cc0d0,2, 0x0cc0e0,1, 0x0cc0e8,1, 0x0cc100,2, 0x0cc10c,1, -0x0cc114,1, -0x0cc120,11, +0x0cc120,9, 0x0cc150,2, 0x0cc160,1, 0x0cc168,1, 0x0cc180,2, 0x0cc18c,1, -0x0cc194,1, -0x0cc1a0,11, +0x0cc1a0,9, 0x0cc1d0,2, 0x0cc1e0,1, 0x0cc1e8,1, 0x0cc200,2, 0x0cc20c,1, -0x0cc214,1, -0x0cc220,11, +0x0cc220,9, 0x0cc250,2, 0x0cc260,1, 0x0cc268,1, -0x0cc280,3, +0x0cc284,2, 0x0cc2a8,2, 0x0cc2b4,1, -0x0cc2c0,3, +0x0cc2c4,2, 0x0cc2e8,2, 0x0cc2f4,1, 0x0cc400,3, @@ -7514,47 +7845,44 @@ 0x0cc600,15, 0x0cc640,3, 0x0cc650,3, -0x0cc660,3, +0x0cc660,1, 0x0cc670,2, -0x0cc680,3, +0x0cc680,1, 0x0cc690,2, 0x0cc6c0,4, 0x0cc6d4,8, 0x0cc700,4, 0x0cc714,8, -0x0cc800,9, +0x0cc800,5, +0x0cc818,3, 0x0cc880,2, 0x0cc88c,1, -0x0cc894,1, -0x0cc8a0,11, +0x0cc8a0,9, 0x0cc8d0,2, 0x0cc8e0,1, 0x0cc8e8,1, 0x0cc900,2, 0x0cc90c,1, -0x0cc914,1, -0x0cc920,11, +0x0cc920,9, 0x0cc950,2, 0x0cc960,1, 0x0cc968,1, 0x0cc980,2, 0x0cc98c,1, -0x0cc994,1, -0x0cc9a0,11, +0x0cc9a0,9, 0x0cc9d0,2, 0x0cc9e0,1, 0x0cc9e8,1, 0x0cca00,2, 0x0cca0c,1, -0x0cca14,1, -0x0cca20,11, +0x0cca20,9, 0x0cca50,2, 0x0cca60,1, 0x0cca68,1, -0x0cca80,3, +0x0cca84,2, 0x0ccaa8,2, 0x0ccab4,1, -0x0ccac0,3, +0x0ccac4,2, 0x0ccae8,2, 0x0ccaf4,1, 0x0ccc00,3, @@ -7574,47 +7902,44 @@ 0x0cce00,15, 0x0cce40,3, 0x0cce50,3, -0x0cce60,3, +0x0cce60,1, 0x0cce70,2, -0x0cce80,3, +0x0cce80,1, 0x0cce90,2, 0x0ccec0,4, 0x0cced4,8, 0x0ccf00,4, 0x0ccf14,8, -0x0cd000,9, +0x0cd000,5, +0x0cd018,3, 0x0cd080,2, 0x0cd08c,1, -0x0cd094,1, -0x0cd0a0,11, +0x0cd0a0,9, 0x0cd0d0,2, 0x0cd0e0,1, 0x0cd0e8,1, 0x0cd100,2, 0x0cd10c,1, -0x0cd114,1, -0x0cd120,11, +0x0cd120,9, 0x0cd150,2, 0x0cd160,1, 0x0cd168,1, 0x0cd180,2, 0x0cd18c,1, -0x0cd194,1, -0x0cd1a0,11, +0x0cd1a0,9, 0x0cd1d0,2, 0x0cd1e0,1, 0x0cd1e8,1, 0x0cd200,2, 0x0cd20c,1, -0x0cd214,1, -0x0cd220,11, +0x0cd220,9, 0x0cd250,2, 0x0cd260,1, 0x0cd268,1, -0x0cd280,3, +0x0cd284,2, 0x0cd2a8,2, 0x0cd2b4,1, -0x0cd2c0,3, +0x0cd2c4,2, 0x0cd2e8,2, 0x0cd2f4,1, 0x0cd400,3, @@ -7634,9 +7959,9 @@ 0x0cd600,15, 0x0cd640,3, 0x0cd650,3, -0x0cd660,3, +0x0cd660,1, 0x0cd670,2, -0x0cd680,3, +0x0cd680,1, 0x0cd690,2, 0x0cd6c0,4, 0x0cd6d4,8, @@ -7645,29 +7970,35 @@ 0x0cd800,31, 0x0cd880,8, 0x0cd8a4,1, -0x0cd8b4,22, +0x0cd8b4,20, 0x0cd910,2, 0x0cd920,3, 0x0cd934,1, -0x0cd93c,4, +0x0cd93c,2, 0x0cd950,2, 0x0cda00,11, 0x0cda4c,8, 0x0cda70,2, 0x0cda7c,33, 0x0cdc00,8, -0x0cdc40,14, +0x0cdc40,2, +0x0cdc4c,11, 0x0cdc80,8, -0x0cdcc0,14, +0x0cdcc0,2, +0x0cdccc,11, 0x0cdd00,8, -0x0cdd40,14, +0x0cdd40,2, +0x0cdd4c,11, 0x0cdd80,8, -0x0cddc0,14, +0x0cddc0,2, +0x0cddcc,11, 0x0cde00,8, -0x0cde40,14, +0x0cde40,2, +0x0cde4c,11, 0x0cde80,8, -0x0cdec0,14, -0x0cdf00,11, +0x0cdec0,2, +0x0cdecc,11, +0x0cdf00,9, 0x0cdf30,2, 0x0cdf40,49, 0x0ce018,1, @@ -7676,120 +8007,132 @@ 0x0ce134,1, 0x0ce14c,1, 0x0ce170,2, -0x0ce200,3, +0x0ce200,1, 0x0ce210,2, 0x0ce400,5, 0x0ce418,9, 0x0ce440,5, -0x0ce460,3, +0x0ce460,1, 0x0ce470,2, 0x0ce500,5, 0x0ce518,9, 0x0ce540,5, -0x0ce560,3, +0x0ce560,1, 0x0ce570,2, 0x0ce600,5, 0x0ce618,9, 0x0ce640,5, -0x0ce660,3, +0x0ce660,1, 0x0ce670,2, 0x0ce700,1, 0x0ce800,6, 0x0ce81c,3, -0x0ce82c,12, +0x0ce82c,3, +0x0ce83c,8, 0x0ce860,1, 0x0ce868,1, 0x0ce870,2, -0x0ce880,3, +0x0ce880,1, 0x0ce890,2, -0x0ce8a0,3, +0x0ce8a0,1, 0x0ce8b0,2, -0x0ce8c0,3, +0x0ce8c0,1, 0x0ce8d0,2, -0x0ce8e0,3, +0x0ce8e0,1, 0x0ce8f0,2, 0x0ce900,29, -0x0ce980,29, +0x0ce980,27, +0x0ce9f0,1, 0x0cec00,6, 0x0cec1c,3, -0x0cec2c,12, +0x0cec2c,3, +0x0cec3c,8, 0x0cec60,1, 0x0cec68,1, 0x0cec70,2, -0x0cec80,3, +0x0cec80,1, 0x0cec90,2, -0x0ceca0,3, +0x0ceca0,1, 0x0cecb0,2, -0x0cecc0,3, +0x0cecc0,1, 0x0cecd0,2, -0x0cece0,3, +0x0cece0,1, 0x0cecf0,2, 0x0ced00,29, -0x0ced80,29, +0x0ced80,27, +0x0cedf0,1, 0x0cf000,6, 0x0cf01c,3, -0x0cf02c,12, +0x0cf02c,3, +0x0cf03c,8, 0x0cf060,1, 0x0cf068,1, 0x0cf070,2, -0x0cf080,3, +0x0cf080,1, 0x0cf090,2, -0x0cf0a0,3, +0x0cf0a0,1, 0x0cf0b0,2, -0x0cf0c0,3, +0x0cf0c0,1, 0x0cf0d0,2, -0x0cf0e0,3, +0x0cf0e0,1, 0x0cf0f0,2, 0x0cf100,29, -0x0cf180,29, +0x0cf180,27, +0x0cf1f0,1, 0x0cf400,6, 0x0cf41c,3, -0x0cf42c,12, +0x0cf42c,3, +0x0cf43c,8, 0x0cf460,1, 0x0cf468,1, 0x0cf470,2, -0x0cf480,3, +0x0cf480,1, 0x0cf490,2, -0x0cf4a0,3, +0x0cf4a0,1, 0x0cf4b0,2, -0x0cf4c0,3, +0x0cf4c0,1, 0x0cf4d0,2, -0x0cf4e0,3, +0x0cf4e0,1, 0x0cf4f0,2, 0x0cf500,29, -0x0cf580,29, +0x0cf580,27, +0x0cf5f0,1, 0x0cf800,6, 0x0cf81c,3, -0x0cf82c,12, +0x0cf82c,3, +0x0cf83c,8, 0x0cf860,1, 0x0cf868,1, 0x0cf870,2, -0x0cf880,3, +0x0cf880,1, 0x0cf890,2, -0x0cf8a0,3, +0x0cf8a0,1, 0x0cf8b0,2, -0x0cf8c0,3, +0x0cf8c0,1, 0x0cf8d0,2, -0x0cf8e0,3, +0x0cf8e0,1, 0x0cf8f0,2, 0x0cf900,29, -0x0cf980,29, +0x0cf980,27, +0x0cf9f0,1, 0x0cfc00,6, 0x0cfc1c,3, -0x0cfc2c,12, +0x0cfc2c,3, +0x0cfc3c,8, 0x0cfc60,1, 0x0cfc68,1, 0x0cfc70,2, -0x0cfc80,3, +0x0cfc80,1, 0x0cfc90,2, -0x0cfca0,3, +0x0cfca0,1, 0x0cfcb0,2, -0x0cfcc0,3, +0x0cfcc0,1, 0x0cfcd0,2, -0x0cfce0,3, +0x0cfce0,1, 0x0cfcf0,2, 0x0cfd00,29, -0x0cfd80,29, +0x0cfd80,27, +0x0cfdf0,1, 0x0d0000,2, 0x0d0018,2, 0x0d0034,2, @@ -7797,17 +8140,17 @@ 0x0d0134,2, 0x0d014c,1, 0x0d0170,2, -0x0d0200,3, +0x0d0200,1, 0x0d0210,2, -0x0d0220,3, +0x0d0220,1, 0x0d0230,2, -0x0d0400,3, +0x0d0400,1, 0x0d0410,2, 0x0d0420,3, 0x0d0430,22, 0x0d04ac,1, 0x0d04c0,6, -0x0d0500,3, +0x0d0500,1, 0x0d0510,2, 0x0d0520,3, 0x0d0540,8, @@ -7822,110 +8165,134 @@ 0x0d0800,5, 0x0d0820,5, 0x0d0890,10, -0x0d08e0,3, +0x0d08e0,1, 0x0d08f0,2, 0x0d0900,5, 0x0d0920,5, 0x0d0990,10, -0x0d09e0,3, +0x0d09e0,1, 0x0d09f0,2, -0x0d0a00,3, +0x0d0a00,1, 0x0d0a10,2, -0x0d0a20,3, +0x0d0a20,1, 0x0d0a30,2, 0x0d0a48,3, -0x0d0a80,18, +0x0d0a80,3, +0x0d0a90,1, +0x0d0a98,12, 0x0d0b04,2, 0x0d0b14,3, 0x0d0b24,2, 0x0d0b34,3, -0x0d0b80,11, +0x0d0b80,5, +0x0d0b98,3, 0x0d0bb0,2, -0x0d0bc0,11, +0x0d0bc0,5, +0x0d0bd8,3, 0x0d0bf0,2, -0x0d0c00,23, -0x0d0c80,27, +0x0d0c00,10, +0x0d0c2c,12, +0x0d0c80,26, 0x0d0d00,2, 0x0d0d20,1, -0x0d0e00,23, -0x0d0e80,27, +0x0d0e00,10, +0x0d0e2c,12, +0x0d0e80,26, 0x0d0f00,2, 0x0d0f20,1, 0x0d1000,5, 0x0d1020,5, 0x0d1090,10, -0x0d10e0,3, +0x0d10e0,1, 0x0d10f0,2, 0x0d1100,5, 0x0d1120,5, 0x0d1190,10, -0x0d11e0,3, +0x0d11e0,1, 0x0d11f0,2, -0x0d1200,3, +0x0d1200,1, 0x0d1210,2, -0x0d1220,3, +0x0d1220,1, 0x0d1230,2, 0x0d1248,3, -0x0d1280,18, +0x0d1280,3, +0x0d1290,1, +0x0d1298,12, 0x0d1304,2, 0x0d1314,3, 0x0d1324,2, 0x0d1334,3, -0x0d1380,11, +0x0d1380,5, +0x0d1398,3, 0x0d13b0,2, -0x0d13c0,11, +0x0d13c0,5, +0x0d13d8,3, 0x0d13f0,2, -0x0d1400,23, -0x0d1480,27, +0x0d1400,10, +0x0d142c,12, +0x0d1480,26, 0x0d1500,2, 0x0d1520,1, -0x0d1600,23, -0x0d1680,27, +0x0d1600,10, +0x0d162c,12, +0x0d1680,26, 0x0d1700,2, 0x0d1720,1, 0x0d1800,5, 0x0d1820,5, 0x0d1890,10, -0x0d18e0,3, +0x0d18e0,1, 0x0d18f0,2, 0x0d1900,5, 0x0d1920,5, 0x0d1990,10, -0x0d19e0,3, +0x0d19e0,1, 0x0d19f0,2, -0x0d1a00,3, +0x0d1a00,1, 0x0d1a10,2, -0x0d1a20,3, +0x0d1a20,1, 0x0d1a30,2, 0x0d1a48,3, -0x0d1a80,18, +0x0d1a80,3, +0x0d1a90,1, +0x0d1a98,12, 0x0d1b04,2, 0x0d1b14,3, 0x0d1b24,2, 0x0d1b34,3, -0x0d1b80,11, +0x0d1b80,5, +0x0d1b98,3, 0x0d1bb0,2, -0x0d1bc0,11, +0x0d1bc0,5, +0x0d1bd8,3, 0x0d1bf0,2, -0x0d1c00,23, -0x0d1c80,27, +0x0d1c00,10, +0x0d1c2c,12, +0x0d1c80,26, 0x0d1d00,2, 0x0d1d20,1, -0x0d1e00,23, -0x0d1e80,27, +0x0d1e00,10, +0x0d1e2c,12, +0x0d1e80,26, 0x0d1f00,2, 0x0d1f20,1, -0x0d2000,16, +0x0d2000,7, +0x0d2020,8, 0x0d2044,8, -0x0d2080,16, +0x0d2080,7, +0x0d20a0,8, 0x0d20c4,8, -0x0d2100,16, +0x0d2100,7, +0x0d2120,8, 0x0d2144,8, -0x0d2180,16, +0x0d2180,7, +0x0d21a0,8, 0x0d21c4,8, -0x0d2200,16, +0x0d2200,7, +0x0d2220,8, 0x0d2244,8, -0x0d2280,16, +0x0d2280,7, +0x0d22a0,8, 0x0d22c4,8, 0x0d2400,1, 0x0d2418,1, @@ -7934,16 +8301,16 @@ 0x0d2534,1, 0x0d254c,1, 0x0d2570,2, -0x0d2600,3, +0x0d2600,1, 0x0d2610,2, 0x0d2804,15, 0x0d2844,15, 0x0d2884,15, 0x0d28c4,15, 0x0d2904,15, -0x0d2944,18, +0x0d2944,16, 0x0d2990,2, -0x0d29a0,3, +0x0d29a0,1, 0x0d29b0,2, 0x0d29c0,2, 0x0d2a00,400, @@ -7958,13 +8325,13 @@ 0x0d32c0,2, 0x0d32cc,2, 0x0d32d8,3, -0x0d3300,3, +0x0d3300,1, 0x0d3310,2, -0x0d3320,3, +0x0d3320,1, 0x0d3330,2, -0x0d3340,3, +0x0d3340,1, 0x0d3350,2, -0x0d3360,3, +0x0d3360,1, 0x0d3370,2, 0x0d3380,1, 0x0d3400,16, @@ -7979,13 +8346,13 @@ 0x0d36c0,2, 0x0d36cc,2, 0x0d36d8,3, -0x0d3700,3, +0x0d3700,1, 0x0d3710,2, -0x0d3720,3, +0x0d3720,1, 0x0d3730,2, -0x0d3740,3, +0x0d3740,1, 0x0d3750,2, -0x0d3760,3, +0x0d3760,1, 0x0d3770,2, 0x0d3780,1, 0x0d3800,16, @@ -8000,13 +8367,13 @@ 0x0d3ac0,2, 0x0d3acc,2, 0x0d3ad8,3, -0x0d3b00,3, +0x0d3b00,1, 0x0d3b10,2, -0x0d3b20,3, +0x0d3b20,1, 0x0d3b30,2, -0x0d3b40,3, +0x0d3b40,1, 0x0d3b50,2, -0x0d3b60,3, +0x0d3b60,1, 0x0d3b70,2, 0x0d3b80,1, 0x0d3c00,18, @@ -8036,39 +8403,36 @@ 0x0d3f44,1, 0x0d3f50,4, 0x0d3fa0,3, -0x0d4000,9, +0x0d4000,5, +0x0d4018,3, 0x0d4080,2, 0x0d408c,1, -0x0d4094,1, -0x0d40a0,11, +0x0d40a0,9, 0x0d40d0,2, 0x0d40e0,1, 0x0d40e8,1, 0x0d4100,2, 0x0d410c,1, -0x0d4114,1, -0x0d4120,11, +0x0d4120,9, 0x0d4150,2, 0x0d4160,1, 0x0d4168,1, 0x0d4180,2, 0x0d418c,1, -0x0d4194,1, -0x0d41a0,11, +0x0d41a0,9, 0x0d41d0,2, 0x0d41e0,1, 0x0d41e8,1, 0x0d4200,2, 0x0d420c,1, -0x0d4214,1, -0x0d4220,11, +0x0d4220,9, 0x0d4250,2, 0x0d4260,1, 0x0d4268,1, -0x0d4280,3, +0x0d4284,2, 0x0d42a8,2, 0x0d42b4,1, -0x0d42c0,3, +0x0d42c4,2, 0x0d42e8,2, 0x0d42f4,1, 0x0d4400,3, @@ -8088,47 +8452,44 @@ 0x0d4600,15, 0x0d4640,3, 0x0d4650,3, -0x0d4660,3, +0x0d4660,1, 0x0d4670,2, -0x0d4680,3, +0x0d4680,1, 0x0d4690,2, 0x0d46c0,4, 0x0d46d4,8, 0x0d4700,4, 0x0d4714,8, -0x0d4800,9, +0x0d4800,5, +0x0d4818,3, 0x0d4880,2, 0x0d488c,1, -0x0d4894,1, -0x0d48a0,11, +0x0d48a0,9, 0x0d48d0,2, 0x0d48e0,1, 0x0d48e8,1, 0x0d4900,2, 0x0d490c,1, -0x0d4914,1, -0x0d4920,11, +0x0d4920,9, 0x0d4950,2, 0x0d4960,1, 0x0d4968,1, 0x0d4980,2, 0x0d498c,1, -0x0d4994,1, -0x0d49a0,11, +0x0d49a0,9, 0x0d49d0,2, 0x0d49e0,1, 0x0d49e8,1, 0x0d4a00,2, 0x0d4a0c,1, -0x0d4a14,1, -0x0d4a20,11, +0x0d4a20,9, 0x0d4a50,2, 0x0d4a60,1, 0x0d4a68,1, -0x0d4a80,3, +0x0d4a84,2, 0x0d4aa8,2, 0x0d4ab4,1, -0x0d4ac0,3, +0x0d4ac4,2, 0x0d4ae8,2, 0x0d4af4,1, 0x0d4c00,3, @@ -8148,47 +8509,44 @@ 0x0d4e00,15, 0x0d4e40,3, 0x0d4e50,3, -0x0d4e60,3, +0x0d4e60,1, 0x0d4e70,2, -0x0d4e80,3, +0x0d4e80,1, 0x0d4e90,2, 0x0d4ec0,4, 0x0d4ed4,8, 0x0d4f00,4, 0x0d4f14,8, -0x0d5000,9, +0x0d5000,5, +0x0d5018,3, 0x0d5080,2, 0x0d508c,1, -0x0d5094,1, -0x0d50a0,11, +0x0d50a0,9, 0x0d50d0,2, 0x0d50e0,1, 0x0d50e8,1, 0x0d5100,2, 0x0d510c,1, -0x0d5114,1, -0x0d5120,11, +0x0d5120,9, 0x0d5150,2, 0x0d5160,1, 0x0d5168,1, 0x0d5180,2, 0x0d518c,1, -0x0d5194,1, -0x0d51a0,11, +0x0d51a0,9, 0x0d51d0,2, 0x0d51e0,1, 0x0d51e8,1, 0x0d5200,2, 0x0d520c,1, -0x0d5214,1, -0x0d5220,11, +0x0d5220,9, 0x0d5250,2, 0x0d5260,1, 0x0d5268,1, -0x0d5280,3, +0x0d5284,2, 0x0d52a8,2, 0x0d52b4,1, -0x0d52c0,3, +0x0d52c4,2, 0x0d52e8,2, 0x0d52f4,1, 0x0d5400,3, @@ -8208,9 +8566,9 @@ 0x0d5600,15, 0x0d5640,3, 0x0d5650,3, -0x0d5660,3, +0x0d5660,1, 0x0d5670,2, -0x0d5680,3, +0x0d5680,1, 0x0d5690,2, 0x0d56c0,4, 0x0d56d4,8, @@ -8219,29 +8577,35 @@ 0x0d5800,31, 0x0d5880,8, 0x0d58a4,1, -0x0d58b4,22, +0x0d58b4,20, 0x0d5910,2, 0x0d5920,3, 0x0d5934,1, -0x0d593c,4, +0x0d593c,2, 0x0d5950,2, 0x0d5a00,11, 0x0d5a4c,8, 0x0d5a70,2, 0x0d5a7c,33, 0x0d5c00,8, -0x0d5c40,14, +0x0d5c40,2, +0x0d5c4c,11, 0x0d5c80,8, -0x0d5cc0,14, +0x0d5cc0,2, +0x0d5ccc,11, 0x0d5d00,8, -0x0d5d40,14, +0x0d5d40,2, +0x0d5d4c,11, 0x0d5d80,8, -0x0d5dc0,14, +0x0d5dc0,2, +0x0d5dcc,11, 0x0d5e00,8, -0x0d5e40,14, +0x0d5e40,2, +0x0d5e4c,11, 0x0d5e80,8, -0x0d5ec0,14, -0x0d5f00,11, +0x0d5ec0,2, +0x0d5ecc,11, +0x0d5f00,9, 0x0d5f30,2, 0x0d5f40,49, 0x0d6018,1, @@ -8250,120 +8614,132 @@ 0x0d6134,1, 0x0d614c,1, 0x0d6170,2, -0x0d6200,3, +0x0d6200,1, 0x0d6210,2, 0x0d6400,5, 0x0d6418,9, 0x0d6440,5, -0x0d6460,3, +0x0d6460,1, 0x0d6470,2, 0x0d6500,5, 0x0d6518,9, 0x0d6540,5, -0x0d6560,3, +0x0d6560,1, 0x0d6570,2, 0x0d6600,5, 0x0d6618,9, 0x0d6640,5, -0x0d6660,3, +0x0d6660,1, 0x0d6670,2, 0x0d6700,1, 0x0d6800,6, 0x0d681c,3, -0x0d682c,12, +0x0d682c,3, +0x0d683c,8, 0x0d6860,1, 0x0d6868,1, 0x0d6870,2, -0x0d6880,3, +0x0d6880,1, 0x0d6890,2, -0x0d68a0,3, +0x0d68a0,1, 0x0d68b0,2, -0x0d68c0,3, +0x0d68c0,1, 0x0d68d0,2, -0x0d68e0,3, +0x0d68e0,1, 0x0d68f0,2, 0x0d6900,29, -0x0d6980,29, +0x0d6980,27, +0x0d69f0,1, 0x0d6c00,6, 0x0d6c1c,3, -0x0d6c2c,12, +0x0d6c2c,3, +0x0d6c3c,8, 0x0d6c60,1, 0x0d6c68,1, 0x0d6c70,2, -0x0d6c80,3, +0x0d6c80,1, 0x0d6c90,2, -0x0d6ca0,3, +0x0d6ca0,1, 0x0d6cb0,2, -0x0d6cc0,3, +0x0d6cc0,1, 0x0d6cd0,2, -0x0d6ce0,3, +0x0d6ce0,1, 0x0d6cf0,2, 0x0d6d00,29, -0x0d6d80,29, +0x0d6d80,27, +0x0d6df0,1, 0x0d7000,6, 0x0d701c,3, -0x0d702c,12, +0x0d702c,3, +0x0d703c,8, 0x0d7060,1, 0x0d7068,1, 0x0d7070,2, -0x0d7080,3, +0x0d7080,1, 0x0d7090,2, -0x0d70a0,3, +0x0d70a0,1, 0x0d70b0,2, -0x0d70c0,3, +0x0d70c0,1, 0x0d70d0,2, -0x0d70e0,3, +0x0d70e0,1, 0x0d70f0,2, 0x0d7100,29, -0x0d7180,29, +0x0d7180,27, +0x0d71f0,1, 0x0d7400,6, 0x0d741c,3, -0x0d742c,12, +0x0d742c,3, +0x0d743c,8, 0x0d7460,1, 0x0d7468,1, 0x0d7470,2, -0x0d7480,3, +0x0d7480,1, 0x0d7490,2, -0x0d74a0,3, +0x0d74a0,1, 0x0d74b0,2, -0x0d74c0,3, +0x0d74c0,1, 0x0d74d0,2, -0x0d74e0,3, +0x0d74e0,1, 0x0d74f0,2, 0x0d7500,29, -0x0d7580,29, +0x0d7580,27, +0x0d75f0,1, 0x0d7800,6, 0x0d781c,3, -0x0d782c,12, +0x0d782c,3, +0x0d783c,8, 0x0d7860,1, 0x0d7868,1, 0x0d7870,2, -0x0d7880,3, +0x0d7880,1, 0x0d7890,2, -0x0d78a0,3, +0x0d78a0,1, 0x0d78b0,2, -0x0d78c0,3, +0x0d78c0,1, 0x0d78d0,2, -0x0d78e0,3, +0x0d78e0,1, 0x0d78f0,2, 0x0d7900,29, -0x0d7980,29, +0x0d7980,27, +0x0d79f0,1, 0x0d7c00,6, 0x0d7c1c,3, -0x0d7c2c,12, +0x0d7c2c,3, +0x0d7c3c,8, 0x0d7c60,1, 0x0d7c68,1, 0x0d7c70,2, -0x0d7c80,3, +0x0d7c80,1, 0x0d7c90,2, -0x0d7ca0,3, +0x0d7ca0,1, 0x0d7cb0,2, -0x0d7cc0,3, +0x0d7cc0,1, 0x0d7cd0,2, -0x0d7ce0,3, +0x0d7ce0,1, 0x0d7cf0,2, 0x0d7d00,29, -0x0d7d80,29, +0x0d7d80,27, +0x0d7df0,1, 0x0d8000,2, 0x0d8018,2, 0x0d8034,2, @@ -8371,17 +8747,17 @@ 0x0d8134,2, 0x0d814c,1, 0x0d8170,2, -0x0d8200,3, +0x0d8200,1, 0x0d8210,2, -0x0d8220,3, +0x0d8220,1, 0x0d8230,2, -0x0d8400,3, +0x0d8400,1, 0x0d8410,2, 0x0d8420,3, 0x0d8430,22, 0x0d84ac,1, 0x0d84c0,6, -0x0d8500,3, +0x0d8500,1, 0x0d8510,2, 0x0d8520,3, 0x0d8540,8, @@ -8396,110 +8772,134 @@ 0x0d8800,5, 0x0d8820,5, 0x0d8890,10, -0x0d88e0,3, +0x0d88e0,1, 0x0d88f0,2, 0x0d8900,5, 0x0d8920,5, 0x0d8990,10, -0x0d89e0,3, +0x0d89e0,1, 0x0d89f0,2, -0x0d8a00,3, +0x0d8a00,1, 0x0d8a10,2, -0x0d8a20,3, +0x0d8a20,1, 0x0d8a30,2, 0x0d8a48,3, -0x0d8a80,18, +0x0d8a80,3, +0x0d8a90,1, +0x0d8a98,12, 0x0d8b04,2, 0x0d8b14,3, 0x0d8b24,2, 0x0d8b34,3, -0x0d8b80,11, +0x0d8b80,5, +0x0d8b98,3, 0x0d8bb0,2, -0x0d8bc0,11, +0x0d8bc0,5, +0x0d8bd8,3, 0x0d8bf0,2, -0x0d8c00,23, -0x0d8c80,27, +0x0d8c00,10, +0x0d8c2c,12, +0x0d8c80,26, 0x0d8d00,2, 0x0d8d20,1, -0x0d8e00,23, -0x0d8e80,27, +0x0d8e00,10, +0x0d8e2c,12, +0x0d8e80,26, 0x0d8f00,2, 0x0d8f20,1, 0x0d9000,5, 0x0d9020,5, 0x0d9090,10, -0x0d90e0,3, +0x0d90e0,1, 0x0d90f0,2, 0x0d9100,5, 0x0d9120,5, 0x0d9190,10, -0x0d91e0,3, +0x0d91e0,1, 0x0d91f0,2, -0x0d9200,3, +0x0d9200,1, 0x0d9210,2, -0x0d9220,3, +0x0d9220,1, 0x0d9230,2, 0x0d9248,3, -0x0d9280,18, +0x0d9280,3, +0x0d9290,1, +0x0d9298,12, 0x0d9304,2, 0x0d9314,3, 0x0d9324,2, 0x0d9334,3, -0x0d9380,11, +0x0d9380,5, +0x0d9398,3, 0x0d93b0,2, -0x0d93c0,11, +0x0d93c0,5, +0x0d93d8,3, 0x0d93f0,2, -0x0d9400,23, -0x0d9480,27, +0x0d9400,10, +0x0d942c,12, +0x0d9480,26, 0x0d9500,2, 0x0d9520,1, -0x0d9600,23, -0x0d9680,27, +0x0d9600,10, +0x0d962c,12, +0x0d9680,26, 0x0d9700,2, 0x0d9720,1, 0x0d9800,5, 0x0d9820,5, 0x0d9890,10, -0x0d98e0,3, +0x0d98e0,1, 0x0d98f0,2, 0x0d9900,5, 0x0d9920,5, 0x0d9990,10, -0x0d99e0,3, +0x0d99e0,1, 0x0d99f0,2, -0x0d9a00,3, +0x0d9a00,1, 0x0d9a10,2, -0x0d9a20,3, +0x0d9a20,1, 0x0d9a30,2, 0x0d9a48,3, -0x0d9a80,18, +0x0d9a80,3, +0x0d9a90,1, +0x0d9a98,12, 0x0d9b04,2, 0x0d9b14,3, 0x0d9b24,2, 0x0d9b34,3, -0x0d9b80,11, +0x0d9b80,5, +0x0d9b98,3, 0x0d9bb0,2, -0x0d9bc0,11, +0x0d9bc0,5, +0x0d9bd8,3, 0x0d9bf0,2, -0x0d9c00,23, -0x0d9c80,27, +0x0d9c00,10, +0x0d9c2c,12, +0x0d9c80,26, 0x0d9d00,2, 0x0d9d20,1, -0x0d9e00,23, -0x0d9e80,27, +0x0d9e00,10, +0x0d9e2c,12, +0x0d9e80,26, 0x0d9f00,2, 0x0d9f20,1, -0x0da000,16, +0x0da000,7, +0x0da020,8, 0x0da044,8, -0x0da080,16, +0x0da080,7, +0x0da0a0,8, 0x0da0c4,8, -0x0da100,16, +0x0da100,7, +0x0da120,8, 0x0da144,8, -0x0da180,16, +0x0da180,7, +0x0da1a0,8, 0x0da1c4,8, -0x0da200,16, +0x0da200,7, +0x0da220,8, 0x0da244,8, -0x0da280,16, +0x0da280,7, +0x0da2a0,8, 0x0da2c4,8, 0x0da400,1, 0x0da418,1, @@ -8508,16 +8908,16 @@ 0x0da534,1, 0x0da54c,1, 0x0da570,2, -0x0da600,3, +0x0da600,1, 0x0da610,2, 0x0da804,15, 0x0da844,15, 0x0da884,15, 0x0da8c4,15, 0x0da904,15, -0x0da944,18, +0x0da944,16, 0x0da990,2, -0x0da9a0,3, +0x0da9a0,1, 0x0da9b0,2, 0x0da9c0,2, 0x0daa00,400, @@ -8532,13 +8932,13 @@ 0x0db2c0,2, 0x0db2cc,2, 0x0db2d8,3, -0x0db300,3, +0x0db300,1, 0x0db310,2, -0x0db320,3, +0x0db320,1, 0x0db330,2, -0x0db340,3, +0x0db340,1, 0x0db350,2, -0x0db360,3, +0x0db360,1, 0x0db370,2, 0x0db380,1, 0x0db400,16, @@ -8553,13 +8953,13 @@ 0x0db6c0,2, 0x0db6cc,2, 0x0db6d8,3, -0x0db700,3, +0x0db700,1, 0x0db710,2, -0x0db720,3, +0x0db720,1, 0x0db730,2, -0x0db740,3, +0x0db740,1, 0x0db750,2, -0x0db760,3, +0x0db760,1, 0x0db770,2, 0x0db780,1, 0x0db800,16, @@ -8574,13 +8974,13 @@ 0x0dbac0,2, 0x0dbacc,2, 0x0dbad8,3, -0x0dbb00,3, +0x0dbb00,1, 0x0dbb10,2, -0x0dbb20,3, +0x0dbb20,1, 0x0dbb30,2, -0x0dbb40,3, +0x0dbb40,1, 0x0dbb50,2, -0x0dbb60,3, +0x0dbb60,1, 0x0dbb70,2, 0x0dbb80,1, 0x0dbc00,18, @@ -8610,39 +9010,36 @@ 0x0dbf44,1, 0x0dbf50,4, 0x0dbfa0,3, -0x0dc000,9, +0x0dc000,5, +0x0dc018,3, 0x0dc080,2, 0x0dc08c,1, -0x0dc094,1, -0x0dc0a0,11, +0x0dc0a0,9, 0x0dc0d0,2, 0x0dc0e0,1, 0x0dc0e8,1, 0x0dc100,2, 0x0dc10c,1, -0x0dc114,1, -0x0dc120,11, +0x0dc120,9, 0x0dc150,2, 0x0dc160,1, 0x0dc168,1, 0x0dc180,2, 0x0dc18c,1, -0x0dc194,1, -0x0dc1a0,11, +0x0dc1a0,9, 0x0dc1d0,2, 0x0dc1e0,1, 0x0dc1e8,1, 0x0dc200,2, 0x0dc20c,1, -0x0dc214,1, -0x0dc220,11, +0x0dc220,9, 0x0dc250,2, 0x0dc260,1, 0x0dc268,1, -0x0dc280,3, +0x0dc284,2, 0x0dc2a8,2, 0x0dc2b4,1, -0x0dc2c0,3, +0x0dc2c4,2, 0x0dc2e8,2, 0x0dc2f4,1, 0x0dc400,3, @@ -8662,47 +9059,44 @@ 0x0dc600,15, 0x0dc640,3, 0x0dc650,3, -0x0dc660,3, +0x0dc660,1, 0x0dc670,2, -0x0dc680,3, +0x0dc680,1, 0x0dc690,2, 0x0dc6c0,4, 0x0dc6d4,8, 0x0dc700,4, 0x0dc714,8, -0x0dc800,9, +0x0dc800,5, +0x0dc818,3, 0x0dc880,2, 0x0dc88c,1, -0x0dc894,1, -0x0dc8a0,11, +0x0dc8a0,9, 0x0dc8d0,2, 0x0dc8e0,1, 0x0dc8e8,1, 0x0dc900,2, 0x0dc90c,1, -0x0dc914,1, -0x0dc920,11, +0x0dc920,9, 0x0dc950,2, 0x0dc960,1, 0x0dc968,1, 0x0dc980,2, 0x0dc98c,1, -0x0dc994,1, -0x0dc9a0,11, +0x0dc9a0,9, 0x0dc9d0,2, 0x0dc9e0,1, 0x0dc9e8,1, 0x0dca00,2, 0x0dca0c,1, -0x0dca14,1, -0x0dca20,11, +0x0dca20,9, 0x0dca50,2, 0x0dca60,1, 0x0dca68,1, -0x0dca80,3, +0x0dca84,2, 0x0dcaa8,2, 0x0dcab4,1, -0x0dcac0,3, +0x0dcac4,2, 0x0dcae8,2, 0x0dcaf4,1, 0x0dcc00,3, @@ -8722,47 +9116,44 @@ 0x0dce00,15, 0x0dce40,3, 0x0dce50,3, -0x0dce60,3, +0x0dce60,1, 0x0dce70,2, -0x0dce80,3, +0x0dce80,1, 0x0dce90,2, 0x0dcec0,4, 0x0dced4,8, 0x0dcf00,4, 0x0dcf14,8, -0x0dd000,9, +0x0dd000,5, +0x0dd018,3, 0x0dd080,2, 0x0dd08c,1, -0x0dd094,1, -0x0dd0a0,11, +0x0dd0a0,9, 0x0dd0d0,2, 0x0dd0e0,1, 0x0dd0e8,1, 0x0dd100,2, 0x0dd10c,1, -0x0dd114,1, -0x0dd120,11, +0x0dd120,9, 0x0dd150,2, 0x0dd160,1, 0x0dd168,1, 0x0dd180,2, 0x0dd18c,1, -0x0dd194,1, -0x0dd1a0,11, +0x0dd1a0,9, 0x0dd1d0,2, 0x0dd1e0,1, 0x0dd1e8,1, 0x0dd200,2, 0x0dd20c,1, -0x0dd214,1, -0x0dd220,11, +0x0dd220,9, 0x0dd250,2, 0x0dd260,1, 0x0dd268,1, -0x0dd280,3, +0x0dd284,2, 0x0dd2a8,2, 0x0dd2b4,1, -0x0dd2c0,3, +0x0dd2c4,2, 0x0dd2e8,2, 0x0dd2f4,1, 0x0dd400,3, @@ -8782,9 +9173,9 @@ 0x0dd600,15, 0x0dd640,3, 0x0dd650,3, -0x0dd660,3, +0x0dd660,1, 0x0dd670,2, -0x0dd680,3, +0x0dd680,1, 0x0dd690,2, 0x0dd6c0,4, 0x0dd6d4,8, @@ -8793,29 +9184,35 @@ 0x0dd800,31, 0x0dd880,8, 0x0dd8a4,1, -0x0dd8b4,22, +0x0dd8b4,20, 0x0dd910,2, 0x0dd920,3, 0x0dd934,1, -0x0dd93c,4, +0x0dd93c,2, 0x0dd950,2, 0x0dda00,11, 0x0dda4c,8, 0x0dda70,2, 0x0dda7c,33, 0x0ddc00,8, -0x0ddc40,14, +0x0ddc40,2, +0x0ddc4c,11, 0x0ddc80,8, -0x0ddcc0,14, +0x0ddcc0,2, +0x0ddccc,11, 0x0ddd00,8, -0x0ddd40,14, +0x0ddd40,2, +0x0ddd4c,11, 0x0ddd80,8, -0x0dddc0,14, +0x0dddc0,2, +0x0dddcc,11, 0x0dde00,8, -0x0dde40,14, +0x0dde40,2, +0x0dde4c,11, 0x0dde80,8, -0x0ddec0,14, -0x0ddf00,11, +0x0ddec0,2, +0x0ddecc,11, +0x0ddf00,9, 0x0ddf30,2, 0x0ddf40,49, 0x0de018,1, @@ -8824,128 +9221,146 @@ 0x0de134,1, 0x0de14c,1, 0x0de170,2, -0x0de200,3, +0x0de200,1, 0x0de210,2, 0x0de400,5, 0x0de418,9, 0x0de440,5, -0x0de460,3, +0x0de460,1, 0x0de470,2, 0x0de500,5, 0x0de518,9, 0x0de540,5, -0x0de560,3, +0x0de560,1, 0x0de570,2, 0x0de600,5, 0x0de618,9, 0x0de640,5, -0x0de660,3, +0x0de660,1, 0x0de670,2, 0x0de700,1, 0x0de800,6, 0x0de81c,3, -0x0de82c,12, +0x0de82c,3, +0x0de83c,8, 0x0de860,1, 0x0de868,1, 0x0de870,2, -0x0de880,3, +0x0de880,1, 0x0de890,2, -0x0de8a0,3, +0x0de8a0,1, 0x0de8b0,2, -0x0de8c0,3, +0x0de8c0,1, 0x0de8d0,2, -0x0de8e0,3, +0x0de8e0,1, 0x0de8f0,2, 0x0de900,29, -0x0de980,29, +0x0de980,27, +0x0de9f0,1, 0x0dec00,6, 0x0dec1c,3, -0x0dec2c,12, +0x0dec2c,3, +0x0dec3c,8, 0x0dec60,1, 0x0dec68,1, 0x0dec70,2, -0x0dec80,3, +0x0dec80,1, 0x0dec90,2, -0x0deca0,3, +0x0deca0,1, 0x0decb0,2, -0x0decc0,3, +0x0decc0,1, 0x0decd0,2, -0x0dece0,3, +0x0dece0,1, 0x0decf0,2, 0x0ded00,29, -0x0ded80,29, +0x0ded80,27, +0x0dedf0,1, 0x0df000,6, 0x0df01c,3, -0x0df02c,12, +0x0df02c,3, +0x0df03c,8, 0x0df060,1, 0x0df068,1, 0x0df070,2, -0x0df080,3, +0x0df080,1, 0x0df090,2, -0x0df0a0,3, +0x0df0a0,1, 0x0df0b0,2, -0x0df0c0,3, +0x0df0c0,1, 0x0df0d0,2, -0x0df0e0,3, +0x0df0e0,1, 0x0df0f0,2, 0x0df100,29, -0x0df180,29, +0x0df180,27, +0x0df1f0,1, 0x0df400,6, 0x0df41c,3, -0x0df42c,12, +0x0df42c,3, +0x0df43c,8, 0x0df460,1, 0x0df468,1, 0x0df470,2, -0x0df480,3, +0x0df480,1, 0x0df490,2, -0x0df4a0,3, +0x0df4a0,1, 0x0df4b0,2, -0x0df4c0,3, +0x0df4c0,1, 0x0df4d0,2, -0x0df4e0,3, +0x0df4e0,1, 0x0df4f0,2, 0x0df500,29, -0x0df580,29, +0x0df580,27, +0x0df5f0,1, 0x0df800,6, 0x0df81c,3, -0x0df82c,12, +0x0df82c,3, +0x0df83c,8, 0x0df860,1, 0x0df868,1, 0x0df870,2, -0x0df880,3, +0x0df880,1, 0x0df890,2, -0x0df8a0,3, +0x0df8a0,1, 0x0df8b0,2, -0x0df8c0,3, +0x0df8c0,1, 0x0df8d0,2, -0x0df8e0,3, +0x0df8e0,1, 0x0df8f0,2, 0x0df900,29, -0x0df980,29, +0x0df980,27, +0x0df9f0,1, 0x0dfc00,6, 0x0dfc1c,3, -0x0dfc2c,12, +0x0dfc2c,3, +0x0dfc3c,8, 0x0dfc60,1, 0x0dfc68,1, 0x0dfc70,2, -0x0dfc80,3, +0x0dfc80,1, 0x0dfc90,2, -0x0dfca0,3, +0x0dfca0,1, 0x0dfcb0,2, -0x0dfcc0,3, +0x0dfcc0,1, 0x0dfcd0,2, -0x0dfce0,3, +0x0dfce0,1, 0x0dfcf0,2, 0x0dfd00,29, -0x0dfd80,29, -0x0e0000,106, -0x0e01e0,3, +0x0dfd80,27, +0x0dfdf0,1, +0x0e0000,19, +0x0e0050,39, +0x0e00f0,46, +0x0e01e0,1, 0x0e01f0,2, -0x0e0200,106, -0x0e03e0,3, +0x0e0200,19, +0x0e0250,39, +0x0e02f0,46, +0x0e03e0,1, 0x0e03f0,2, -0x0e0400,106, -0x0e05e0,3, +0x0e0400,19, +0x0e0450,39, +0x0e04f0,46, +0x0e05e0,1, 0x0e05f0,2, 0x0e0600,6, 0x0e0620,6, @@ -8957,14 +9372,20 @@ 0x0e070c,1, 0x0e0744,1, 0x0e074c,1, -0x0e07fc,107, -0x0e09e0,3, +0x0e07fc,20, +0x0e0850,39, +0x0e08f0,46, +0x0e09e0,1, 0x0e09f0,2, -0x0e0a00,106, -0x0e0be0,3, +0x0e0a00,19, +0x0e0a50,39, +0x0e0af0,46, +0x0e0be0,1, 0x0e0bf0,2, -0x0e0c00,106, -0x0e0de0,3, +0x0e0c00,19, +0x0e0c50,39, +0x0e0cf0,46, +0x0e0de0,1, 0x0e0df0,2, 0x0e0e00,6, 0x0e0e20,6, @@ -8976,14 +9397,20 @@ 0x0e0f0c,1, 0x0e0f44,1, 0x0e0f4c,1, -0x0e0ffc,107, -0x0e11e0,3, +0x0e0ffc,20, +0x0e1050,39, +0x0e10f0,46, +0x0e11e0,1, 0x0e11f0,2, -0x0e1200,106, -0x0e13e0,3, +0x0e1200,19, +0x0e1250,39, +0x0e12f0,46, +0x0e13e0,1, 0x0e13f0,2, -0x0e1400,106, -0x0e15e0,3, +0x0e1400,19, +0x0e1450,39, +0x0e14f0,46, +0x0e15e0,1, 0x0e15f0,2, 0x0e1600,6, 0x0e1620,6, @@ -8995,14 +9422,20 @@ 0x0e170c,1, 0x0e1744,1, 0x0e174c,1, -0x0e17fc,107, -0x0e19e0,3, +0x0e17fc,20, +0x0e1850,39, +0x0e18f0,46, +0x0e19e0,1, 0x0e19f0,2, -0x0e1a00,106, -0x0e1be0,3, +0x0e1a00,19, +0x0e1a50,39, +0x0e1af0,46, +0x0e1be0,1, 0x0e1bf0,2, -0x0e1c00,106, -0x0e1de0,3, +0x0e1c00,19, +0x0e1c50,39, +0x0e1cf0,46, +0x0e1de0,1, 0x0e1df0,2, 0x0e1e00,6, 0x0e1e20,6, @@ -9014,14 +9447,20 @@ 0x0e1f0c,1, 0x0e1f44,1, 0x0e1f4c,1, -0x0e1ffc,107, -0x0e21e0,3, +0x0e1ffc,20, +0x0e2050,39, +0x0e20f0,46, +0x0e21e0,1, 0x0e21f0,2, -0x0e2200,106, -0x0e23e0,3, +0x0e2200,19, +0x0e2250,39, +0x0e22f0,46, +0x0e23e0,1, 0x0e23f0,2, -0x0e2400,106, -0x0e25e0,3, +0x0e2400,19, +0x0e2450,39, +0x0e24f0,46, +0x0e25e0,1, 0x0e25f0,2, 0x0e2600,6, 0x0e2620,6, @@ -9033,14 +9472,20 @@ 0x0e270c,1, 0x0e2744,1, 0x0e274c,1, -0x0e27fc,107, -0x0e29e0,3, +0x0e27fc,20, +0x0e2850,39, +0x0e28f0,46, +0x0e29e0,1, 0x0e29f0,2, -0x0e2a00,106, -0x0e2be0,3, +0x0e2a00,19, +0x0e2a50,39, +0x0e2af0,46, +0x0e2be0,1, 0x0e2bf0,2, -0x0e2c00,106, -0x0e2de0,3, +0x0e2c00,19, +0x0e2c50,39, +0x0e2cf0,46, +0x0e2de0,1, 0x0e2df0,2, 0x0e2e00,6, 0x0e2e20,6, @@ -9052,23 +9497,31 @@ 0x0e2f0c,1, 0x0e2f44,1, 0x0e2f4c,1, -0x0e2ffc,107, -0x0e31e0,3, +0x0e2ffc,20, +0x0e3050,39, +0x0e30f0,46, +0x0e31e0,1, 0x0e31f0,2, -0x0e3800,3, +0x0e3800,1, 0x0e3810,2, 0x0e3820,3, 0x0e3840,2, 0x0e384c,2, 0x0e3858,5, -0x0e4000,106, -0x0e41e0,3, +0x0e4000,19, +0x0e4050,39, +0x0e40f0,46, +0x0e41e0,1, 0x0e41f0,2, -0x0e4200,106, -0x0e43e0,3, +0x0e4200,19, +0x0e4250,39, +0x0e42f0,46, +0x0e43e0,1, 0x0e43f0,2, -0x0e4400,106, -0x0e45e0,3, +0x0e4400,19, +0x0e4450,39, +0x0e44f0,46, +0x0e45e0,1, 0x0e45f0,2, 0x0e4600,6, 0x0e4620,6, @@ -9080,14 +9533,20 @@ 0x0e470c,1, 0x0e4744,1, 0x0e474c,1, -0x0e47fc,107, -0x0e49e0,3, +0x0e47fc,20, +0x0e4850,39, +0x0e48f0,46, +0x0e49e0,1, 0x0e49f0,2, -0x0e4a00,106, -0x0e4be0,3, +0x0e4a00,19, +0x0e4a50,39, +0x0e4af0,46, +0x0e4be0,1, 0x0e4bf0,2, -0x0e4c00,106, -0x0e4de0,3, +0x0e4c00,19, +0x0e4c50,39, +0x0e4cf0,46, +0x0e4de0,1, 0x0e4df0,2, 0x0e4e00,6, 0x0e4e20,6, @@ -9099,14 +9558,20 @@ 0x0e4f0c,1, 0x0e4f44,1, 0x0e4f4c,1, -0x0e4ffc,107, -0x0e51e0,3, +0x0e4ffc,20, +0x0e5050,39, +0x0e50f0,46, +0x0e51e0,1, 0x0e51f0,2, -0x0e5200,106, -0x0e53e0,3, +0x0e5200,19, +0x0e5250,39, +0x0e52f0,46, +0x0e53e0,1, 0x0e53f0,2, -0x0e5400,106, -0x0e55e0,3, +0x0e5400,19, +0x0e5450,39, +0x0e54f0,46, +0x0e55e0,1, 0x0e55f0,2, 0x0e5600,6, 0x0e5620,6, @@ -9118,14 +9583,20 @@ 0x0e570c,1, 0x0e5744,1, 0x0e574c,1, -0x0e57fc,107, -0x0e59e0,3, +0x0e57fc,20, +0x0e5850,39, +0x0e58f0,46, +0x0e59e0,1, 0x0e59f0,2, -0x0e5a00,106, -0x0e5be0,3, +0x0e5a00,19, +0x0e5a50,39, +0x0e5af0,46, +0x0e5be0,1, 0x0e5bf0,2, -0x0e5c00,106, -0x0e5de0,3, +0x0e5c00,19, +0x0e5c50,39, +0x0e5cf0,46, +0x0e5de0,1, 0x0e5df0,2, 0x0e5e00,6, 0x0e5e20,6, @@ -9137,14 +9608,20 @@ 0x0e5f0c,1, 0x0e5f44,1, 0x0e5f4c,1, -0x0e5ffc,107, -0x0e61e0,3, +0x0e5ffc,20, +0x0e6050,39, +0x0e60f0,46, +0x0e61e0,1, 0x0e61f0,2, -0x0e6200,106, -0x0e63e0,3, +0x0e6200,19, +0x0e6250,39, +0x0e62f0,46, +0x0e63e0,1, 0x0e63f0,2, -0x0e6400,106, -0x0e65e0,3, +0x0e6400,19, +0x0e6450,39, +0x0e64f0,46, +0x0e65e0,1, 0x0e65f0,2, 0x0e6600,6, 0x0e6620,6, @@ -9156,14 +9633,20 @@ 0x0e670c,1, 0x0e6744,1, 0x0e674c,1, -0x0e67fc,107, -0x0e69e0,3, +0x0e67fc,20, +0x0e6850,39, +0x0e68f0,46, +0x0e69e0,1, 0x0e69f0,2, -0x0e6a00,106, -0x0e6be0,3, +0x0e6a00,19, +0x0e6a50,39, +0x0e6af0,46, +0x0e6be0,1, 0x0e6bf0,2, -0x0e6c00,106, -0x0e6de0,3, +0x0e6c00,19, +0x0e6c50,39, +0x0e6cf0,46, +0x0e6de0,1, 0x0e6df0,2, 0x0e6e00,6, 0x0e6e20,6, @@ -9175,10 +9658,12 @@ 0x0e6f0c,1, 0x0e6f44,1, 0x0e6f4c,1, -0x0e6ffc,107, -0x0e71e0,3, +0x0e6ffc,20, +0x0e7050,39, +0x0e70f0,46, +0x0e71e0,1, 0x0e71f0,2, -0x0e7800,3, +0x0e7800,1, 0x0e7810,2, 0x0e7820,3, 0x0e7840,2, @@ -9187,14 +9672,14 @@ 0x0ec000,26, 0x0ec070,7, 0x0ec090,15, -0x0ec0d0,7, +0x0ec0d0,5, 0x0ec0f0,2, 0x0ec100,1, 0x0ec200,76, 0x0ec400,26, 0x0ec470,7, 0x0ec490,15, -0x0ec4d0,7, +0x0ec4d0,5, 0x0ec4f0,2, 0x0ec500,1, 0x0ec600,76, @@ -9220,7 +9705,8 @@ 0x0ed10c,1, 0x0ed120,2, 0x0ed130,5, -0x0ed184,15, +0x0ed184,13, +0x0ed1bc,1, 0x0ed204,1, 0x0ed210,5, 0x0ed244,6, @@ -9236,27 +9722,29 @@ 0x0ed548,2, 0x0ed554,4, 0x0ed574,2, -0x0ed580,11, +0x0ed580,9, 0x0ed5b0,2, 0x0ed5cc,8, 0x0ed704,1, 0x0ed70c,12, -0x0ed760,3, +0x0ed760,1, 0x0ed770,2, -0x0ed780,3, +0x0ed780,1, 0x0ed790,2, 0x0ed7a0,2, 0x0ed7ac,5, 0x0ed800,3, 0x0ed810,24, -0x0ed880,11, +0x0ed880,9, 0x0ed8b0,2, 0x0ed8c0,2, 0x0ed8d0,1, 0x0ed8f8,2, 0x0eda00,3, -0x0eda10,13, -0x0eda60,3, +0x0eda10,4, +0x0eda24,3, +0x0eda34,4, +0x0eda60,1, 0x0eda70,2, 0x0eda84,3, 0x0edb00,3, @@ -9267,7 +9755,7 @@ 0x0edd34,1, 0x0edd4c,1, 0x0edd70,2, -0x0ede00,3, +0x0ede00,1, 0x0ede10,2, 0x0ee010,7, 0x0ee030,4, @@ -9277,14 +9765,16 @@ 0x0ee160,16, 0x0ee200,16, 0x0ee300,2, -0x0ee4fc,4, +0x0ee4fc,2, 0x0ee510,2, -0x0f0000,15, +0x0f0000,3, +0x0f0014,10, 0x0f0040,3, 0x0f0058,5, 0x0f0070,7, 0x0f0090,2, -0x0f009c,6, +0x0f009c,2, +0x0f00a8,3, 0x0f00c0,2, 0x0f00dc,9, 0x0f0128,2, @@ -9296,17 +9786,19 @@ 0x0f0200,38, 0x0f0404,8, 0x0f0440,4, -0x0f0480,10, -0x0f04e0,3, +0x0f0480,6, +0x0f04a0,2, +0x0f04e0,1, 0x0f04f0,2, -0x0f0500,10, -0x0f0560,3, +0x0f0500,6, +0x0f0520,2, +0x0f0560,1, 0x0f0570,2, -0x0f0580,3, +0x0f0580,1, 0x0f0590,2, -0x0f05a0,3, +0x0f05a0,1, 0x0f05b0,2, -0x0f05c0,3, +0x0f05c0,1, 0x0f05d0,2, 0x0f05e0,1, 0x0f0600,64, @@ -9326,9 +9818,9 @@ 0x0f8134,1, 0x0f814c,1, 0x0f8170,2, -0x0f8200,3, +0x0f8200,1, 0x0f8210,2, -0x0f8400,98, +0x0f8400,96, 0x0f85a4,1, 0x0f85ac,1, 0x0f85b4,1, @@ -9356,11 +9848,12 @@ 0x0f86c4,1, 0x0f86d4,25, 0x0f8740,14, -0x0f8780,11, +0x0f8780,7, +0x0f87a0,1, 0x0f87b0,3, -0x0f87c0,3, +0x0f87c0,1, 0x0f87d0,2, -0x0f87e0,2, +0x0f87e4,1, 0x0f8800,1, 0x0f8818,1, 0x0f8834,1, @@ -9368,9 +9861,9 @@ 0x0f8934,1, 0x0f894c,1, 0x0f8970,2, -0x0f8a00,3, +0x0f8a00,1, 0x0f8a10,2, -0x0f8c00,98, +0x0f8c00,96, 0x0f8da4,1, 0x0f8dac,1, 0x0f8db4,1, @@ -9398,49 +9891,50 @@ 0x0f8ec4,1, 0x0f8ed4,25, 0x0f8f40,14, -0x0f8f80,11, +0x0f8f80,7, +0x0f8fa0,1, 0x0f8fb0,3, -0x0f8fc0,3, +0x0f8fc0,1, 0x0f8fd0,2, -0x0f8fe0,2, +0x0f8fe4,1, 0x0f9000,3, -0x0f9020,3, +0x0f9020,1, 0x0f9030,2, -0x0f9040,3, +0x0f9040,1, 0x0f9050,2, -0x0f9060,3, +0x0f9060,1, 0x0f9070,2, -0x0f9080,3, +0x0f9080,1, 0x0f9090,2, -0x0f90a0,3, +0x0f90a0,1, 0x0f90b0,2, -0x0f90c0,3, +0x0f90c0,1, 0x0f90d0,2, -0x0f90e0,3, +0x0f90e0,1, 0x0f90f0,2, -0x0f9100,3, +0x0f9100,1, 0x0f9110,2, -0x0f9120,3, +0x0f9120,1, 0x0f9130,2, -0x0f9140,3, +0x0f9140,1, 0x0f9150,2, -0x0f9160,3, +0x0f9160,1, 0x0f9170,2, -0x0f9180,3, +0x0f9180,1, 0x0f9190,2, -0x0f91a0,3, +0x0f91a0,1, 0x0f91b0,2, -0x0f91c0,3, +0x0f91c0,1, 0x0f91d0,2, -0x0f91e0,3, +0x0f91e0,1, 0x0f91f0,2, -0x0f9200,3, +0x0f9200,1, 0x0f9210,2, -0x0f9220,3, +0x0f9220,1, 0x0f9230,2, -0x0f9240,3, +0x0f9240,1, 0x0f9250,2, -0x0f9260,3, +0x0f9260,1, 0x0f9270,2, 0x0f9400,18, 0x0f9480,18, @@ -9455,9 +9949,10 @@ 0x0fc0c4,3, 0x0fc0e0,4, 0x0fc0f4,1, -0x0fc0fc,11, +0x0fc0fc,3, +0x0fc10c,7, 0x0fc130,3, -0x0fc140,3, +0x0fc140,1, 0x0fc150,2, 0x0fc200,4, 0x0fc214,1, @@ -9469,9 +9964,10 @@ 0x0fc2c4,3, 0x0fc2e0,4, 0x0fc2f4,1, -0x0fc2fc,11, +0x0fc2fc,3, +0x0fc30c,7, 0x0fc330,3, -0x0fc340,3, +0x0fc340,1, 0x0fc350,2, 0x0fc400,4, 0x0fc414,1, @@ -9483,9 +9979,10 @@ 0x0fc4c4,3, 0x0fc4e0,4, 0x0fc4f4,1, -0x0fc4fc,11, +0x0fc4fc,3, +0x0fc50c,7, 0x0fc530,3, -0x0fc540,3, +0x0fc540,1, 0x0fc550,2, 0x0fc600,4, 0x0fc614,1, @@ -9497,9 +9994,10 @@ 0x0fc6c4,3, 0x0fc6e0,4, 0x0fc6f4,1, -0x0fc6fc,11, +0x0fc6fc,3, +0x0fc70c,7, 0x0fc730,3, -0x0fc740,3, +0x0fc740,1, 0x0fc750,2, 0x0fc800,4, 0x0fc814,1, @@ -9511,9 +10009,10 @@ 0x0fc8c4,3, 0x0fc8e0,4, 0x0fc8f4,1, -0x0fc8fc,11, +0x0fc8fc,3, +0x0fc90c,7, 0x0fc930,3, -0x0fc940,3, +0x0fc940,1, 0x0fc950,2, 0x0fca00,4, 0x0fca14,1, @@ -9525,20 +10024,21 @@ 0x0fcac4,3, 0x0fcae0,4, 0x0fcaf4,1, -0x0fcafc,11, +0x0fcafc,3, +0x0fcb0c,7, 0x0fcb30,3, -0x0fcb40,3, +0x0fcb40,1, 0x0fcb50,2, 0x0fcc00,2, 0x0fcc24,1, 0x0fcc34,7, -0x0fcc80,3, +0x0fcc80,1, 0x0fcc90,2, 0x0fce00,14, 0x0fd500,2, -0x0fd520,3, +0x0fd520,1, 0x0fd530,2, -0x0fd720,3, +0x0fd720,1, 0x0fd730,2, 0x0fd7a0,3, 0x0fd7f0,1, @@ -9580,11 +10080,11 @@ 0x0fdaf4,2, 0x0fdb00,1, 0x0fdb80,2, -0x0fdba0,3, +0x0fdba0,1, 0x0fdbb0,2, -0x0fdbc0,3, +0x0fdbc0,1, 0x0fdbd0,2, -0x0fdbe0,3, +0x0fdbe0,1, 0x0fdbf0,2, 0x0fdc00,4, 0x0fdc18,4, @@ -9593,13 +10093,13 @@ 0x0fdd34,4, 0x0fdd4c,1, 0x0fdd70,2, -0x0fde00,3, +0x0fde00,1, 0x0fde10,2, -0x0fde20,3, +0x0fde20,1, 0x0fde30,2, -0x0fde40,3, +0x0fde40,1, 0x0fde50,2, -0x0fde60,3, +0x0fde60,1, 0x0fde70,2, 0x0fe000,4, 0x0fe014,1, @@ -9611,9 +10111,10 @@ 0x0fe0c4,3, 0x0fe0e0,4, 0x0fe0f4,1, -0x0fe0fc,11, +0x0fe0fc,3, +0x0fe10c,7, 0x0fe130,3, -0x0fe140,3, +0x0fe140,1, 0x0fe150,2, 0x0fe200,4, 0x0fe214,1, @@ -9625,9 +10126,10 @@ 0x0fe2c4,3, 0x0fe2e0,4, 0x0fe2f4,1, -0x0fe2fc,11, +0x0fe2fc,3, +0x0fe30c,7, 0x0fe330,3, -0x0fe340,3, +0x0fe340,1, 0x0fe350,2, 0x0fe400,4, 0x0fe414,1, @@ -9639,9 +10141,10 @@ 0x0fe4c4,3, 0x0fe4e0,4, 0x0fe4f4,1, -0x0fe4fc,11, +0x0fe4fc,3, +0x0fe50c,7, 0x0fe530,3, -0x0fe540,3, +0x0fe540,1, 0x0fe550,2, 0x0fe600,4, 0x0fe614,1, @@ -9653,9 +10156,10 @@ 0x0fe6c4,3, 0x0fe6e0,4, 0x0fe6f4,1, -0x0fe6fc,11, +0x0fe6fc,3, +0x0fe70c,7, 0x0fe730,3, -0x0fe740,3, +0x0fe740,1, 0x0fe750,2, 0x0fe800,4, 0x0fe814,1, @@ -9667,9 +10171,10 @@ 0x0fe8c4,3, 0x0fe8e0,4, 0x0fe8f4,1, -0x0fe8fc,11, +0x0fe8fc,3, +0x0fe90c,7, 0x0fe930,3, -0x0fe940,3, +0x0fe940,1, 0x0fe950,2, 0x0fea00,4, 0x0fea14,1, @@ -9681,20 +10186,21 @@ 0x0feac4,3, 0x0feae0,4, 0x0feaf4,1, -0x0feafc,11, +0x0feafc,3, +0x0feb0c,7, 0x0feb30,3, -0x0feb40,3, +0x0feb40,1, 0x0feb50,2, 0x0fec00,2, 0x0fec24,1, 0x0fec34,7, -0x0fec80,3, +0x0fec80,1, 0x0fec90,2, 0x0fee00,14, 0x0ff500,2, -0x0ff520,3, +0x0ff520,1, 0x0ff530,2, -0x0ff720,3, +0x0ff720,1, 0x0ff730,2, 0x0ff7a0,3, 0x0ff7f0,1, @@ -9736,11 +10242,11 @@ 0x0ffaf4,2, 0x0ffb00,1, 0x0ffb80,2, -0x0ffba0,3, +0x0ffba0,1, 0x0ffbb0,2, -0x0ffbc0,3, +0x0ffbc0,1, 0x0ffbd0,2, -0x0ffbe0,3, +0x0ffbe0,1, 0x0ffbf0,2, 0x0ffc00,4, 0x0ffc18,4, @@ -9749,11 +10255,11 @@ 0x0ffd34,4, 0x0ffd4c,1, 0x0ffd70,2, -0x0ffe00,3, +0x0ffe00,1, 0x0ffe10,2, -0x0ffe20,3, +0x0ffe20,1, 0x0ffe30,2, -0x0ffe40,3, +0x0ffe40,1, 0x0ffe50,2, -0x0ffe60,3, +0x0ffe60,1, 0x0ffe70,2, diff --git a/small_utils/Makefile.am b/small_utils/Makefile.am index fd0ddfb..c38b463 100644 --- a/small_utils/Makefile.am +++ b/small_utils/Makefile.am @@ -29,9 +29,13 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. #-- -INCLUDES= -I$(top_srcdir)/include/mtcr_ul -LDADD=../mtcr_ul/libmtcr_ul.a -ldl +USER_DIR = .. +COMMON_DIR = $(USER_DIR)/common + +INCLUDES= -I$(top_srcdir)/include/mtcr_ul -I $(COMMON_DIR) + +LDADD= ../mtcr_ul/libmtcr_ul.a -ldl bin_PROGRAMS = mstmread \ mstmwrite \ @@ -50,4 +54,4 @@ mstvpd_SOURCES = vpd.c mstmcra_SOURCES = mcra.c mstmtserver_SOURCES = mtserver.c tcp.c tcp.h -mstmtserver_CFLAGS = -DMST_UL +mstmtserver_CFLAGS = -DMST_UL diff --git a/small_utils/mcra.c b/small_utils/mcra.c index e80ec1d..a35556c 100644 --- a/small_utils/mcra.c +++ b/small_utils/mcra.c @@ -29,60 +29,78 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ + /* * * mcra.c - Mellanox Configuratio Register Access tool * */ -#include "mtcr.h" - #include #include #include +#include +#include +#include "mtcr.h" +#include "tools_version.h" #define ONES32(size) ((size)?(0xffffffff>>(32-(size))):0) #define MASK32(offset,size) (ONES32(size)<<(offset)) #define EXTRACT_C(source,offset,size) ((((unsigned)(source))>>(offset)) & ONES32(size)) -#define EXTRACT(src,start,len) (((len)==32)?(src):EXTRACT_C(src,start,len)) +#define EXTRACT(src, start,len) (((len)==32)?(src):EXTRACT_C(src,start,len)) #define MERGE_C(rsrc1,rsrc2,start,len) ((((rsrc2)<<(start)) & (MASK32((start),(len)))) | ((rsrc1) & (~MASK32((start),(len))))) #define MERGE(rsrc1,rsrc2,start,len) (((len)==32)?(rsrc2):MERGE_C(rsrc1,rsrc2,start,len)) - +#define ADB_DUMP_VAR "ADB_DUMP" -void usage(const char *n) + +void usage(const char *n, int with_exit) { printf(" Mellanox Configuration Registers Access tool\n"); - printf(" Usage: %s :]> [data]\n", n); + printf(" Usage: %s [-s ] [-a ] [-v] [-h] :]> [data]\n", n); printf(" If data is given, operation is write. Otherwise it is read.\n"); printf(" If a bit range is given in the address (E.G.: 0xf0014.16:8):.\n"); printf(" For read - Only the requested bits are printed.\n"); - printf(" For write - Read-Modify-Write. Only the requested bits are changed.\n"); - exit(1); + printf(" For write - Read-Modify-Write. Only the requested bits are changed.\n\n"); + printf(" -s : I2C slave address.\n"); + printf(" -a : adb dump file, used for access by path.\n"); + printf(" -h : Print this help message.\n"); + printf(" -v : Display version info\n"); + printf("\n"); + printf("Environment Variables:\n"); + printf(" ADB_DUMP : Holds the path to adb dump, used for access by path (can be overriden by \"-a\").\n"); + if (with_exit) { + exit(1); + } } +#define MCRA_TOOL_NAME "mcra" +#define MCRA_TOOL_VERSON "1.0.0" -int main(int ac, char *av[]) +int main(int argc, char *argv[]) { char* endp; char* dev = NULL; + char* adb_dump = NULL; + char* path = NULL; int rc=0; unsigned int addr = 0, val = 0; mfile *mf; unsigned int i2c_slave = 0; - int ap = 1; + int c; int read_op = 0; - int bit_offs = 0; - int bit_size = 32; + int bit_offs = 0; + int bit_size = 32; + int byte_size = 0; + int read_block = 0; /* if 0 then read field according to "addr.bit:size", else read block of size "byte_size" */ char* op_name = "cr write"; #if 0 int i, rc1; char buf[1024], *p=buf; rc1 = mdevices(buf, 1024); - for (i=0; i 6) - usage(av[0]); + if (argc < 2) { + usage(argv[0], 1); + } - // I2c slave stuff - if (av[1][0] == '-') { - if (!strcmp(av[1], "-s")) { - i2c_slave = strtoul(av[2], &endp, 0); + while ((c = getopt(argc, argv, "s:a:hv")) != -1) { + switch (c) { + case 's': + i2c_slave = strtoul(optarg, &endp, 0); if (*endp || i2c_slave == 0 || i2c_slave > 0x7f) { - fprintf(stderr, "-E- Bad slave address given (%s). Expecting a number [0x1 .. 0x7f]\n", av[2]); + fprintf(stderr, "-E- Bad slave address given (%s). Expecting a number [0x1 .. 0x7f]\n", optarg); exit(1); - } - ap = 3; - }else { - fprintf(stderr, "-E- Unknown flag \"%s\"\n", av[2]); + } + break; + + case 'a': + adb_dump = optarg; + break; + + case 'v': + print_version_string(MCRA_TOOL_NAME, MCRA_TOOL_VERSON); + exit(0); + + case 'h': + usage(argv[0], 0); + exit(0); + + case '?': + break; + + default: + fprintf(stderr, "-E- Unknown flag \"%c\"\n", c); exit(1); } } - if (ap >= ac) { + // parse non-optons argv elements + if (optind >= argc) { fprintf(stderr, "-E- Missing device argument\n"); exit(1); } else { - dev = av[ap]; - ap++; + dev = argv[optind]; + optind++; } - if (ap >= ac) { + if (optind >= argc) { fprintf(stderr, "-E- Missing address argument\n"); exit(1); } else { - addr = strtoul(av[ap], &endp, 0); - if (*endp != '\0' && *endp != '.') { - fprintf(stderr, "-E- Bad address given (%s). Unparsed string: \"%s\"\n", av[ap] ,endp); - exit(1); - } - - if (*endp == '.') { - bit_offs = strtoul(endp+1, &endp, 0); - if ((*endp != '\0' && *endp != ':') || bit_offs >= 32) { - fprintf(stderr, "-E- Bad bit offset in given address (%s). Unparsed string: \"%s\"\n", av[ap] ,endp); - exit(1); - } - } - - if (*endp == ':') { - bit_size = strtoul(endp+1, &endp, 0); - if (*endp != '\0') { - fprintf(stderr, "-E- Bad bit size in given address (%s). Unparsed string: \"%s\"\n", av[ap] ,endp); - exit(1); - } - - if (bit_size + bit_offs > 32) { - fprintf(stderr, "-E- Bad bit offset/size in given address (%s) - exceeds 32 bits\n", av[ap]); - - exit(1); - } - } - - if (*endp) { - fprintf(stderr, "-E- Bad address given (%s). Unparsed string: \"%s\"\n", av[ap] ,endp); - exit(1); - } - - // Allow the bit_size to be ommited - if (bit_size + bit_offs > 32) - bit_size = 32 - bit_offs; - - ap++; + addr = strtoul(argv[optind], &endp, 0); + if (*endp != '\0' && *endp != '.' && *endp != ',') { + //fprintf(stderr, "-E- Bad address given (%s). Unparsed string: \"%s\"\n", av[ap] ,endp); + //exit(1); + path = argv[optind]; + } + + if (*endp == ',') { + if (path) { + fprintf(stderr, "-E- Can't read block with full path\n"); + exit(1); + } + read_block = 1; + byte_size = strtoul(endp+1, &endp, 0); + + if (*endp != '\0' || byte_size == 0) + { + fprintf(stderr, "-E- Bad byte size in given address (%s). Unparsed string: \"%s\"\n", argv[optind] ,endp); + exit(1); + } + } + + if (*endp == '.') { + if (path) { + fprintf(stderr, "-E- Full path with bit address notation is illegal\n"); + exit(1); + } + + bit_offs = strtoul(endp+1, &endp, 0); + if ((*endp != '\0' && *endp != ':') || bit_offs >= 32) { + fprintf(stderr, "-E- Bad bit offset in given address (%s). Unparsed string: \"%s\"\n", argv[optind] ,endp); + exit(1); + } + } + + if (*endp == ':') { + if (path) { + fprintf(stderr, "-E- Full path with bit size notation is illegal\n"); + exit(1); + } + + bit_size = strtoul(endp+1, &endp, 0); + if (*endp != '\0') { + fprintf(stderr, "-E- Bad bit size in given address (%s). Unparsed string: \"%s\"\n", argv[optind] ,endp); + exit(1); + } + + if (bit_size + bit_offs > 32) { + fprintf(stderr, "-E- Bad bit offset/size in given address (%s) - exceeds 32 bits\n", argv[optind]); + + exit(1); + } + } + + if (!path && *endp) { + fprintf(stderr, "-E- Bad address given (%s). Unparsed string: \"%s\"\n", argv[optind] ,endp); + exit(1); + } + + // Allow the bit_size to be ommited + if (bit_size + bit_offs > 32) + bit_size = 32 - bit_offs; + + optind++; } - if (ap >= ac) { + + if (optind >= argc) { read_op = 1; op_name = "cr read"; } else { - val = strtoul(av[ap], &endp, 0); + val = strtoul(argv[optind], &endp, 0); if (*endp) { - fprintf(stderr, "-E- Bad data given (%s)\n", av[ap]); + fprintf(stderr, "-E- Bad data given (%s)\n", argv[optind]); exit(1); } - ap++; + optind++; } - if (ap < ac) { - fprintf(stderr, "-E- Extra argument given (%s)\n", av[ap]); + if (optind < argc) { + fprintf(stderr, "-E- Extra argument given (%s)\n", argv[optind]); exit(1); } + if (!adb_dump) { + adb_dump = getenv(ADB_DUMP_VAR); + } // Do the job mf = mopen(dev); - if (!mf) - { + if (!mf) { perror("mopen"); return 1; } - //if (i2c_slave) - // mset_i2c_slave(mf, (u_int8_t)i2c_slave); + if (i2c_slave) + mset_i2c_slave(mf, (u_int8_t)i2c_slave); + + if (path) { + FILE* fp; + char* fpath; + char line[1024]; + char *offset, *size; + unsigned tmp; + int path_found = 0; + + if (!adb_dump) { + fprintf(stderr, "-E- Can't access by path without providing adb dump file path\n"); + goto error; + } + + fp = fopen(adb_dump, "r"); + if (!fp) { + fprintf(stderr, "-E- Can't open adb dump (%s) file: %s\n", adb_dump, strerror(errno)); + goto error; + } + + while (fgets(line, sizeof(line), fp) != NULL) { + if (!strstr(line, path)) { + continue; + } + + fpath = strtok(line, " "); + + if (strcmp(fpath, path)) { + continue; + } + + if (!fpath) { + fprintf(stderr, "-E- Bad register map file format (%s), Can't find path\n", line); + fclose(fp); + goto error; + } + + offset = strtok(NULL, " "); + size = strtok(NULL, " "); + + if (!offset || !size) { + fprintf(stderr, "-E- Bad register map file format (%s), Can't find offset/size\n", line); + fclose(fp); + goto error; + } + path_found = 1; + + if (sscanf(offset, "0x%x.%d", &addr, &bit_offs) != 2) { + if (sscanf(offset, "0x%x", &addr) != 1) { + fprintf(stderr, "-E- Bad offset format in adb dump file, offset=%s\n", offset); + fclose(fp); + goto error; + } + + bit_offs = 0; + } + + if (sscanf(size, "%d", &bit_size) != 1) { + fprintf(stderr, "-E- Bad size format in adb dump file, size=%s\n", size); + fclose(fp); + goto error; + } + + break; + } + + fclose(fp); + if (!path_found) { + fprintf(stderr, "-E- Can't find path (%s)\n", path); + goto error; + } + } if (read_op) { - rc = mread4(mf, addr, &val); - val = EXTRACT(val, bit_offs, bit_size); + if (read_block) { + int i; + int dowrd_size = ((byte_size - 1)/4) + 1; + u_int32_t* data = malloc(sizeof(u_int32_t)*dowrd_size); + + if (!data) { + fprintf(stderr, "-E- Failed to allocate memmory for read block buffer\n"); + } + + addr = (addr >> 2) << 2; + if (mread4_block(mf, addr, data, dowrd_size*4) != dowrd_size*4) + goto access_error; + + // print the dowrds + for (i = 0; i < dowrd_size; i++) { + printf("0x%08x 0x%08x\n", addr + i*4, data[i]); + } + } else { + if (mread4(mf, addr, &val) != 4) + goto access_error; + + val = EXTRACT(val, bit_offs, bit_size); + printf("0x%08x\n", val); + } } else { - if (bit_offs != 0 || bit_size != 32) { - // read-modify-write - u_int32_t tmp_val; - rc = mread4(mf, addr, &tmp_val); - if (rc != 4) { - perror(op_name); - exit(1); - } - - val = MERGE(tmp_val, val, bit_offs, bit_size); - } + if (read_block) { + fprintf(stderr, "-E- Writing blocks is not supported yet\n"); + exit(1); + } + + if (bit_offs != 0 || bit_size != 32) { + // read-modify-write + u_int32_t tmp_val; + if (mread4(mf, addr, &tmp_val) != 4) + goto access_error; + + val = MERGE(tmp_val, val, bit_offs, bit_size); + } rc = mwrite4(mf, addr, val); } + goto success; - if (rc != 4) { - perror(op_name); - } else { - if (read_op) - printf("0x%08x\n", val); +access_error: + perror(op_name); - rc = 0; - } +error: + mclose(mf); + return 1; +success: mclose(mf); - return rc; + return 0; } diff --git a/tools_layouts/Makefile.am b/tools_layouts/Makefile.am new file mode 100644 index 0000000..3e6eaac --- /dev/null +++ b/tools_layouts/Makefile.am @@ -0,0 +1,47 @@ +#-- +# Copyright (c) 2004-2010 Mellanox Technologies LTD. All rights reserved. +# +# This software is available to you under a choice of one of two +# licenses. You may choose to be licensed under the terms of the GNU +# General Public License (GPL) Version 2, available from the file +# COPYING in the main directory of this source tree, or the +# OpenIB.org BSD license below: +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the following +# conditions are met: +# +# - Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# - Redistributions 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. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +#-- + +# Makefile.am -- Process this file with automake to produce Makefile.in +USER_DIR = .. +MTCR_DIR = $(USER_DIR)/mtcr_ul +INCLUDES = -I$(USER_DIR) -I$(MTCR_DIR) -I$(USER_DIR)/common #-I$(MFT_EXT_LIBS_INC_DIR) +AM_CFLAGS = -Wall -W -g -MP -MD -pipe $(COMPILER_FPIC) +lib_LTLIBRARIES = libtools_layouts.la + +libraryincludedir=$(includedir)/mstmft/tools_layouts/ + +libraryinclude_HEADERS = adb_to_c_utils.h cibfw_layouts.h + +libtools_layouts_la_SOURCES = cibfw_layouts.c adb_to_c_utils.c +#libtools_layouts_la_DEPENDENCIES = $(USER_DIR)/xz_utils/libxz_utils.la $(USER_DIR)/tools_crypto/libtools_crypto.la +#libtools_layouts_la_LIBADD = $(USER_DIR)/xz_utils/libxz_utils.la $(USER_DIR)/tools_crypto/libtools_crypto.la $(WS2_LIB) + diff --git a/tools_layouts/adb_to_c_utils.c b/tools_layouts/adb_to_c_utils.c new file mode 100644 index 0000000..64fa104 --- /dev/null +++ b/tools_layouts/adb_to_c_utils.c @@ -0,0 +1,273 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) 2010-2011, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + + +/*** + *** This file was generated at "2013-12-03 16:31:51" + *** by: + *** > /mswg/release/eat_me/last_release/adabe_plugins/adb2c/adb2pack.py --input adb/golan/golan.adb --file-prefix golan --prefix golan_ + ***/ + +#include "adb_to_c_utils.h" + +/************************************ + * Function: adb2c_calc_array_field_address + ************************************/ +u_int32_t adb2c_calc_array_field_address(u_int32_t start_bit_offset, u_int32_t arr_elemnt_size, + int arr_idx, u_int32_t parent_node_size, + int is_big_endian_arr) +{ + u_int32_t offs; + + if (arr_elemnt_size > 32) + { + assert(!(arr_elemnt_size % 32)); + start_bit_offset += arr_elemnt_size*(u_int32_t)arr_idx; + return start_bit_offset; + } + + if (is_big_endian_arr) + { + u_int32_t dword_delta; + offs = start_bit_offset - arr_elemnt_size*(u_int32_t)arr_idx; + dword_delta = (((start_bit_offset>>5)<<2) - ((offs>>5)<<2))/4; + if (dword_delta) + { + offs += 64*dword_delta; + } + } + else + { + offs = start_bit_offset + arr_elemnt_size*(u_int32_t)arr_idx; + } + + //printf("==> %d\n", MIN(32, parent_node_size) - (offs%32) - arr_elemnt_size + ((offs>>5)<<5)); + return ADB2C_MIN(32, parent_node_size) - (offs%32) - arr_elemnt_size + ((offs>>5)<<5); +} + +/************************************ + * Function: adb2c_push_integer_to_buff + ************************************/ +void adb2c_push_integer_to_buff(u_int8_t *buff, u_int32_t bit_offset, u_int32_t byte_size, u_int64_t field_value) +{ + field_value = ADB2C_CPU_TO_BE64(field_value); + memcpy(buff + bit_offset/8, (u_int8_t*)&field_value + (8-byte_size), (size_t)byte_size); +} + +/************************************ + * Function: adb2c_push_bits_to_buff + ************************************/ +//the next function will push the field into the buffer by inserting it's MSB bits first +//and therefore by doing it we save the CPU_TO_BE operation +void adb2c_push_bits_to_buff(u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_size, u_int32_t field_value) +{ + u_int32_t i = 0; + u_int32_t byte_n = bit_offset / 8; + u_int32_t byte_n_offset = bit_offset % 8; + u_int32_t to_push; + + //going over all bits in field + while (i < field_size) + { + to_push = ADB2C_MIN(8 - byte_n_offset, field_size - i); + i += to_push; + ADB2C_INSERTF_8(ADB2C_BYTE_N(buff, byte_n), 8U - to_push - byte_n_offset, field_value, field_size - i, to_push); + byte_n_offset = 0; //(byte_n_offset + to_push) % 8U; + byte_n++; + } +} + +/************************************ + * Function: adb2c_push_to_buf + ************************************/ +void adb2c_push_to_buf(u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_size, u_int64_t field_value) +{ + bit_offset = adb2c_calc_array_field_address(bit_offset, field_size, 0, field_size + 32, 0); + if (field_size <= 32) + adb2c_push_bits_to_buff(buff, bit_offset, field_size, (u_int32_t)field_value); + else + adb2c_push_integer_to_buff(buff, bit_offset, field_size/8, field_value); +} + +/************************************ + * Function: adb2c_pop_integer_from_buff + ************************************/ +u_int64_t adb2c_pop_integer_from_buff(const u_int8_t *buff, u_int32_t bit_offset, u_int32_t byte_size) +{ + u_int64_t val = 0; + memcpy((u_int8_t*)&val + (8-byte_size), buff + bit_offset/8, (size_t)byte_size); + return ADB2C_BE64_TO_CPU(val); +} + +/************************************ + * Function: adb2c_pop_bits_from_buff + ************************************/ +//the next function will pop the field into the buffer by removing it's MSB bits first +//and therefore by doing it we save the BE_TO_CPU operation +u_int32_t adb2c_pop_bits_from_buff(const u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_size) +{ + u_int32_t i = 0; + u_int32_t byte_n = bit_offset / 8; + u_int32_t byte_n_offset = bit_offset % 8; + u_int32_t field_32 = 0; + u_int32_t to_pop; + + //going over all bits in field + while (i < field_size) + { + to_pop = ADB2C_MIN(8 - byte_n_offset, field_size - i); + i += to_pop; + ADB2C_INSERTF_8(field_32, field_size - i, ADB2C_BYTE_N(buff, byte_n), 8 - to_pop - byte_n_offset, to_pop); + byte_n_offset = 0; //(byte_n_offset + to_pop) % 8; + byte_n++; + } + return field_32; +} + +/************************************ + * Function: adb2c_pop_from_buf + ************************************/ +u_int64_t adb2c_pop_from_buf(const u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_size) +{ + bit_offset = adb2c_calc_array_field_address(bit_offset, field_size, 0, field_size + 32, 0); + if (field_size <= 32) + return adb2c_pop_bits_from_buff(buff, bit_offset, field_size); + else + return adb2c_pop_integer_from_buff(buff, bit_offset, field_size/8); +} + +/************************************ + * Function: adb2c_db_get_field_enum_name + ************************************/ +const char* adb2c_db_get_field_enum_name(struct adb2c_field_format* field, int val) +{ + int i; + for (i = 0; i < field->enums_len; i++) + { + if (field->enums[i].val == val) + return field->enums[i].name; + } + + + return "Unknown Enum Value"; +} + +/************************************ + * Function: adb2c_db_get_field_enum_val + ************************************/ +int adb2c_db_get_field_enum_val(struct adb2c_field_format* field, const char* name) +{ + int i; + for (i = 0; i < field->enums_len; i++) + { + if (!strcmp(field->enums[i].name, name)) + return field->enums[i].val; + } + + return -1; +} + +/************************************ + * Function: adb2c_db_get_field_attr + ************************************/ +const char* adb2c_db_get_field_attr(struct adb2c_field_format* field, const char* attr_name) +{ + int i; + for (i = 0; i < field->attrs_len; i++) + { + if (!strcmp(attr_name, field->attrs[i].name)) + return field->attrs[i].val; + } + + return NULL; +} + +/************************************ + * Function: adb2c_db_get_node_attr + ************************************/ +const char* adb2c_db_get_node_attr(struct adb2c_node_format* node, const char* attr_name) +{ + int i; + for (i = 0; i < node->attrs_len; i++) + { + if (!strcmp(attr_name, node->attrs[i].name)) + return node->attrs[i].val; + } + + return NULL; +} + +/************************************ + * Function: adb2c_db_find_node + ************************************/ +struct adb2c_node_format* adb2c_db_find_node(struct adb2c_node_db* db, const char* node_name) +{ + int i; + + for (i = 0; i < db->nodes_len; i++) + { + if (!strcmp(node_name, db->nodes[i].name)) + return &db->nodes[i]; + } + + return NULL; +} + +/************************************ + * Function: adb2c_db_find_field + ************************************/ +struct adb2c_field_format* adb2c_db_find_field(struct adb2c_node_format* node, const char* field_name) +{ + int i; + + for(i = 0; i < node->fields_len; i++) + { + if (!strcmp(field_name, node->fields[i].full_name)) + return &node->fields[i]; + } + + return NULL; +} + +/************************************ + * Function: adb2c_add_indentation + ************************************/ +void adb2c_add_indentation(FILE* file, int indent_level) +{ + while (indent_level) + { + fprintf(file, "\t"); + indent_level--; + } +} + +/************************************ + * Function: adb2c_print_raw + ************************************/ +void adb2c_print_raw(FILE* file, void* buff, int buff_len) +{ + u_int8_t* data = (u_int8_t*)buff; + int i; + adb2c_add_indentation(file, 0); + for (i = 0; i < buff_len; i++) + { + if (!(i % 4)) + { + fprintf(file, "\n0x%08x: ", i); + } + + fprintf(file, " 0x%02x", data[i]); + } + fprintf(file, "\n"); +} diff --git a/tools_layouts/adb_to_c_utils.h b/tools_layouts/adb_to_c_utils.h new file mode 100644 index 0000000..c161407 --- /dev/null +++ b/tools_layouts/adb_to_c_utils.h @@ -0,0 +1,264 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) 2010-2011, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + + +/*** + *** This file was generated at "2013-12-03 16:31:51" + *** by: + *** > /mswg/release/eat_me/last_release/adabe_plugins/adb2c/adb2pack.py --input adb/golan/golan.adb --file-prefix golan --prefix golan_ + ***/ + +#ifndef ADABE_TO_C_UTILS +#define ADABE_TO_C_UTILS + +#include +#include +#include +#include + +//for htonl etc... +#if defined(_WIN32) || defined(_WIN64) + #include +#else /* Linux */ + #include +#endif /* Windows */ + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************/ +/************************************/ +/************************************/ +/* Endianess Defines */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + #define PLATFORM_MEM "Little Endianess" + #define _LITTLE_ENDIANESS +#else /* __BYTE_ORDER == __BIG_ENDIAN */ + #define PLATFORM_MEM "Big Endianess" + #define _BIG_ENDIANESS +#endif + + +/* Bit manipulation macros */ + +/* MASK generate a bit mask S bits width */ +//#define ADB2C_MASK32(S) ( ((u_int32_t) ~0L) >> (32-(S)) ) +#define ADB2C_MASK8(S) ( ((u_int8_t) ~0) >> (8-(S)) ) + +/* BITS generate a bit mask with bits O+S..O set (assumes 32 / 8 bit integer) */ +//#define ADB2C_BITS32(O,S) ( ADB2C_MASK32(S) << (O) ) +#define ADB2C_BITS8(O,S) ( ADB2C_MASK8(S) << (O) ) + +/* EXTRACT32/8 macro extracts S bits from (u_int32_t/u_int8_t)W with offset O + * and shifts them O places to the right (right justifies the field extracted) */ +//#define ADB2C_EXTRACT32(W,O,S) ( ((W)>>(O)) & ADB2C_MASK32(S) ) +#define ADB2C_EXTRACT8(W,O,S) ( ((W)>>(O)) & ADB2C_MASK8(S) ) + + +/* INSERT32/8 macro inserts S bits with offset O from field F into word W (u_int32_t/u_int8_t) */ +//#define ADB2C_INSERT32(W,F,O,S) ((W)= ( ( (W) & (~ADB2C_BITS32(O,S)) ) | (((F) & ADB2C_MASK32(S))<<(O)) )) +#define ADB2C_INSERT8(W,F,O,S) ((W)= ( ( (W) & (~ADB2C_BITS8(O,S)) ) | (((F) & ADB2C_MASK8(S))<<(O)) )) + +//#define ADB2C_INSERTF_32(W,O1,F,O2,S) (ADB2C_INSERT32(W, ADB2C_EXTRACT32(F, O2, S), O1, S) ) +#define ADB2C_INSERTF_8(W,O1,F,O2,S) (ADB2C_INSERT8(W, ADB2C_EXTRACT8(F, O2, S), O1, S) ) + + +#define ADB2C_PTR_64_OF_BUFF(buf, offset) ((u_int64_t*)((u_int8_t*)(buf) + (offset))) +#define ADB2C_PTR_32_OF_BUFF(buf, offset) ((u_int32_t*)((u_int8_t*)(buf) + (offset))) +#define ADB2C_PTR_8_OF_BUFF(buf, offset) ((u_int8_t*)((u_int8_t*)(buf) + (offset))) +#define ADB2C_FIELD_64_OF_BUFF(buf, offset) (*ADB2C_PTR_64_OF_BUFF(buf, offset)) +#define ADB2C_FIELD_32_OF_BUFF(buf, offset) (*ADB2C_PTR_32_OF_BUFF(buf, offset)) +#define ADB2C_FIELD_8_OF_BUFF(buf, offset) (*ADB2C_PTR_8_OF_BUFF(buf, offset)) +#define ADB2C_DWORD_N(buf, n) ADB2C_FIELD_32_OF_BUFF((buf), (n) * 4) +#define ADB2C_BYTE_N(buf, n) ADB2C_FIELD_8_OF_BUFF((buf), (n)) + + +#define ADB2C_MIN(a, b) ((a) < (b) ? (a) : (b)) + + +#define ADB2C_CPU_TO_BE32(x) htonl(x) +#define ADB2C_BE32_TO_CPU(x) ntohl(x) +#define ADB2C_CPU_TO_BE16(x) htons(x) +#define ADB2C_BE16_TO_CPU(x) ntohs(x) +#ifdef _LITTLE_ENDIANESS + #define ADB2C_CPU_TO_BE64(x) (((u_int64_t)htonl((u_int32_t)((x) & 0xffffffff)) << 32) | ((u_int64_t)htonl((u_int32_t)((x >> 32) & 0xffffffff)))) + + #define ADB2C_BE64_TO_CPU(x) (((u_int64_t)ntohl((u_int32_t)((x) & 0xffffffff)) << 32) | ((u_int64_t)ntohl((u_int32_t)((x >> 32) & 0xffffffff)))) +#else + #define ADB2C_CPU_TO_BE64(x) (x) + #define ADB2C_BE64_TO_CPU(x) (x) +#endif + + +/* define macros to the architecture of the CPU */ +#if defined(__linux) || defined(__FreeBSD__) /* __linux || __FreeBSD__ */ +# if defined(__i386__) +# define ARCH_x86 +# elif defined(__x86_64__) +# define ARCH_x86_64 +# elif defined(__ia64__) +# define ARCH_ia64 +# elif defined(__PPC64__) +# define ARCH_ppc64 +# elif defined(__PPC__) +# define ARCH_ppc +# else +# error Unknown CPU architecture using the linux OS +# endif +#elif defined(__MINGW32__) || defined(__MINGW64__) /* Windows MINGW */ +# if defined(__MINGW32__) +# define ARCH_x86 +# elif defined(__MINGW64__) +# define ARCH_x86_64 +# else +# error Unknown CPU architecture using the windows-mingw OS +# endif +#elif defined(_WIN32) || defined(_WIN64) /* Windows */ +# if defined(_WIN32) +# define ARCH_x86 +# elif defined(_WIN64) +# define ARCH_x86_64 +# else +# error Unknown CPU architecture using the windows OS +# endif +#else /* Unknown */ +# error Unknown OS +#endif + + +/* define macros for print fields */ +#define U32D_FMT "%u" +#define U32H_FMT "0x%08x" +#define UH_FMT "0x%x" +#define STR_FMT "%s" +#define U16H_FMT "0x%04x" +#define U8H_FMT "0x%02x" + +#if defined(ARCH_x86) || defined(ARCH_ppc) || defined(UEFI_BUILD) +# if defined(__MINGW32__) || defined(__MINGW64__) +# include +# define U64D_FMT "0x%"PRId64 +# define U64H_FMT "0x%"PRIx64 +# define U48H_FMT "0x%"PRIx64 +# else +# define U64D_FMT "%llu" +# define U64H_FMT "0x%016llx" +# define U48H_FMT "0x%012llx" +# endif +#elif defined (ARCH_ia64) || defined(ARCH_x86_64) || defined(ARCH_ppc64) +# define U64D_FMT "%lu" +# define U64H_FMT "0x%016lx" +# define U48H_FMT "0x%012lx" +#else +# error Unknown architecture +#endif /* ARCH */ + + +#if !defined(_WIN32) && !defined(_WIN64) /* Linux */ + #include +#elif defined(__MINGW32__) || defined(__MINGW64__) /* windows - mingw */ + #include + #ifndef MFT_TOOLS_VARS + #define MFT_TOOLS_VARS + typedef uint8_t u_int8_t; + typedef uint16_t u_int16_t; + typedef uint32_t u_int32_t; + typedef uint64_t u_int64_t; + #endif +#else /* Windows */ + typedef __int8 int8_t; + typedef unsigned __int8 u_int8_t; + typedef __int16 int16_t; + typedef unsigned __int16 u_int16_t; + typedef __int32 int32_t; + typedef unsigned __int32 u_int32_t; + typedef __int64 int64_t; + typedef unsigned __int64 u_int64_t; +#endif + + +/************************************/ +/************************************/ +/************************************/ +struct adb2c_attr_format +{ + const char* name; + const char* val; +}; + +struct adb2c_enum_format +{ + int val; + const char* name; +}; + +struct adb2c_field_format +{ + const char* full_name; + const char* desc; + int offs; + int size; + int enums_len; + struct adb2c_enum_format* enums; + int attrs_len; + struct adb2c_attr_format* attrs; +}; + +struct adb2c_node_format +{ + const char* name; + const char* desc; + int size; + int is_union; + int attrs_len; + struct adb2c_attr_format* attrs; + int fields_len; + struct adb2c_field_format* fields; +}; + +struct adb2c_node_db +{ + int nodes_len; + struct adb2c_node_format* nodes; +}; + +/************************************/ +/************************************/ +/************************************/ +u_int32_t adb2c_calc_array_field_address(u_int32_t start_bit_offset, u_int32_t arr_elemnt_size, + int arr_idx, u_int32_t parent_node_size, + int is_big_endian_arr); +void adb2c_push_integer_to_buff(u_int8_t *buff, u_int32_t bit_offset, u_int32_t byte_size, u_int64_t field_value); +void adb2c_push_bits_to_buff(u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_size, u_int32_t field_value); +void adb2c_push_to_buf(u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_size, u_int64_t field_value); +u_int64_t adb2c_pop_integer_from_buff(const u_int8_t *buff, u_int32_t bit_offset, u_int32_t byte_size); +u_int32_t adb2c_pop_bits_from_buff(const u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_size); +u_int64_t adb2c_pop_from_buf(const u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_size); +void adb2c_add_indentation(FILE* file, int indent_level); + +void adb2c_print_raw(FILE* file, void* buff, int buff_len); +void adb2c_push_to_buf(u_int8_t *buff, u_int32_t bit_offset, u_int32_t field_size, u_int64_t field_value); +const char* adb2c_db_get_field_enum_name(struct adb2c_field_format* field, int val); +int adb2c_db_get_field_enum_val(struct adb2c_field_format* field, const char* name); +const char* adb2c_db_get_field_attr(struct adb2c_field_format* field, const char* attr_name); +const char* adb2c_db_get_node_attr(struct adb2c_node_format* node, const char* attr_name); +struct adb2c_node_format* adb2c_db_find_node(struct adb2c_node_db* db, const char* node_name); +struct adb2c_field_format* adb2c_db_find_field(struct adb2c_node_format*, const char* field_name); + +#ifdef __cplusplus +} +#endif + +#endif // ADABE_TO_C_UTILS diff --git a/tools_layouts/cibfw_layouts.c b/tools_layouts/cibfw_layouts.c new file mode 100644 index 0000000..f909188 --- /dev/null +++ b/tools_layouts/cibfw_layouts.c @@ -0,0 +1,979 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) 2010-2011, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + + +/*** + *** This file was generated at "2013-12-03 16:31:41" + *** by: + *** > /mswg/release/eat_me/last_release/adabe_plugins/adb2c/adb2pack.py --input adb/cibfw/cibfw.adb --file-prefix cibfw --prefix cibfw_ + ***/ +#include "cibfw_layouts.h" + +void cibfw_uint64_pack(const struct cibfw_uint64 *ptr_struct, u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=0; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->hi); + + offset=32; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->lo); + +} + +void cibfw_uint64_unpack(struct cibfw_uint64 *ptr_struct, const u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=0; + ptr_struct->hi = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + + offset=32; + ptr_struct->lo = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + +} + +void cibfw_uint64_print(const struct cibfw_uint64 *ptr_struct, FILE* file, int indent_level){ + adb2c_add_indentation(file, indent_level); + fprintf(file, "======== uint64 ========\n"); + int i=0; + i=i; + + adb2c_add_indentation(file, indent_level); + fprintf(file, "hi : "U32H_FMT"\n", ptr_struct->hi); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "lo : "U32H_FMT"\n", ptr_struct->lo); + +} + +int cibfw_uint64_size(){ + return 8; +} + +void cibfw_uint64_dump(const struct cibfw_uint64 *ptr_struct, FILE* file) { + cibfw_uint64_print(ptr_struct, file, 0); +} + +void cibfw_uid_entry_pack(const struct cibfw_uid_entry *ptr_struct, u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=24; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->num_allocated); + + offset=16; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->step); + + offset=64; + adb2c_push_integer_to_buff(ptr_buff, offset, 8, ptr_struct->uid); + +} + +void cibfw_uid_entry_unpack(struct cibfw_uid_entry *ptr_struct, const u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=24; + ptr_struct->num_allocated = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + + offset=16; + ptr_struct->step = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + + offset=64; + ptr_struct->uid = adb2c_pop_integer_from_buff(ptr_buff, offset, 8); + +} + +void cibfw_uid_entry_print(const struct cibfw_uid_entry *ptr_struct, FILE* file, int indent_level){ + adb2c_add_indentation(file, indent_level); + fprintf(file, "======== uid_entry ========\n"); + int i=0; + i=i; + + adb2c_add_indentation(file, indent_level); + fprintf(file, "num_allocated : "UH_FMT"\n", ptr_struct->num_allocated); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "step : "UH_FMT"\n", ptr_struct->step); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "uid : "U64H_FMT"\n", ptr_struct->uid); + +} + +int cibfw_uid_entry_size(){ + return 16; +} + +void cibfw_uid_entry_dump(const struct cibfw_uid_entry *ptr_struct, FILE* file) { + cibfw_uid_entry_print(ptr_struct, file, 0); +} + +void cibfw_TRIPPLE_VERSION_pack(const struct cibfw_TRIPPLE_VERSION *ptr_struct, u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=0; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->MAJOR); + + offset=48; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->SUBMINOR); + + offset=32; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->MINOR); + +} + +void cibfw_TRIPPLE_VERSION_unpack(struct cibfw_TRIPPLE_VERSION *ptr_struct, const u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=0; + ptr_struct->MAJOR = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + + offset=48; + ptr_struct->SUBMINOR = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + + offset=32; + ptr_struct->MINOR = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + +} + +void cibfw_TRIPPLE_VERSION_print(const struct cibfw_TRIPPLE_VERSION *ptr_struct, FILE* file, int indent_level){ + adb2c_add_indentation(file, indent_level); + fprintf(file, "======== TRIPPLE_VERSION ========\n"); + int i=0; + i=i; + + adb2c_add_indentation(file, indent_level); + fprintf(file, "MAJOR : "UH_FMT"\n", ptr_struct->MAJOR); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "SUBMINOR : "UH_FMT"\n", ptr_struct->SUBMINOR); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "MINOR : "UH_FMT"\n", ptr_struct->MINOR); + +} + +int cibfw_TRIPPLE_VERSION_size(){ + return 8; +} + +void cibfw_TRIPPLE_VERSION_dump(const struct cibfw_TRIPPLE_VERSION *ptr_struct, FILE* file) { + cibfw_TRIPPLE_VERSION_print(ptr_struct, file, 0); +} + +void cibfw_FW_VERSION_pack(const struct cibfw_FW_VERSION *ptr_struct, u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=0; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->MAJOR); + + offset=48; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->SUBMINOR); + + offset=32; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->MINOR); + + offset=80; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->Hour); + + offset=72; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->Minutes); + + offset=64; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->Seconds); + + offset=120; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->Day); + + offset=112; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->Month); + + offset=96; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->Year); + +} + +void cibfw_FW_VERSION_unpack(struct cibfw_FW_VERSION *ptr_struct, const u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=0; + ptr_struct->MAJOR = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + + offset=48; + ptr_struct->SUBMINOR = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + + offset=32; + ptr_struct->MINOR = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + + offset=80; + ptr_struct->Hour = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + + offset=72; + ptr_struct->Minutes = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + + offset=64; + ptr_struct->Seconds = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + + offset=120; + ptr_struct->Day = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + + offset=112; + ptr_struct->Month = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + + offset=96; + ptr_struct->Year = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + +} + +void cibfw_FW_VERSION_print(const struct cibfw_FW_VERSION *ptr_struct, FILE* file, int indent_level){ + adb2c_add_indentation(file, indent_level); + fprintf(file, "======== FW_VERSION ========\n"); + int i=0; + i=i; + + adb2c_add_indentation(file, indent_level); + fprintf(file, "MAJOR : "UH_FMT"\n", ptr_struct->MAJOR); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "SUBMINOR : "UH_FMT"\n", ptr_struct->SUBMINOR); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "MINOR : "UH_FMT"\n", ptr_struct->MINOR); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "Hour : "UH_FMT"\n", ptr_struct->Hour); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "Minutes : "UH_FMT"\n", ptr_struct->Minutes); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "Seconds : "UH_FMT"\n", ptr_struct->Seconds); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "Day : "UH_FMT"\n", ptr_struct->Day); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "Month : "UH_FMT"\n", ptr_struct->Month); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "Year : "UH_FMT"\n", ptr_struct->Year); + +} + +int cibfw_FW_VERSION_size(){ + return 16; +} + +void cibfw_FW_VERSION_dump(const struct cibfw_FW_VERSION *ptr_struct, FILE* file) { + cibfw_FW_VERSION_print(ptr_struct, file, 0); +} + +void cibfw_guids_pack(const struct cibfw_guids *ptr_struct, u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + for (i=0; i < 2; i++) { + offset=adb2c_calc_array_field_address(0, 128, i, 512, 1); + cibfw_uid_entry_pack(&(ptr_struct->guids[i]), ptr_buff + offset/8); + } + + for (i=0; i < 2; i++) { + offset=adb2c_calc_array_field_address(256, 128, i, 512, 1); + cibfw_uid_entry_pack(&(ptr_struct->macs[i]), ptr_buff + offset/8); + } + +} + +void cibfw_guids_unpack(struct cibfw_guids *ptr_struct, const u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + for (i=0; i < 2; i++) { + offset=adb2c_calc_array_field_address(0, 128, i, 512, 1); + cibfw_uid_entry_unpack(&(ptr_struct->guids[i]), ptr_buff + offset/8); + } + + for (i=0; i < 2; i++) { + offset=adb2c_calc_array_field_address(256, 128, i, 512, 1); + cibfw_uid_entry_unpack(&(ptr_struct->macs[i]), ptr_buff + offset/8); + } + +} + +void cibfw_guids_print(const struct cibfw_guids *ptr_struct, FILE* file, int indent_level){ + adb2c_add_indentation(file, indent_level); + fprintf(file, "======== guids ========\n"); + int i=0; + i=i; + + for (i=0; i < 2; i++) { + adb2c_add_indentation(file, indent_level); + fprintf(file, "guids[%3d]:\n", i); + cibfw_uid_entry_print(&(ptr_struct->guids[i]), file, indent_level + 1); + } + + for (i=0; i < 2; i++) { + adb2c_add_indentation(file, indent_level); + fprintf(file, "macs[%3d]:\n", i); + cibfw_uid_entry_print(&(ptr_struct->macs[i]), file, indent_level + 1); + } + +} + +int cibfw_guids_size(){ + return 64; +} + +void cibfw_guids_dump(const struct cibfw_guids *ptr_struct, FILE* file) { + cibfw_guids_print(ptr_struct, file, 0); +} + +void cibfw_operation_key_pack(const struct cibfw_operation_key *ptr_struct, u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=16; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->key_modifier); + + offset=64; + adb2c_push_integer_to_buff(ptr_buff, offset, 8, ptr_struct->key); + +} + +void cibfw_operation_key_unpack(struct cibfw_operation_key *ptr_struct, const u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=16; + ptr_struct->key_modifier = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + + offset=64; + ptr_struct->key = adb2c_pop_integer_from_buff(ptr_buff, offset, 8); + +} + +void cibfw_operation_key_print(const struct cibfw_operation_key *ptr_struct, FILE* file, int indent_level){ + adb2c_add_indentation(file, indent_level); + fprintf(file, "======== operation_key ========\n"); + int i=0; + i=i; + + adb2c_add_indentation(file, indent_level); + fprintf(file, "key_modifier : "UH_FMT"\n", ptr_struct->key_modifier); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "key : "U64H_FMT"\n", ptr_struct->key); + +} + +int cibfw_operation_key_size(){ + return 16; +} + +void cibfw_operation_key_dump(const struct cibfw_operation_key *ptr_struct, FILE* file) { + cibfw_operation_key_print(ptr_struct, file, 0); +} + +void cibfw_image_info_pack(const struct cibfw_image_info *ptr_struct, u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=32; + cibfw_FW_VERSION_pack(&(ptr_struct->FW_VERSION), ptr_buff + offset/8); + + offset=160; + cibfw_TRIPPLE_VERSION_pack(&(ptr_struct->mic_version), ptr_buff + offset/8); + + for (i=0; i < 16; i++) { + offset=adb2c_calc_array_field_address(312, 8, i, 8192, 1); + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->psid[i]); + } + + offset=432; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->vsd_vendor_id); + + for (i=0; i < 208; i++) { + offset=adb2c_calc_array_field_address(472, 8, i, 8192, 1); + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->vsd[i]); + } + + for (i=0; i < 4; i++) { + offset=adb2c_calc_array_field_address(2240, 32, i, 8192, 1); + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->supported_hw_id[i]); + } + + offset=2368; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->ini_file_num); + + for (i=0; i < 16; i++) { + offset=adb2c_calc_array_field_address(3608, 8, i, 8192, 1); + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->prod_ver[i]); + } + +} + +void cibfw_image_info_unpack(struct cibfw_image_info *ptr_struct, const u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=32; + cibfw_FW_VERSION_unpack(&(ptr_struct->FW_VERSION), ptr_buff + offset/8); + + offset=160; + cibfw_TRIPPLE_VERSION_unpack(&(ptr_struct->mic_version), ptr_buff + offset/8); + + for (i=0; i < 16; i++) { + offset=adb2c_calc_array_field_address(312, 8, i, 8192, 1); + ptr_struct->psid[i] = (char)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + } + + ptr_struct->psid[16] = '\0'; + offset=432; + ptr_struct->vsd_vendor_id = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + + for (i=0; i < 208; i++) { + offset=adb2c_calc_array_field_address(472, 8, i, 8192, 1); + ptr_struct->vsd[i] = (char)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + } + + ptr_struct->vsd[208] = '\0'; + for (i=0; i < 4; i++) { + offset=adb2c_calc_array_field_address(2240, 32, i, 8192, 1); + ptr_struct->supported_hw_id[i] = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + } + + offset=2368; + ptr_struct->ini_file_num = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + + for (i=0; i < 16; i++) { + offset=adb2c_calc_array_field_address(3608, 8, i, 8192, 1); + ptr_struct->prod_ver[i] = (char)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + } + + ptr_struct->prod_ver[16] = '\0'; +} + +void cibfw_image_info_print(const struct cibfw_image_info *ptr_struct, FILE* file, int indent_level){ + adb2c_add_indentation(file, indent_level); + fprintf(file, "======== image_info ========\n"); + int i=0; + i=i; + + adb2c_add_indentation(file, indent_level); + fprintf(file, "FW_VERSION:\n"); + cibfw_FW_VERSION_print(&(ptr_struct->FW_VERSION), file, indent_level + 1); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "mic_version:\n"); + cibfw_TRIPPLE_VERSION_print(&(ptr_struct->mic_version), file, indent_level + 1); + + fprintf(file, "psid : \"%s\"\n", ptr_struct->psid); + adb2c_add_indentation(file, indent_level); + fprintf(file, "vsd_vendor_id : "UH_FMT"\n", ptr_struct->vsd_vendor_id); + + fprintf(file, "vsd : \"%s\"\n", ptr_struct->vsd); + for (i=0; i < 4; i++) { + adb2c_add_indentation(file, indent_level); + fprintf(file, "supported_hw_id[%3d] : "U32H_FMT"\n", i, ptr_struct->supported_hw_id[i]); + } + + adb2c_add_indentation(file, indent_level); + fprintf(file, "ini_file_num : "U32H_FMT"\n", ptr_struct->ini_file_num); + + fprintf(file, "prod_ver : \"%s\"\n", ptr_struct->prod_ver); +} + +int cibfw_image_info_size(){ + return 1024; +} + +void cibfw_image_info_dump(const struct cibfw_image_info *ptr_struct, FILE* file) { + cibfw_image_info_print(ptr_struct, file, 0); +} + +void cibfw_mfg_info_pack(const struct cibfw_mfg_info *ptr_struct, u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + for (i=0; i < 16; i++) { + offset=adb2c_calc_array_field_address(24, 8, i, 2560, 1); + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->psid[i]); + } + + offset=255; + adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->guids_override_en); + + offset=256; + cibfw_guids_pack(&(ptr_struct->guids), ptr_buff + offset/8); + +} + +void cibfw_mfg_info_unpack(struct cibfw_mfg_info *ptr_struct, const u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + for (i=0; i < 16; i++) { + offset=adb2c_calc_array_field_address(24, 8, i, 2560, 1); + ptr_struct->psid[i] = (char)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + } + + ptr_struct->psid[16] = '\0'; + offset=255; + ptr_struct->guids_override_en = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); + + offset=256; + cibfw_guids_unpack(&(ptr_struct->guids), ptr_buff + offset/8); + +} + +void cibfw_mfg_info_print(const struct cibfw_mfg_info *ptr_struct, FILE* file, int indent_level){ + adb2c_add_indentation(file, indent_level); + fprintf(file, "======== mfg_info ========\n"); + int i=0; + i=i; + + fprintf(file, "psid : \"%s\"\n", ptr_struct->psid); + adb2c_add_indentation(file, indent_level); + fprintf(file, "guids_override_en : "UH_FMT"\n", ptr_struct->guids_override_en); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "guids:\n"); + cibfw_guids_print(&(ptr_struct->guids), file, indent_level + 1); + +} + +int cibfw_mfg_info_size(){ + return 320; +} + +void cibfw_mfg_info_dump(const struct cibfw_mfg_info *ptr_struct, FILE* file) { + cibfw_mfg_info_print(ptr_struct, file, 0); +} + +void cibfw_device_info_pack(const struct cibfw_device_info *ptr_struct, u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=0; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->signature0); + + offset=32; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->signature1); + + offset=64; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->signature2); + + offset=96; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->signature3); + + offset=152; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->minor_version); + + offset=143; + adb2c_push_bits_to_buff(ptr_buff, offset, 9, (u_int32_t)ptr_struct->major_version); + + offset=256; + cibfw_guids_pack(&(ptr_struct->guids), ptr_buff + offset/8); + + offset=880; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->vsd_vendor_id); + + for (i=0; i < 208; i++) { + offset=adb2c_calc_array_field_address(920, 8, i, 4096, 1); + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->vsd[i]); + } + + for (i=0; i < 4; i++) { + offset=adb2c_calc_array_field_address(2816, 128, i, 4096, 1); + cibfw_operation_key_pack(&(ptr_struct->keys[i]), ptr_buff + offset/8); + } + +} + +void cibfw_device_info_unpack(struct cibfw_device_info *ptr_struct, const u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=0; + ptr_struct->signature0 = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + + offset=32; + ptr_struct->signature1 = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + + offset=64; + ptr_struct->signature2 = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + + offset=96; + ptr_struct->signature3 = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + + offset=152; + ptr_struct->minor_version = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + + offset=143; + ptr_struct->major_version = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 9); + + offset=256; + cibfw_guids_unpack(&(ptr_struct->guids), ptr_buff + offset/8); + + offset=880; + ptr_struct->vsd_vendor_id = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + + for (i=0; i < 208; i++) { + offset=adb2c_calc_array_field_address(920, 8, i, 4096, 1); + ptr_struct->vsd[i] = (char)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + } + + ptr_struct->vsd[208] = '\0'; + for (i=0; i < 4; i++) { + offset=adb2c_calc_array_field_address(2816, 128, i, 4096, 1); + cibfw_operation_key_unpack(&(ptr_struct->keys[i]), ptr_buff + offset/8); + } + +} + +void cibfw_device_info_print(const struct cibfw_device_info *ptr_struct, FILE* file, int indent_level){ + adb2c_add_indentation(file, indent_level); + fprintf(file, "======== device_info ========\n"); + int i=0; + i=i; + + adb2c_add_indentation(file, indent_level); + fprintf(file, "signature0 : "U32H_FMT"\n", ptr_struct->signature0); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "signature1 : "U32H_FMT"\n", ptr_struct->signature1); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "signature2 : "U32H_FMT"\n", ptr_struct->signature2); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "signature3 : "U32H_FMT"\n", ptr_struct->signature3); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "minor_version : "UH_FMT"\n", ptr_struct->minor_version); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "major_version : "UH_FMT"\n", ptr_struct->major_version); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "guids:\n"); + cibfw_guids_print(&(ptr_struct->guids), file, indent_level + 1); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "vsd_vendor_id : "UH_FMT"\n", ptr_struct->vsd_vendor_id); + + fprintf(file, "vsd : \"%s\"\n", ptr_struct->vsd); + for (i=0; i < 4; i++) { + adb2c_add_indentation(file, indent_level); + fprintf(file, "keys[%3d]:\n", i); + cibfw_operation_key_print(&(ptr_struct->keys[i]), file, indent_level + 1); + } + +} + +int cibfw_device_info_size(){ + return 512; +} + +void cibfw_device_info_dump(const struct cibfw_device_info *ptr_struct, FILE* file) { + cibfw_device_info_print(ptr_struct, file, 0); +} + +void cibfw_itoc_header_pack(const struct cibfw_itoc_header *ptr_struct, u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=0; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->signature0); + + offset=32; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->signature1); + + offset=64; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->signature2); + + offset=96; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->signature3); + + offset=152; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->version); + + offset=240; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->itoc_entry_crc); + +} + +void cibfw_itoc_header_unpack(struct cibfw_itoc_header *ptr_struct, const u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=0; + ptr_struct->signature0 = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + + offset=32; + ptr_struct->signature1 = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + + offset=64; + ptr_struct->signature2 = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + + offset=96; + ptr_struct->signature3 = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + + offset=152; + ptr_struct->version = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + + offset=240; + ptr_struct->itoc_entry_crc = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + +} + +void cibfw_itoc_header_print(const struct cibfw_itoc_header *ptr_struct, FILE* file, int indent_level){ + adb2c_add_indentation(file, indent_level); + fprintf(file, "======== itoc_header ========\n"); + int i=0; + i=i; + + adb2c_add_indentation(file, indent_level); + fprintf(file, "signature0 : "U32H_FMT"\n", ptr_struct->signature0); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "signature1 : "U32H_FMT"\n", ptr_struct->signature1); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "signature2 : "U32H_FMT"\n", ptr_struct->signature2); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "signature3 : "U32H_FMT"\n", ptr_struct->signature3); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "version : "UH_FMT"\n", ptr_struct->version); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "itoc_entry_crc : "UH_FMT"\n", ptr_struct->itoc_entry_crc); + +} + +int cibfw_itoc_header_size(){ + return 32; +} + +void cibfw_itoc_header_dump(const struct cibfw_itoc_header *ptr_struct, FILE* file) { + cibfw_itoc_header_print(ptr_struct, file, 0); +} + +void cibfw_itoc_entry_pack(const struct cibfw_itoc_entry *ptr_struct, u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=8; + adb2c_push_bits_to_buff(ptr_buff, offset, 22, (u_int32_t)ptr_struct->size); + + offset=0; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->type); + + offset=32; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->param0); + + offset=64; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int64_t)ptr_struct->param1); + + offset=161; + adb2c_push_bits_to_buff(ptr_buff, offset, 29, (u_int32_t)ptr_struct->flash_addr); + + offset=160; + adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->relative_addr); + + offset=208; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->section_crc); + + offset=207; + adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->no_crc); + + offset=206; + adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->device_data); + + offset=205; + adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->cache_line_crc); + + offset=240; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->itoc_entry_crc); + +} + +void cibfw_itoc_entry_unpack(struct cibfw_itoc_entry *ptr_struct, const u_int8_t* ptr_buff){ + u_int32_t offset; + int i=0; + i=i; + + offset=8; + ptr_struct->size = (u_int32_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 22); + + offset=0; + ptr_struct->type = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + + offset=32; + ptr_struct->param0 = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + + offset=64; + ptr_struct->param1 = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + + offset=161; + ptr_struct->flash_addr = (u_int32_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 29); + + offset=160; + ptr_struct->relative_addr = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); + + offset=208; + ptr_struct->section_crc = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + + offset=207; + ptr_struct->no_crc = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); + + offset=206; + ptr_struct->device_data = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); + + offset=205; + ptr_struct->cache_line_crc = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); + + offset=240; + ptr_struct->itoc_entry_crc = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + +} + +void cibfw_itoc_entry_print(const struct cibfw_itoc_entry *ptr_struct, FILE* file, int indent_level){ + adb2c_add_indentation(file, indent_level); + fprintf(file, "======== itoc_entry ========\n"); + int i=0; + i=i; + + adb2c_add_indentation(file, indent_level); + fprintf(file, "size : "UH_FMT"\n", ptr_struct->size); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "type : "UH_FMT"\n", ptr_struct->type); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "param0 : "U32H_FMT"\n", ptr_struct->param0); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "param1 : "U32H_FMT"\n", ptr_struct->param1); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "flash_addr : "UH_FMT"\n", ptr_struct->flash_addr); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "relative_addr : "UH_FMT"\n", ptr_struct->relative_addr); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "section_crc : "UH_FMT"\n", ptr_struct->section_crc); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "no_crc : "UH_FMT"\n", ptr_struct->no_crc); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "device_data : "UH_FMT"\n", ptr_struct->device_data); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "cache_line_crc : "UH_FMT"\n", ptr_struct->cache_line_crc); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "itoc_entry_crc : "UH_FMT"\n", ptr_struct->itoc_entry_crc); + +} + +int cibfw_itoc_entry_size(){ + return 32; +} + +void cibfw_itoc_entry_dump(const struct cibfw_itoc_entry *ptr_struct, FILE* file) { + cibfw_itoc_entry_print(ptr_struct, file, 0); +} + +void cibfw_Nodes_pack(const union cibfw_Nodes *ptr_struct, u_int8_t* ptr_buff) +{ + memcpy(ptr_buff, ptr_struct, 1024); +} + +void cibfw_Nodes_unpack(union cibfw_Nodes *ptr_struct, const u_int8_t* ptr_buff) +{ + memcpy(ptr_struct, ptr_buff, 1024); +} + +void cibfw_Nodes_print(const union cibfw_Nodes *ptr_struct, FILE* file, int indent_level){ + adb2c_add_indentation(file, indent_level); + fprintf(file, "======== Nodes ========\n"); + int i=0; + i=i; + + adb2c_add_indentation(file, indent_level); + fprintf(file, "itoc_entry:\n"); + cibfw_itoc_entry_print(&(ptr_struct->itoc_entry), file, indent_level + 1); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "guids:\n"); + cibfw_guids_print(&(ptr_struct->guids), file, indent_level + 1); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "itoc_header:\n"); + cibfw_itoc_header_print(&(ptr_struct->itoc_header), file, indent_level + 1); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "device_info:\n"); + cibfw_device_info_print(&(ptr_struct->device_info), file, indent_level + 1); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "mfg_info:\n"); + cibfw_mfg_info_print(&(ptr_struct->mfg_info), file, indent_level + 1); + + adb2c_add_indentation(file, indent_level); + fprintf(file, "image_info:\n"); + cibfw_image_info_print(&(ptr_struct->image_info), file, indent_level + 1); + +} + +int cibfw_Nodes_size(){ + return 1024; +} + +void cibfw_Nodes_dump(const union cibfw_Nodes *ptr_struct, FILE* file) { + cibfw_Nodes_print(ptr_struct, file, 0); +} + diff --git a/tools_layouts/cibfw_layouts.h b/tools_layouts/cibfw_layouts.h new file mode 100644 index 0000000..7bbd351 --- /dev/null +++ b/tools_layouts/cibfw_layouts.h @@ -0,0 +1,467 @@ + +/* - Mellanox Confidential and Proprietary - + * + * Copyright (C) 2010-2011, Mellanox Technologies Ltd. ALL RIGHTS RESERVED. + * + * Except as specifically permitted herein, no portion of the information, + * including but not limited to object code and source code, may be reproduced, + * modified, distributed, republished or otherwise exploited in any form or by + * any means for any purpose without the prior written permission of Mellanox + * Technologies Ltd. Use of software subject to the terms and conditions + * detailed in the file "LICENSE.txt". + * + */ + + +/*** + *** This file was generated at "2013-12-03 16:31:41" + *** by: + *** > /mswg/release/eat_me/last_release/adabe_plugins/adb2c/adb2pack.py --input adb/cibfw/cibfw.adb --file-prefix cibfw --prefix cibfw_ + ***/ +#ifndef CIBFW_LAYOUTS_H +#define CIBFW_LAYOUTS_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "adb_to_c_utils.h"/* Description - */ +/* Size in bytes - 8 */ +struct cibfw_uint64 { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - */ + /* 0.0 - 4.31 */ + u_int32_t hi; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ + /* Description - */ + /* 4.0 - 8.31 */ + u_int32_t lo; +}; + +/* Description - */ +/* Size in bytes - 16 */ +struct cibfw_uid_entry { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - Number of allocated UIDs in this entry */ + /* 0.0 - 0.7 */ + u_int8_t num_allocated; + /* Description - Step size by which to derive the UIDs for this entry +See struct description */ + /* 0.8 - 0.15 */ + u_int8_t step; +/*---------------- DWORD[2] (Offset 0x8) ----------------*/ + /* Description - For MACs, the upper 16 bits in the 'hi' dword are reserved */ + /* 8.0 - 16.31 */ + u_int64_t uid; +}; + +/* Description - */ +/* Size in bytes - 8 */ +struct cibfw_TRIPPLE_VERSION { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - */ + /* 0.16 - 4.31 */ + u_int16_t MAJOR; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ + /* Description - */ + /* 4.0 - 4.15 */ + u_int16_t SUBMINOR; + /* Description - */ + /* 4.16 - 8.31 */ + u_int16_t MINOR; +}; + +/* Description - */ +/* Size in bytes - 16 */ +struct cibfw_FW_VERSION { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - */ + /* 0.16 - 4.31 */ + u_int16_t MAJOR; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ + /* Description - */ + /* 4.0 - 4.15 */ + u_int16_t SUBMINOR; + /* Description - */ + /* 4.16 - 8.31 */ + u_int16_t MINOR; +/*---------------- DWORD[2] (Offset 0x8) ----------------*/ + /* Description - */ + /* 8.8 - 8.15 */ + u_int8_t Hour; + /* Description - */ + /* 8.16 - 8.23 */ + u_int8_t Minutes; + /* Description - */ + /* 8.24 - 12.31 */ + u_int8_t Seconds; +/*---------------- DWORD[3] (Offset 0xc) ----------------*/ + /* Description - */ + /* 12.0 - 12.7 */ + u_int8_t Day; + /* Description - */ + /* 12.8 - 12.15 */ + u_int8_t Month; + /* Description - */ + /* 12.16 - 16.31 */ + u_int16_t Year; +}; + +/* Description - */ +/* Size in bytes - 64 */ +struct cibfw_guids { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - UIDs (MACs and GUIDs) Allocation Entry. +guids[0], is used for system GUID, node GUID and port GUID of port 0. guids[1], is used for port GUID of port 1.;/Multiple UIDs can be assigned to a single port, to be used for multiple virtual guests. + +Allocation Example: +For a port GUID, if the + UID = 0x2c9030001000 + num_allocated = 4, + step = 8 + +Then the GUIDs for this port would be: + 0x2c9030001000 + 0x2c9030001008 + 0x2c9030001010 + 0x2c9030001018 */ + /* 0.0 - 32.31 */ + struct cibfw_uid_entry guids[2]; +/*---------------- DWORD[8] (Offset 0x20) ----------------*/ + /* Description - */ + /* 32.0 - 64.31 */ + struct cibfw_uid_entry macs[2]; +}; + +/* Description - */ +/* Size in bytes - 16 */ +struct cibfw_operation_key { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - */ + /* 0.0 - 0.15 */ + u_int16_t key_modifier; +/*---------------- DWORD[2] (Offset 0x8) ----------------*/ + /* Description - */ + /* 8.0 - 16.31 */ + u_int64_t key; +}; + +/* Description - */ +/* Size in bytes - 1024 */ +struct cibfw_image_info { +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ + /* Description - */ + /* 4.0 - 20.31 */ + struct cibfw_FW_VERSION FW_VERSION; +/*---------------- DWORD[5] (Offset 0x14) ----------------*/ + /* Description - */ + /* 20.0 - 28.31 */ + struct cibfw_TRIPPLE_VERSION mic_version; +/*---------------- DWORD[9] (Offset 0x24) ----------------*/ + /* Description - */ + /* 36.24 - 52.23 */ + char psid[17]; +/*---------------- DWORD[13] (Offset 0x34) ----------------*/ + /* Description - */ + /* 52.0 - 52.15 */ + u_int16_t vsd_vendor_id; +/*---------------- DWORD[14] (Offset 0x38) ----------------*/ + /* Description - */ + /* 56.24 - 264.23 */ + char vsd[209]; +/*---------------- DWORD[70] (Offset 0x118) ----------------*/ + /* Description - HW device(s) supported by this FW image. +0 means invalid entry. +For Golan A0, first entry should be 0x1ff + */ + /* 280.0 - 296.31 */ + u_int32_t supported_hw_id[4]; +/*---------------- DWORD[74] (Offset 0x128) ----------------*/ + /* Description - */ + /* 296.0 - 300.31 */ + u_int32_t ini_file_num; +/*---------------- DWORD[112] (Offset 0x1c0) ----------------*/ + /* Description - Product Version is the unified version of the FW and expansion ROM. +Format is defined by the packager. +When set to a non-empty string the FW update tool burns the image as a monolythic entity and refuses to update rom only or FW only. */ + /* 448.24 - 464.23 */ + char prod_ver[17]; +}; + +/* Description - */ +/* Size in bytes - 320 */ +struct cibfw_mfg_info { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - */ + /* 0.24 - 16.23 */ + char psid[17]; +/*---------------- DWORD[7] (Offset 0x1c) ----------------*/ + /* Description - When this bit is set, the GUIDs should eb taken from the device_info node. +When this bit is cleared, the GUIDs should be taken from the mfg_info node. */ + /* 28.0 - 28.0 */ + u_int8_t guids_override_en; +/*---------------- DWORD[8] (Offset 0x20) ----------------*/ + /* Description - */ + /* 32.0 - 96.31 */ + struct cibfw_guids guids; +}; + +/* Description - */ +/* Size in bytes - 512 */ +struct cibfw_device_info { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - */ + /* 0.0 - 4.31 */ + u_int32_t signature0; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ + /* Description - */ + /* 4.0 - 8.31 */ + u_int32_t signature1; +/*---------------- DWORD[2] (Offset 0x8) ----------------*/ + /* Description - */ + /* 8.0 - 12.31 */ + u_int32_t signature2; +/*---------------- DWORD[3] (Offset 0xc) ----------------*/ + /* Description - */ + /* 12.0 - 16.31 */ + u_int32_t signature3; +/*---------------- DWORD[4] (Offset 0x10) ----------------*/ + /* Description - Format version for this struct */ + /* 16.0 - 16.7 */ + u_int8_t minor_version; + /* Description - Format version for this struct */ + /* 16.8 - 16.16 */ + u_int16_t major_version; +/*---------------- DWORD[8] (Offset 0x20) ----------------*/ + /* Description - */ + /* 32.0 - 96.31 */ + struct cibfw_guids guids; +/*---------------- DWORD[27] (Offset 0x6c) ----------------*/ + /* Description - */ + /* 108.0 - 108.15 */ + u_int16_t vsd_vendor_id; +/*---------------- DWORD[28] (Offset 0x70) ----------------*/ + /* Description - */ + /* 112.24 - 320.23 */ + char vsd[209]; +/*---------------- DWORD[88] (Offset 0x160) ----------------*/ + /* Description - */ + /* 352.0 - 416.31 */ + struct cibfw_operation_key keys[4]; +}; + +/* Description - */ +/* Size in bytes - 32 */ +struct cibfw_itoc_header { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - 49 54 4f 43 */ + /* 0.0 - 4.31 */ + u_int32_t signature0; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ + /* Description - 04 08 15 16 */ + /* 4.0 - 8.31 */ + u_int32_t signature1; +/*---------------- DWORD[2] (Offset 0x8) ----------------*/ + /* Description - 23 42 ca fa */ + /* 8.0 - 12.31 */ + u_int32_t signature2; +/*---------------- DWORD[3] (Offset 0xc) ----------------*/ + /* Description - ba ca fe 00 */ + /* 12.0 - 16.31 */ + u_int32_t signature3; +/*---------------- DWORD[4] (Offset 0x10) ----------------*/ + /* Description - Current version: 1 */ + /* 16.0 - 16.7 */ + u_int8_t version; +/*---------------- DWORD[7] (Offset 0x1c) ----------------*/ + /* Description - */ + /* 28.0 - 28.15 */ + u_int16_t itoc_entry_crc; +}; + +/* Description - */ +/* Size in bytes - 32 */ +struct cibfw_itoc_entry { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - */ + /* 0.2 - 0.23 */ + u_int32_t size; + /* Description - Section ID Section Type DESCRIPTION +0x1 BOOT_CODE FW loader code +0x2 PCI_CODE Code that is required to raise PCIe link. +0x3 MAIN_CODE All non-PCIe FW code +0x8 HW_BOOT_CFG Initial values for the PCI related registers +0x9 HW_MAIN_CFG Initial values for all other registers +0x10 IMAGE_INFO Management data for the burning tool. See 'Image Info Section' chapter in the Mellanox Flash Programming Application Note +0x11 FW_BOOT_CFG Initial values for user set-able hi level non-hardware related settings, such as number of physical functions +(optional) +0x12 FW_MAIN_CFG Initial values for user set-able hi level non-hardware related settings. +(optional) +0x18 ROM_CODE PXE/Boot over IB code. +0x30 DBG_LOG_MAP FW logger 'index to string' map. The map is in ASCI text. Format is TBD. + PARAM0 in the iTOC specifies the compression method of this sector: + 0. Uncompressed + 1. Zlib compress2() + 2. LZMA + Others - Reserved +0x31 DBG_FW_INI The Ini file used in the image generation. The PARAM0 applies the same as in DBG_LOG_MAP section type. +0x32 DBG_FW_PARAMS FW settable parameters. ASCII text. Format is TBD. The PARAM0 applies the same as in DBG_LOG_MAP section type. +0xff END_MARKER A type of 0xff marks the end of the iTOC entries array. It is recommended to leave the unused part of the iTOC section blank (that is, 0xff in all unused bytes) +All other values Reserved + */ + /* 0.24 - 4.31 */ + u_int8_t type; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ + /* Description - if partition type is code or ini then the load address is in here */ + /* 4.0 - 8.31 */ + u_int32_t param0; +/*---------------- DWORD[2] (Offset 0x8) ----------------*/ + /* Description - if partition type is code then the jump address is in here */ + /* 8.0 - 12.31 */ + u_int32_t param1; +/*---------------- DWORD[5] (Offset 0x14) ----------------*/ + /* Description - */ + /* 20.2 - 20.30 */ + u_int32_t flash_addr; + /* Description - */ + /* 20.31 - 24.31 */ + u_int8_t relative_addr; +/*---------------- DWORD[6] (Offset 0x18) ----------------*/ + /* Description - */ + /* 24.0 - 24.15 */ + u_int16_t section_crc; + /* Description - */ + /* 24.16 - 24.16 */ + u_int8_t no_crc; + /* Description - When this bit is set, the section pointed by this entry in belongs to teh device tather than to teh FW image. +A device_data section should not be updated in a regular FW update. +Example for device_data section: VPD_R, GUIDs. */ + /* 24.17 - 24.17 */ + u_int8_t device_data; + /* Description - When this bit is set, Data within the section is protected by per-line crc. See yu.flash.replacement.crc_en */ + /* 24.18 - 24.18 */ + u_int8_t cache_line_crc; +/*---------------- DWORD[7] (Offset 0x1c) ----------------*/ + /* Description - */ + /* 28.0 - 28.15 */ + u_int16_t itoc_entry_crc; +}; + +/* Description - */ +/* Size in bytes - 1024 */ +union cibfw_Nodes { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - */ + /* 0.0 - 32.31 */ + struct cibfw_itoc_entry itoc_entry; + /* Description - */ + /* 0.0 - 64.31 */ + struct cibfw_guids guids; + /* Description - */ + /* 0.0 - 32.31 */ + struct cibfw_itoc_header itoc_header; + /* Description - */ + /* 0.0 - 512.31 */ + struct cibfw_device_info device_info; + /* Description - */ + /* 0.0 - 320.31 */ + struct cibfw_mfg_info mfg_info; + /* Description - */ + /* 0.0 - 1024.31 */ + struct cibfw_image_info image_info; +}; + + +/*================= PACK/UNPACK/PRINT FUNCTIONS ======================*/ +/* uint64 */ +void cibfw_uint64_pack(const struct cibfw_uint64 *ptr_struct, u_int8_t* ptr_buff); +void cibfw_uint64_unpack(struct cibfw_uint64 *ptr_struct, const u_int8_t* ptr_buff); +void cibfw_uint64_print(const struct cibfw_uint64 *ptr_struct, FILE* file, int indent_level); +int cibfw_uint64_size(); +#define CIBFW_UINT64_SIZE (0x8) +void cibfw_uint64_dump(const struct cibfw_uint64 *ptr_struct, FILE* file); +/* uid_entry */ +void cibfw_uid_entry_pack(const struct cibfw_uid_entry *ptr_struct, u_int8_t* ptr_buff); +void cibfw_uid_entry_unpack(struct cibfw_uid_entry *ptr_struct, const u_int8_t* ptr_buff); +void cibfw_uid_entry_print(const struct cibfw_uid_entry *ptr_struct, FILE* file, int indent_level); +int cibfw_uid_entry_size(); +#define CIBFW_UID_ENTRY_SIZE (0x10) +void cibfw_uid_entry_dump(const struct cibfw_uid_entry *ptr_struct, FILE* file); +/* TRIPPLE_VERSION */ +void cibfw_TRIPPLE_VERSION_pack(const struct cibfw_TRIPPLE_VERSION *ptr_struct, u_int8_t* ptr_buff); +void cibfw_TRIPPLE_VERSION_unpack(struct cibfw_TRIPPLE_VERSION *ptr_struct, const u_int8_t* ptr_buff); +void cibfw_TRIPPLE_VERSION_print(const struct cibfw_TRIPPLE_VERSION *ptr_struct, FILE* file, int indent_level); +int cibfw_TRIPPLE_VERSION_size(); +#define CIBFW_TRIPPLE_VERSION_SIZE (0x8) +void cibfw_TRIPPLE_VERSION_dump(const struct cibfw_TRIPPLE_VERSION *ptr_struct, FILE* file); +/* FW_VERSION */ +void cibfw_FW_VERSION_pack(const struct cibfw_FW_VERSION *ptr_struct, u_int8_t* ptr_buff); +void cibfw_FW_VERSION_unpack(struct cibfw_FW_VERSION *ptr_struct, const u_int8_t* ptr_buff); +void cibfw_FW_VERSION_print(const struct cibfw_FW_VERSION *ptr_struct, FILE* file, int indent_level); +int cibfw_FW_VERSION_size(); +#define CIBFW_FW_VERSION_SIZE (0x10) +void cibfw_FW_VERSION_dump(const struct cibfw_FW_VERSION *ptr_struct, FILE* file); +/* guids */ +void cibfw_guids_pack(const struct cibfw_guids *ptr_struct, u_int8_t* ptr_buff); +void cibfw_guids_unpack(struct cibfw_guids *ptr_struct, const u_int8_t* ptr_buff); +void cibfw_guids_print(const struct cibfw_guids *ptr_struct, FILE* file, int indent_level); +int cibfw_guids_size(); +#define CIBFW_GUIDS_SIZE (0x40) +void cibfw_guids_dump(const struct cibfw_guids *ptr_struct, FILE* file); +/* operation_key */ +void cibfw_operation_key_pack(const struct cibfw_operation_key *ptr_struct, u_int8_t* ptr_buff); +void cibfw_operation_key_unpack(struct cibfw_operation_key *ptr_struct, const u_int8_t* ptr_buff); +void cibfw_operation_key_print(const struct cibfw_operation_key *ptr_struct, FILE* file, int indent_level); +int cibfw_operation_key_size(); +#define CIBFW_OPERATION_KEY_SIZE (0x10) +void cibfw_operation_key_dump(const struct cibfw_operation_key *ptr_struct, FILE* file); +/* image_info */ +void cibfw_image_info_pack(const struct cibfw_image_info *ptr_struct, u_int8_t* ptr_buff); +void cibfw_image_info_unpack(struct cibfw_image_info *ptr_struct, const u_int8_t* ptr_buff); +void cibfw_image_info_print(const struct cibfw_image_info *ptr_struct, FILE* file, int indent_level); +int cibfw_image_info_size(); +#define CIBFW_IMAGE_INFO_SIZE (0x400) +void cibfw_image_info_dump(const struct cibfw_image_info *ptr_struct, FILE* file); +/* mfg_info */ +void cibfw_mfg_info_pack(const struct cibfw_mfg_info *ptr_struct, u_int8_t* ptr_buff); +void cibfw_mfg_info_unpack(struct cibfw_mfg_info *ptr_struct, const u_int8_t* ptr_buff); +void cibfw_mfg_info_print(const struct cibfw_mfg_info *ptr_struct, FILE* file, int indent_level); +int cibfw_mfg_info_size(); +#define CIBFW_MFG_INFO_SIZE (0x140) +void cibfw_mfg_info_dump(const struct cibfw_mfg_info *ptr_struct, FILE* file); +/* device_info */ +void cibfw_device_info_pack(const struct cibfw_device_info *ptr_struct, u_int8_t* ptr_buff); +void cibfw_device_info_unpack(struct cibfw_device_info *ptr_struct, const u_int8_t* ptr_buff); +void cibfw_device_info_print(const struct cibfw_device_info *ptr_struct, FILE* file, int indent_level); +int cibfw_device_info_size(); +#define CIBFW_DEVICE_INFO_SIZE (0x200) +void cibfw_device_info_dump(const struct cibfw_device_info *ptr_struct, FILE* file); +/* itoc_header */ +void cibfw_itoc_header_pack(const struct cibfw_itoc_header *ptr_struct, u_int8_t* ptr_buff); +void cibfw_itoc_header_unpack(struct cibfw_itoc_header *ptr_struct, const u_int8_t* ptr_buff); +void cibfw_itoc_header_print(const struct cibfw_itoc_header *ptr_struct, FILE* file, int indent_level); +int cibfw_itoc_header_size(); +#define CIBFW_ITOC_HEADER_SIZE (0x20) +void cibfw_itoc_header_dump(const struct cibfw_itoc_header *ptr_struct, FILE* file); +/* itoc_entry */ +void cibfw_itoc_entry_pack(const struct cibfw_itoc_entry *ptr_struct, u_int8_t* ptr_buff); +void cibfw_itoc_entry_unpack(struct cibfw_itoc_entry *ptr_struct, const u_int8_t* ptr_buff); +void cibfw_itoc_entry_print(const struct cibfw_itoc_entry *ptr_struct, FILE* file, int indent_level); +int cibfw_itoc_entry_size(); +#define CIBFW_ITOC_ENTRY_SIZE (0x20) +void cibfw_itoc_entry_dump(const struct cibfw_itoc_entry *ptr_struct, FILE* file); +/* Nodes */ +void cibfw_Nodes_pack(const union cibfw_Nodes *ptr_struct, u_int8_t* ptr_buff); +void cibfw_Nodes_unpack(union cibfw_Nodes *ptr_struct, const u_int8_t* ptr_buff); +void cibfw_Nodes_print(const union cibfw_Nodes *ptr_struct, FILE* file, int indent_level); +int cibfw_Nodes_size(); +#define CIBFW_NODES_SIZE (0x400) +void cibfw_Nodes_dump(const union cibfw_Nodes *ptr_struct, FILE* file); + + +#ifdef __cplusplus +} +#endif + +#endif // CIBFW_LAYOUTS_H -- 2.41.0