⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmi.c

📁 version control, version control
💻 C
字号:
/* dmi.c  using the DMI from SMBIOS to read information about the hardware's * memory devices capabilities and where they are mapped into the address space * * Copyright (c) Joachim Deguara, AMD 2006 * * Release under the GPL version 2 * ---------------------------------------------------- * Memtest86+ V1.70 - Added compliance with SMBIOS Spec V2.5 *									- Support for FB-DIMM */#include "test.h"#include <stdint.h>#define DMI_SEARCH_START  0x0000F000#define DMI_SEARCH_LENGTH 0x000F0FFF#define MAX_DMI_MEMDEVS 32#define round_up(x,y) (((x) + (y) - 1) & ~((y)-1))#define round_down(x,y) ((x) & ~((y)-1))struct dmi_eps {	uint8_t  anchor[4];	int8_t   checksum;	uint8_t  length;	uint8_t  majorversion;	uint8_t  minorversion;	uint16_t maxstructsize;	uint8_t  revision;	uint8_t  pad[5];	uint8_t  intanchor[5];	int8_t   intchecksum;	uint16_t tablelength;	uint32_t tableaddress;	uint16_t numstructs;	uint8_t  SMBIOSrev;} __attribute__((packed));struct tstruct_header{	uint8_t  type;	uint8_t  length;	uint16_t handle;} __attribute__((packed));struct mem_dev {	struct tstruct_header header;	uint16_t pma_handle;	uint16_t err_handle;	uint16_t tot_width;	uint16_t dat_width;	uint16_t size;	uint8_t  form;	uint8_t  set;	uint8_t  dev_locator;	uint8_t  bank_locator;	uint8_t  type;	uint16_t typedetail;	uint16_t speed;	uint8_t  manufacturer;	uint8_t  serialnum;	uint8_t  asset;	uint8_t  partnum;} __attribute__((packed));struct md_map{	struct tstruct_header header;	uint32_t start;	uint32_t end;	uint16_t md_handle;	uint16_t mama_handle;	uint8_t  row_pos;	uint8_t  interl_pos;	uint8_t  interl_depth;} __attribute__((packed));struct pma{	struct tstruct_header header;	uint8_t  location;	uint8_t  use;	uint8_t  ecc;	uint32_t capacity;	uint16_t errhandle;	uint16_t numdevs;} __attribute__((packed));static char *form_factors[] = {	"?",	"Other", "Unknown", "SIMM", "SIP", "Chip", "DIP", "ZIP",	"Proprietary Card", "DIMM", "TSOP", "Row of chips", "RIMM",	"SODIMM", "SRIMM", "FB-DIMM"};static char *memory_types[] = {	"?",	"Other", "Unknown", "DRAM", "EDRAM", "VRAM", "SRAM", "RAM",	"ROM", "FLASH", "EEPROM", "FEPROM", "EPROM", "CDRAM", "3DRAM",	"SDRAM", "SGRAM", "RDRAM", "DDR", "DDR2", "DDR2 FB"};struct mem_dev * mem_devs[MAX_DMI_MEMDEVS];int mem_devs_count=0;struct md_map * md_maps[MAX_DMI_MEMDEVS];int md_maps_count=0;int bad_devs[MAX_DMI_MEMDEVS];int dmi_initialized=0;int strlen(char * string){	int i=0;	while(*string++){i++;};	return i;}char * get_tstruct_string(struct tstruct_header *header, int n){	if(n<1)		return 0;	char * a = (char *)header + header->length;	n--;	do{		if (!*a)			n--;		if (!n && *a)			return a;		a++;	}while (!(*a==0 && *(a-1)==0));	return 0;}int open_dmi(void){	char *dmi, *dmi_search_start, *dmi_start;	int found=0;	struct dmi_eps *eps;	char *table_start;	int tstruct_count=0;	dmi_search_start = (char *)DMI_SEARCH_START;	//find anchor	for(dmi = dmi_search_start; dmi < dmi_search_start + 0xf0000; dmi +=16){		if( *dmi == '_' &&		    *(dmi+1) == 'S' &&		    *(dmi+2) == 'M' &&		    *(dmi+3) == '_'){			found =1;			break;		}	}	if (!found) {		return -1;	}	dmi_start=dmi;	eps=(struct dmi_eps *)dmi;	//check checksum	int8_t checksum=0;	for (; dmi < dmi_start + eps->length; dmi++)		checksum += *dmi;	if (checksum){		return -1;	}	//we need at least revision 2.1 of SMBIOS	if ( eps->majorversion < 2 &&	     eps->minorversion < 1){	    return -1;	}	table_start=(char *)eps->tableaddress;	dmi=table_start;//look at all structs	while(dmi < table_start + eps->tablelength){		struct tstruct_header *header = (struct tstruct_header *)dmi;		if (header->type == 17)			mem_devs[mem_devs_count++]=(struct mem_dev *)dmi;		if (header->type == 20)			md_maps[md_maps_count++]=(struct md_map *)dmi;		dmi+=header->length;		while( ! (*dmi == 0  && *(dmi+1) == 0 ) )			dmi++;		dmi+=2;		if (++tstruct_count > eps->numstructs)			return -1;	}	return 0;}void init_dmi(void){	int i;	for(i=0; i < MAX_DMI_MEMDEVS; i++)		bad_devs[i]=0;	open_dmi();	dmi_initialized=1;}void print_dmi_info(void){	int i,j,page;	char * string=0;	if(!dmi_initialized)		init_dmi();	if (mem_devs_count == 0){		cprint(POP2_Y+1, POP2_X+2, "No valid DMI Memory Devices info found");		while (get_key() == 0);		return;	}	for(page=1; page <= 1 + (mem_devs_count-1)/8; page++){		pop2clear();		cprint(POP2_Y+1, POP2_X+2, "DMI Memory Device Info  (page ");		itoa(string,page);		cprint(POP2_Y+1, POP2_X+32, string);		cprint(POP2_Y+1, POP2_X+33, "/");		itoa(string,1 + (mem_devs_count-1)/8);		cprint(POP2_Y+1, POP2_X+34, string);		cprint(POP2_Y+1, POP2_X+35, ")");		cprint(POP2_Y+3, POP2_X+4, "Location         Size(MB) Speed(MHz) Type   Form");		cprint(POP2_Y+4, POP2_X+4, "--------------------------------------------------------------");		for(i=8*(page-1); i<mem_devs_count && i<8*page; i++){			int size_in_mb;			int yof;			yof=POP2_Y+5+2*(i-8*(page-1));			cprint(yof, POP2_X+4, get_tstruct_string(&(mem_devs[i]->header), mem_devs[i]->dev_locator));			if (mem_devs[i]->size == 0){				cprint(yof, POP2_X+4+18, "Empty");			}else if (mem_devs[i]->size == 0xFFFF){				cprint(yof, POP2_X+4+18, "Unknown");			}else{				size_in_mb = 0xEFFF & mem_devs[i]->size;				if (mem_devs[i]->size & 0x8000)					size_in_mb = size_in_mb<<10;				itoa(string, size_in_mb);				cprint(yof, POP2_X+4+18, string);			}						//this is the only field that needs to be SMBIOS 2.3+ 			if ( mem_devs[i]->speed && 			     mem_devs[i]->header.length > 21){				itoa(string, mem_devs[i]->speed);				cprint(yof, POP2_X+4+27, string);			}else{				cprint(yof, POP2_X+4+27, "Unknown");			}			cprint(yof, POP2_X+4+37, memory_types[mem_devs[i]->type]);			cprint(yof, POP2_X+4+44, form_factors[mem_devs[i]->form]);			//print mappings			int mapped=0,of=0;			cprint(yof+1, POP2_X+6,"mapped to: ");			for(j=0; j<md_maps_count; j++){				if (mem_devs[i]->header.handle != md_maps[j]->md_handle)					continue;				if (mapped++){					cprint(yof+1, POP2_X+17+of, ",");					of++;				}				hprint3(yof+1, POP2_X+17+of, md_maps[j]->start<<10, 12);				of += 12;				cprint(yof+1, POP2_X+17+of, "-");				of++;				hprint3(yof+1, POP2_X+17+of, md_maps[j]->end<<10, 12);				of += 12;			}			if (!mapped)				cprint(yof+1, POP2_X+17, "No mapping (unused device)");		}		wait_keyup();		while (get_key() == 0);	}}	//return 1 if the list of bad memory devices changes, 0 otherwise, -1 if no mappedint add_dmi_err(ulong adr){	int i,j,found=-1;		if(!dmi_initialized)		init_dmi();		for(i=0; i < md_maps_count; i++){		if ( adr < (md_maps[i]->start<<10) ||		     adr > (md_maps[i]->end<<10) )			continue;		//matching map found, now check find corresponding dev		for(j=0; j < mem_devs_count; j++){			if (mem_devs[j]->header.handle != md_maps[i]->md_handle)				continue;			if (bad_devs[j]){				found=0;			}else{				found = bad_devs[j] = 1;			}		}	}		return found;}	void print_dmi_err(void){	int i,count,of;	char *string;		scroll();		cprint(v->msg_line, 0,"Bad Memory Devices: ");	of=20;	for ( i=count=0; i < MAX_DMI_MEMDEVS; i++){		if (!bad_devs[i])			continue;		struct mem_dev *md = mem_devs[i];		if(count++){			cprint(v->msg_line, of, ", ");			of+=2;		}		string=get_tstruct_string((struct tstruct_header *)md,md->dev_locator);		if (strlen(string) + of > 80){			scroll();			of=7;		}		cprint(v->msg_line, of, string);		of += strlen(string);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -