📄 nvbuild.c
字号:
#define STATIC
/*
** File: NVBUILD.C
**
** Function: Contains routines necessary for the
** NVBUILD portion of the AMCCPCI program.
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#include <time.h>
#include <conio.h>
#include <dos.h>
#include <io.h>
#include "cxldef.h"
#include "cxlkey.h"
#include "cxlmou.h"
#include "cxlstr.h"
#include "cxlvid.h"
#include "cxlwin.h"
#include "amcc.h"
#include "amccpci.h"
#define AMCC_VENDOR_ID 0x10e8
STATIC int backup_file(char *);
STATIC int check_class_code(char *);
STATIC int check_device_id(char *);
STATIC int check_exp_rom(char *);
STATIC int check_filetype(char *);
STATIC int check_intr_pin(char *);
STATIC int check_io_base_addr(char *);
STATIC int check_latency_timer(char *);
STATIC int check_membase_addr(char *);
STATIC int check_memory_loc(char *);
STATIC int check_passthru(char *);
STATIC int check_revision_id(char *);
STATIC int check_subclass_code(char *);
STATIC int check_subsys_device_id(char *);
STATIC int check_subsys_vendor_id(char *);
STATIC int check_vendor_id(char *);
STATIC void close_progress_display(void);
STATIC void del_menu_pick(void);
STATIC void determine_row_col(int *, int *, int);
STATIC void disp_exp_rom(void);
STATIC void disp_menu_pick(void);
STATIC void disp_select_device(void);
STATIC void display_image(void);
STATIC void edit_base(void);
STATIC void edit_base_addr(void);
STATIC void edit_loc_45_config_bits(void);
STATIC void edit_other(void);
STATIC void download(void);
STATIC void edit(void);
STATIC void initialize_progress_display(void);
STATIC void load(void);
STATIC int load_hex_file(char *, byte *, long, long *, int);
STATIC int load_nvram_from_device(int);
STATIC void merge_with_file(void);
STATIC int output_hex_line(FILE *, int, long, byte *, int *);
STATIC int output_hex_eof(FILE *);
STATIC void pick_base_io_mem_size(void);
STATIC void pick_base_mem_size(void);
STATIC void pick_class_code(void);
STATIC void pick_exp_rom(void);
STATIC void pick_memory_loc(void);
STATIC void pick_passthru_width(void);
STATIC void pick_subclass_code(void);
STATIC void post_base_io_mem_size(void);
STATIC void post_base_mem_size(void);
STATIC void post_class_code(void);
STATIC void post_exp_rom(void);
STATIC void post_intr_pin(void);
STATIC void post_memory_loc(void);
STATIC void post_passthru_width(void);
STATIC void post_subclass_code(void);
STATIC void pre_base_io_mem_size(void);
STATIC void pre_base_mem_size(void);
STATIC void pre_class_code(void);
STATIC void pre_edit_menu(void);
STATIC void pre_exp_rom(void);
STATIC void pre_intr_pin(void);
STATIC void pre_memory_loc(void);
STATIC void pre_nvbuild_menu(void);
STATIC void pre_passthru_width(void);
STATIC void pre_subclass_code(void);
STATIC int program_nvram(byte *, long, dword, int, word);
STATIC int program_nvram_segment(dword, word, byte *, int, long);
STATIC void save(void);
STATIC int save_hex_data(FILE *);
STATIC void save_nvram_to_device(void);
STATIC void save_to_file(void);
STATIC void update_progress_display(long, long);
STATIC void update_base_addr(void);
STATIC int wait_for_not_busy_io(word);
STATIC int wait_for_not_busy_mem(FARPTR);
STATIC int select_nvram_file(char *);
#pragma pack(1)
struct s5920 {
byte PCI_target_latency_enb:1;
byte retry_flush_enb:1;
byte write_fifo_mode:1;
byte reserved:4;
byte reserved2:1;
};
struct s5933 {
byte PCI_latency_timer_timeout_enable:1;
byte reserved:4;
byte wrfifo_enable:1;
byte rdfifo_enable:1;
byte bus_master_add_on:1;
};
struct nvram {
word vendor_id;
word device_id;
byte command_low;
union {
struct s5920 s20;
struct s5933 s33;
} command_high;
word status;
byte revision_id;
struct {
byte prog_if;
byte subclass;
byte base_class;
} class_code;
byte cache_line_size;
byte latency_timer;
struct {
byte reserved:7;
byte multi_function:1;
} header_type;
struct {
byte reserved:7;
byte bist_capable:1;
} bist;
dword base_address[6];
dword reserved_28h_2Bh;
word subsystem_vendor_id;
word subsystem_device_id;
dword exp_rom_size;
dword reserved_34h_37h;
dword reserved_38h_3Bh;
byte intr_line;
byte intr_pin;
byte min_grant;
byte max_latency;
};
struct nvram default_nvram =
{
AMCC_VENDOR_ID, /* vendor_id (AMCC id) */
0x5933, /* device_id (5933) */
0, /* command low */
{1,0,1,1,1}, /* command high */
0, /* status */
0, /* revision_id */
{0,0,0xff}, /* class_code */
0, /* Cache line size */
0, /* latency timer */
{0, 0}, /* header_type */
{0, 0}, /* bist */
{ 0x10e8ffc1L, /* base address registers */
0x0L,
0x0L,
0x0L,
0x0L,
0x0L
},
0, /* reserved_28h_2Bh */
0, /* subsystem_vendor_id */
0, /* subsystem_id */
0, /* expansion rom address */
0, /* reserved_34h_37h */
0, /* reserved_38h_3Bh */
0xff, /* interrupt_line (no connection) */
0x01, /* interrupt_pin (INT#A) */
0, /* min_gnt */
0 /* max_lat */
};
#pragma pack()
#define NUMBER_DEVICE_TYPES 7
enum nvram_program_type {UNKNOWN_DEVICE, SECTOR_BASED_EEPROM, SERIAL_NVRAM};
char *nvram_names[NUMBER_DEVICE_TYPES + 1] = {"Amtel AT29C256",
"Amtel AT29C512",
"24C01",
"24C02",
"24C04",
"24C08",
"24C16",
NULL
};
STATIC struct nvram_program
{
byte type; /* nvram_program_type */
long size; /* bytes */
long sector_size; /* bytes per sector -- SECTOR_BASED_EEPROM only */
} nvram_programs[NUMBER_DEVICE_TYPES + 1] = {
{SECTOR_BASED_EEPROM, 32*1024, 64},
{SECTOR_BASED_EEPROM, 64*1024, 128},
{SERIAL_NVRAM, 128, 1},
{SERIAL_NVRAM, 256, 1},
{SERIAL_NVRAM, 512, 1},
{SERIAL_NVRAM, 1*1024, 1},
{SERIAL_NVRAM, 2*1024, 1},
{UNKNOWN_DEVICE, 0, 0}
};
STATIC WINDOW nvbuild_menu_window;
struct nvram cur_nvram;
struct nvram tmp_nvram;
ULONG nvram_loaded;
ULONG nvram_bsize;
byte *nvram_buf;
#define MAXPATH 255
#define MAXDRIVE 3
#define MAXDIR MAXPATH
#define MAXFILE 9
#define MAXEXT 5
STATIC char savename[MAXPATH] = "NVRAM.HEX";
int field_edit_menu;
void (*field_edit_menu_process)(void);
STATIC int class_code_subscr;
STATIC int subclass_code_subscr;
STATIC char vendor_id[5];
STATIC char subsystem_vendor_id[5];
STATIC char device_id[5];
STATIC char subsystem_device_id[5];
STATIC char revision_id[3];
STATIC char class_code[3];
STATIC char subclass_code[3];
STATIC char prog_if[3];
STATIC char latency_timer[3];
STATIC char multi_function_agent[2];
STATIC char bist_capable[2];
STATIC char intr_line[3];
struct _field_t *subclass_field;
char intr_pin[2];
int intr_pin_subscr;
char min_grant[3];
char max_latency[3];
char exp_rom_size[9];
int exp_rom_subscr;
#define WILDCARDS 0x01
#define EXTENSION 0x02
#define FILENAME 0x04
#define DIRECTORY 0x08
#define DRIVE 0x10
void
Log(char *msg, long a, long b, long c)
{
FILE *fp;
fp = fopen("logfile", "a");
fprintf(fp, "%s 0x%X 0x%X 0x%X\n", msg, a, b, c);
fclose(fp);
}
int
fnsplit(char *__path, char *__drive, char *__dir, char *__name, char *__ext)
{
char *p, *pfile, *npath;
int retval;
retval = 0;
if (!__path)
return(0);
if (!(npath = malloc(strlen(__path) + 1)))
return(0);
strcpy(npath, __path);
strbtrim(npath);
if (npath[1] == ':')
{
// Drive letter is present
retval |= DRIVE;
if (__drive)
{
strncpy(__drive, npath, 2);
__drive[2] = '\0';
}
// Delete drive from path
strshl(npath, 2);
strbtrim(npath);
}
else {
// No drive
if ( __drive != NULL )
{
__drive[0] = '\0';
}
}
// printf("fns:after drive strip, npath=%s\n", npath);
// Look for last back-slash
p = strrchr(npath, '\\');
if ( p != NULL )
{
// Path is present
pfile = ++p;
retval |= DIRECTORY;
if ( __dir != NULL )
{
strncpy(__dir, npath, MAXDIR);
p = strrchr(__dir, '\\');
if (p==npath) /* Then only single backslash */
{
*(p+1)='\0';
}
else {
*p = '\0';
}
}
}
else
{
// No path
pfile = npath;
if ( __dir != NULL )
{
__dir[0] = '\0';
}
}
p = strrchr(pfile, '.');
if ( p != NULL )
{
// Extension is present
retval |= EXTENSION;
if ( __ext != NULL )
{
// printf("\nIn cpy, p=*%s*\n",p);
strncpy(__ext, p, MAXEXT);
// printf("\nIn cpy, __ext=*%s*\n",__ext);
}
p = strrchr(npath, '.');
*p = '\0';
}
else
{
if ( __ext != NULL )
{
strncpy(__ext, "", MAXEXT);
}
}
if ( strlen(pfile) > 0 )
{
retval |= FILENAME;
if ( __name != NULL )
{
strncpy(__name, pfile, MAXFILE);
}
}
return(retval);
}
void
fnmerge(char *__path, const char *__drive, const char *__dir,
const char *__name, const char *__ext )
{
if (!__path)
return;
strcpy(__path, "");
if (__drive)
strcat(__path, __drive);
if (__dir)
strcat(__path, __dir);
if (__path && __path[strlen(__path)] != '\\')
strcat(__path, "\\");
if (__name)
strcat(__path, __name);
if (__ext && __ext[0] != '.')
strcat(__path, __ext);
if (__ext)
strcat(__path, __ext);
}
void
initialize_nvbuild(void)
{
/*
** Do any initialization that is specific to the exerciser
*/
struct nvram_program *nvp;
nvp = nvram_programs;
nvram_bsize = 0;
while (nvp->type != UNKNOWN_DEVICE)
{
nvram_bsize = nvp->size > nvram_bsize ? nvp->size : nvram_bsize;
nvp++;
}
if ((nvram_buf = malloc(nvram_bsize)) == NULL)
wperror("Memory Allocation Error!!!", YES);
}
void
nvbuild_menu(void)
{
int row;
wactiv(main_menu_window);
whide();
/*
** Setup different registers based upon device type
*/
if (current_device_type == S5920) {
default_nvram.base_address[0] = 0x10e8ff81L; // 32 DWORDS
default_nvram.device_id = 0x5920;
default_nvram.command_high.s20.reserved = 0;
default_nvram.command_high.s20.reserved2 = 0;
default_nvram.command_high.s20.write_fifo_mode = 1;
default_nvram.command_high.s20.retry_flush_enb = 1;
default_nvram.command_high.s20.PCI_target_latency_enb = 1;
} else {
default_nvram.base_address[0] = 0x10e8ffc1L;
default_nvram.device_id = 0x5933;
default_nvram.command_high.s33.reserved = 0;
default_nvram.command_high.s33.bus_master_add_on = 1;
default_nvram.command_high.s33.wrfifo_enable = 1;
default_nvram.command_high.s33.rdfifo_enable = 1;
default_nvram.command_high.s33.PCI_latency_timer_timeout_enable = 1;
}
cur_nvram = default_nvram;
nvram_loaded = CONF_SPACE_END;
/* push global help category onto help stack, so when */
/* [F1] is pressed while selection bar is on an item */
/* without help, the global help category will be used. */
whelpushc(H_GLOBAL);
/* define and process the main menu */
wmenubeg(8, 20, 22, 60, 0, menu_border_color, menu_window_color,
pre_nvbuild_menu);
row = 1;
wmenuitem(row, 10, "Load Memory Image", 'L', 1, 0, load , 0, H_LOAD);
row += 2;
wmenuitem(row, 10, "Save Memory Image", 'S', 2, 0, save , 0, H_SAVE);
row += 2;
wmenuitem(row, 10, "Edit Memory Image", 'E', 3, 0, edit, 0, H_EDIT);
row += 2;
wmenuitem(row, 10, "Write to Device", 'W', 4, 0, download, 0, H_WRITE);
row += 2 ;
wmenuitem(row, 10, "Display Memory Image", 'D', 5, 0, display_image,
0, H_DISPLAY_IMAGE);
row += 2;
wmenuitem(row, 10, "Exit Menu", 'x', 7, 0, NULL, 0, 0);
/*
** Disable "Write to Device" item if no valid PCI devices found
*/
if (n_pci_devs == 0)
wmenuidsab(4);
wmenuend(1, M_VERT, 0, 6, menu_border_color, menu_qsel_color,
menu_disabled_sel_color, menu_selection_color);
if (wmenuget() == -1 && _winfo.errno > W_ESCPRESS)
error_exit(1);
/* pop the global help category off of the stack, and into the void */
whelpopc();
wunhide(main_menu_window);
}
/*
** Called during the setup of the NVBUILD menu. It is called by
** wmenuget() right after the main menu's window is opened.
*/
STATIC void
pre_nvbuild_menu(void)
{
hidecur();
add_shadow();
wtitle("[ NVBUILD Menu ]",TCENTER,menu_border_color);
}
enum load_type {PCI_DEVICE_SELECT, FILE_SELECT, LD_EXIT_SELECT};
enum file_type {INTEL_HEX_TYPE, BINARY_TYPE, ERROR_TYPE};
/*
** Display menu to select where to load a NVRAM image from.
*/
STATIC void
load(void)
{
static enum load_type subscr = PCI_DEVICE_SELECT;
enum load_type prev_subscr;
enum file_type ftype;
long loaded;
char *fname;
fname = NULL;
wactiv(nvbuild_menu_window);
whide();
prev_subscr = subscr;
if (n_pci_devs > 0) {
whelpushc(H_LOAD_LOCATION);
if (!wopen(8, 26, 16, 53, 0, menu_border_color, menu_window_color))
error_exit(1);
wtitle("[ Select Load Location ]", TCENTER, menu_border_color);
add_shadow();
wmenubegc();
wmenuitem(1, 8, "PCI Device", 'D', PCI_DEVICE_SELECT, 0, NULL,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -