Пример #1
0
/* Gets the ACPI 2.0 RSDP address */
static struct acpi_2_rsdp* getAddressOfAcpi20Table()
{
    /* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */
	
    void *acpi_addr = (void*)ACPI_RANGE_START;
    for(; acpi_addr <= (void*)ACPI_RANGE_END; acpi_addr += 16)
    {
        if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE)
        {
            uint8_t csum = checksum8(acpi_addr, 20);

            /* Only assume this is a 2.0 or better table if the revision is greater than 0
             * NOTE: ACPI 3.0 spec only seems to say that 1.0 tables have revision 1
             * and that the current revision is 2.. I am going to assume that rev > 0 is 2.0.
             */

            if(csum == 0 && (((struct acpi_2_rsdp*)acpi_addr)->Revision > 0))
            {
                uint8_t csum2 = checksum8(acpi_addr, sizeof(struct acpi_2_rsdp));
                if(csum2 == 0)
                    return acpi_addr;
            }
        }
    }
    return NULL;
}
Пример #2
0
static inline struct SMBEntryPoint * getAddressOfSmbiosTable()
{
	/* First see if we can even find the damn SMBIOS table
     * The logic here is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking
     * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").
     */
    void *smbios_addr = (void*)SMBIOS_RANGE_START;
    for(; (smbios_addr <= (void*)SMBIOS_RANGE_END) && (*(uint32_t*)smbios_addr != SMBIOS_ANCHOR_UINT32_LE); smbios_addr += 16)
        ;
    if(smbios_addr <= (void*)SMBIOS_RANGE_END)
    {
        /* NOTE: The specification does not specifically state what to do in the event of finding an
         * SMBIOS anchor on an invalid table.  It might be better to move this code into the for loop
         * so that searching can continue.
         */
        uint8_t csum = checksum8(smbios_addr, sizeof(struct SMBEntryPoint));
        /* The table already contains the checksum so we merely need to see if its checksum is now zero. */
        if(csum != 0)
        {
            printf("Found SMBIOS anchor but bad table checksum.  Assuming no SMBIOS.\n");
            sleep(5);
            smbios_addr = 0;
        }
    }
    else
    {
        /* If this happens, it's possible that a PnP BIOS call can be done to retrieve the address of the table.
         * The latest versions of the spec state that modern programs should not even attempt to do this. */
        printf("Unable to find SMBIOS table.\n");
        sleep(5);
        smbios_addr = 0;
    }
    return smbios_addr;
}
Пример #3
0
int birom16_write(struct birom16_state *state, uint16_t address, uint8_t *data, uint16_t size) {
	uint8_t buffer[4096];
	memset(buffer, 0x00, sizeof(buffer));

	serial_purge(state->serial);

	buffer[0] = BIROM16_CMD_WRITE;
	buffer[1] = (address & 0xFF00) >> 8;
	buffer[2] = (address & 0x00FF);
	buffer[3] = (size & 0xFF00) >> 8;
	buffer[4] = (size & 0x00FF);

	memcpy(buffer + 5, data, size);
	size += 5;

	uint8_t csum = checksum8(buffer, size);
	buffer[size++] = csum;

	LOGD("Writing %d bytes to address 0x%04X...", size, address);

	int rc = serial_write(state->serial, buffer, size);
	if (rc < size) {
		LOGE("Error writing to MCU.");
		return E_WRITE;
	}

	//Give MCU some breathing space.
	serial_drain(state->serial);

	//Expect single byte result of operation from MCU.
	uint8_t code = 0;
	uint8_t value = 0;
	double timeout = get_ticks() + 2;
	while (get_ticks() < timeout) {
		msleep(10);
		rc = serial_read(state->serial, &code, 1);
		if (rc < 0) {
			LOGE("Error reading from '%s'.", state->serial->address);
			return E_READ;
		}

		if (rc > 0) {
			if (code == BIROM16_RESP_ACK) {
				return E_NONE;
			}
		}
	}

	LOGE("Invalid MCU response: Code %d, value %d.", code, value);
	return E_MSGMALFORMED;
	//return E_NONE;
}
Пример #4
0
/* Gets the ACPI 1.0 RSDP address */
static struct acpi_2_rsdp* getAddressOfAcpiTable()
{
    /* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */
	
    void *acpi_addr = (void*)ACPI_RANGE_START;
    for(; acpi_addr <= (void*)ACPI_RANGE_END; acpi_addr += 16)
    {
        if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE)
        {
            uint8_t csum = checksum8(acpi_addr, 20);
            if(csum == 0)
            {
                // Only return the table if it is a true version 1.0 table (Revision 0)
                if(((struct acpi_2_rsdp*)acpi_addr)->Revision == 0)
                    return acpi_addr;
            }
        }
    }
    return NULL;
}
Пример #5
0
SMBEntryPoint *getAddressOfSmbiosTable(void)
{
	SMBEntryPoint	*smbios;
	/*
	 * The logic is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking
	 * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").
	 */
	smbios = (SMBEntryPoint*)SMBIOS_RANGE_START;
	while (smbios <= (SMBEntryPoint *)SMBIOS_RANGE_END) {
		if (COMPARE_DWORD(smbios->anchor, SMTAG)  &&
			COMPARE_DWORD(smbios->dmi.anchor, DMITAG) &&
			smbios->dmi.anchor[4] == DMITAG[4] &&
			checksum8(smbios, sizeof(SMBEntryPoint)) == 0) {
			return smbios;
	    }
		smbios = (SMBEntryPoint*)(((char*)smbios) + 16);
	}
	DBG("ERROR: Unable to find SMBIOS!\n");
	pause();
	return NULL;
}
Пример #6
0
void
smbios_real_run (struct SMBEntryPoint * origsmbios,
				 struct SMBEntryPoint * newsmbios)
{
	char *smbiostables=0;
	char *tablesptr, *newtablesptr;
	int origsmbiosnum=0;
	// bitmask of used handles
	uint8_t handles[8192]; 
	uint16_t nexthandle=0;
	int i, j;
	int tablespresent[256];
	BOOL do_auto=1;
	
	getBoolForKey("SMBIOSdefaults",&do_auto,&bootInfo->bootConfig);
	
	for (i=0;i<256;i++)
		tablespresent[i]=0;
	
	memset (handles,0,8192);
	newsmbios->dmi.tableAddress=(uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);
	if (origsmbios)
    {
		smbiostables=(char *) origsmbios->dmi.tableAddress;
		origsmbiosnum=origsmbios->dmi.structureCount;
    }
	tablesptr=smbiostables;
	newtablesptr=(char *) newsmbios->dmi.tableAddress;
	if (smbiostables)
		for (i=0;i<origsmbiosnum;i++)
		{
			struct smbios_table_header *oldcur
			=(struct smbios_table_header *) tablesptr,
			*newcur=(struct smbios_table_header *) newtablesptr;
			char *stringsptr;
			int nstrings=0;
			
			handles[(oldcur->handle)/8]|=1<<((oldcur->handle)%8);
			
			memcpy (newcur,oldcur, oldcur->length);
			
			tablesptr+=oldcur->length;
			stringsptr=tablesptr;
			newtablesptr+=oldcur->length;
			for (;tablesptr[0]!=0 || tablesptr[1]!=0;tablesptr++)
				if (tablesptr[0]==0)
					nstrings++;
			if (tablesptr!=stringsptr)
				nstrings++;
			tablesptr+=2;
			memcpy (newtablesptr,stringsptr,tablesptr-stringsptr);
			//point to next possible space for a string
			newtablesptr+=tablesptr-stringsptr-1;
			if (nstrings==0)
				newtablesptr--;
			for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
				 j++)
			{
				const char *str;
				int size;
				int num;
				char altname[40];
				sprintf (altname, "%s_%d",smbios_properties[j].name,
						 tablespresent[newcur->type]+1);				
				
				if (smbios_properties[j].table_type==newcur->type)
					switch (smbios_properties[j].value_type)
				{
					case SMSTRING:
						if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
							||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
						{
							memcpy (newtablesptr, str,size);
							newtablesptr[size]=0;
							newtablesptr+=size+1;
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
						}
						else if (do_auto && smbios_properties[j].auto_str)
						{
							str=smbios_properties[j].auto_str(smbios_properties[j].name,tablespresent[newcur->type]);
							size=strlen (str);
							memcpy (newtablesptr, str,size);
							newtablesptr[size]=0;
							newtablesptr+=size+1;
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
						}
						
						break;
						
					case SMOWORD:
						if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
							||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
						{
							int k=0, t=0, kk=0;
							const char *ptr=str;
							memset(((char*)newcur)+smbios_properties[j].offset, 0, 16);
							while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n'))
								ptr++;
							if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X'))
								ptr+=2;
							for (;ptr-str<size && *ptr && k<16;ptr++)
							{
								if (*ptr>='0' && *ptr<='9')
									(t=(t<<4)|(*ptr-'0')),kk++;
								if (*ptr>='a' && *ptr<='f')
									(t=(t<<4)|(*ptr-'a'+10)),kk++;
								if (*ptr>='A' && *ptr<='F')
									(t=(t<<4)|(*ptr-'A'+10)),kk++;
								if (kk==2)
								{
									*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset+k))=t;
									k++;
									kk=0;
									t=0;
								}
							}
						}
						break;
						
					case SMBYTE:
						if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
							||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
						else if (do_auto && smbios_properties[j].auto_int)
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))
							=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);							
						break;
						
					case SMWORD:
						if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
							||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
						else if (do_auto && smbios_properties[j].auto_int)
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))
							=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						break;
				}
			}
			if (nstrings==0)
			{
				newtablesptr[0]=0;
				newtablesptr++;
			}
			newtablesptr[0]=0;
			newtablesptr++;
			tablespresent[newcur->type]++;
		}
	for (i=0;i<sizeof (smbios_table_descriptions)
		 /sizeof(smbios_table_descriptions[0]);i++)
	{
		int numnec=-1;
		char buffer[40];
		sprintf (buffer, "SMtable%d", i);
		if (!getIntForKey(buffer,&numnec,&bootInfo->smbiosConfig))
			numnec=-1;
		if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc)
			numnec=smbios_table_descriptions[i].numfunc (smbios_table_descriptions[i].type);
		
		while (tablespresent[smbios_table_descriptions[i].type]<numnec)
		{
			struct smbios_table_header *newcur=(struct smbios_table_header *) newtablesptr;
			int nstrings=0;
			
			memset (newcur,0, smbios_table_descriptions[i].len);
			while (handles[(nexthandle)/8]&(1<<((nexthandle)%8)))
				nexthandle++;
			newcur->handle=nexthandle;
			handles[nexthandle/8]|=1<<(nexthandle%8);
			newcur->type=smbios_table_descriptions[i].type;
			newcur->length=smbios_table_descriptions[i].len;
			newtablesptr+=smbios_table_descriptions[i].len;
			for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
				 j++)
			{
				const char *str;
				int size;
				int num;
				char altname[40];
				sprintf (altname, "%s_%d",smbios_properties[j].name,
						 tablespresent[newcur->type]+1);				
				
				if (smbios_properties[j].table_type==newcur->type)
					switch (smbios_properties[j].value_type)
				{
					case SMSTRING:
						if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
							||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
						{
							memcpy (newtablesptr, str,size);
							newtablesptr[size]=0;
							newtablesptr+=size+1;
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
						}
						else if (do_auto && smbios_properties[j].auto_str)
						{
							str=smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
							size=strlen (str);
							memcpy (newtablesptr, str,size);
							newtablesptr[size]=0;
							newtablesptr+=size+1;
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
						}						
						break;
						
					case SMOWORD:
						if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
							||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
						{
							int k=0, t=0, kk=0;
							const char *ptr=str;
							memset(((char*)newcur)+smbios_properties[j].offset, 0, 16);
							while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n'))
								ptr++;
							if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X'))
								ptr+=2;
							for (;ptr-str<size && *ptr && k<16;ptr++)
							{
								if (*ptr>='0' && *ptr<='9')
									(t=(t<<4)|(*ptr-'0')),kk++;
								if (*ptr>='a' && *ptr<='f')
									(t=(t<<4)|(*ptr-'a'+10)),kk++;
								if (*ptr>='A' && *ptr<='F')
									(t=(t<<4)|(*ptr-'A'+10)),kk++;
								if (kk==2)
								{
									*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset+k))=t;
									k++;
									kk=0;
									t=0;
								}
							}
						}
						break;
						
					case SMBYTE:
						if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
							||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
						else if (do_auto && smbios_properties[j].auto_int)
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))
							=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						break;
						
					case SMWORD:
						if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
							||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
						else if (do_auto && smbios_properties[j].auto_int)
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))
							=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						break;
				}
			}
			if (nstrings==0)
			{
				newtablesptr[0]=0;
				newtablesptr++;
			}
			newtablesptr[0]=0;
			newtablesptr++;
			tablespresent[smbios_table_descriptions[i].type]++;
		}
	}
	newsmbios->dmi.checksum=0;
	newsmbios->dmi.checksum=256-checksum8 (&newsmbios->dmi,sizeof (newsmbios->dmi));
	newsmbios->checksum=0;
	newsmbios->checksum=256-checksum8 (newsmbios,sizeof (*newsmbios));
	verbose("Patched DMI Table.\n");
}
Пример #7
0
/** From the origsmbios detected by getAddressOfSmbiosTable() to newsmbios whose entrypoint 
 * struct has been created by smbios_dry_run, update each table struct content of new smbios
 * int the new allocated table address of size newsmbios->tablelength.
 */
static void smbios_real_run(struct SMBEntryPoint * origsmbios, struct SMBEntryPoint * newsmbios)
{
	char *smbiostables;
	char *tablesptr, *newtablesptr;
	int origsmbiosnum;
	// bitmask of used handles
	uint8_t handles[8192]; 
	uint16_t nexthandle=0;
	int i, j;
	int tablespresent[256];
	bool do_auto=true;
        
        extern void dumpPhysAddr(const char * title, void * a, int len);

	bzero(tablespresent, sizeof(tablespresent));
	bzero(handles, sizeof(handles));

	getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);
	
	newsmbios->dmi.tableAddress = (uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);
	if (origsmbios) {
		smbiostables = (char *)origsmbios->dmi.tableAddress;
		origsmbiosnum = origsmbios->dmi.structureCount;
	} else {
		smbiostables = NULL;
		origsmbiosnum = 0;
	}
	tablesptr = smbiostables;
	newtablesptr = (char *)newsmbios->dmi.tableAddress;

        // if old smbios exists then update new smbios  with old smbios original content first
	if (smbiostables) {
		for (i=0; i<origsmbiosnum; i++) {
			struct smbios_table_header	*oldcur = (struct smbios_table_header *) tablesptr;
			struct smbios_table_header	*newcur = (struct smbios_table_header *) newtablesptr;
			char				*stringsptr;
			int				nstrings = 0;

			handles[(oldcur->handle) / 8] |= 1 << ((oldcur->handle) % 8);

                        // copy table length from old table to new table but not the old strings
			memcpy(newcur,oldcur, oldcur->length);

			tablesptr += oldcur->length;
			stringsptr = tablesptr;
			newtablesptr += oldcur->length;

                        // calculate the number of strings in the old content
			for (;tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++) {
				if (tablesptr[0] == 0) {
					nstrings++;
				}
			}
			if (tablesptr != stringsptr) {
				nstrings++;
			}
			tablesptr += 2;

                        // copy the old strings to new table
			memcpy(newtablesptr, stringsptr, tablesptr-stringsptr);

 			// point to next possible space for a string (deducting the second 0 char at the end)
			newtablesptr += tablesptr - stringsptr - 1;
                            if (nstrings == 0) { // if no string was found rewind to the first 0 char of the 0,0 terminator
				newtablesptr--;
			}

                        // now for each property in the table update the overrides if any (auto or user)
			for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
				const char	*str;
				int		size;
				int		num;
				char		altname[40];

				sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
				if (smbios_properties[j].table_type == newcur->type) {
					switch (smbios_properties[j].value_type) {
					case SMSTRING:
						if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
						    getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
						{
							memcpy(newtablesptr, str, size);
							newtablesptr[size] = 0;
							newtablesptr += size + 1;
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
						} else if (do_auto && smbios_properties[j].auto_str) {
							str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
							size = strlen(str);
							memcpy(newtablesptr, str, size);
							newtablesptr[size] = 0;
							newtablesptr += size + 1;
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
						}
						break;

					case SMOWORD:
						if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
						    getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
						{
							int		k=0, t=0, kk=0;
							const char	*ptr = str;
							memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
							while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
								ptr++;
							}
							if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
								ptr += 2;
							}
							for (;ptr-str<size && *ptr && k<16;ptr++) {
								if (*ptr>='0' && *ptr<='9') {
									(t=(t<<4)|(*ptr-'0')),kk++;
								}
								if (*ptr>='a' && *ptr<='f') {
									(t=(t<<4)|(*ptr-'a'+10)),kk++;
								}
								if (*ptr>='A' && *ptr<='F') {
									(t=(t<<4)|(*ptr-'A'+10)),kk++;
								}
								if (kk == 2) {
									*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
									k++;
									kk = 0;
									t = 0;
								}
							}
						}
						break;

					case SMBYTE:
						if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
						    getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
						{
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
						} else if (do_auto && smbios_properties[j].auto_int) {
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);							
						}
						break;

					case SMWORD:
						if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
						    getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
						{
							*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
						} else if (do_auto && smbios_properties[j].auto_int) {
							*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						}
						break;
					}
				}
			}
			if (nstrings == 0) {
				newtablesptr[0] = 0;
				newtablesptr++;
			}
			newtablesptr[0] = 0;
			newtablesptr++;
			tablespresent[newcur->type]++;
		}
	}

        // for each eventual complementary table not present in the original smbios, do the overrides
	for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
		int	numnec = -1;
		char	buffer[40];

		sprintf(buffer, "SMtable%d", i);
		if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
			numnec = -1;
		}
		if (numnec == -1 && do_auto && smbios_table_descriptions[i].numfunc) {
			numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
		}
		while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
			struct smbios_table_header	*newcur = (struct smbios_table_header *) newtablesptr;
			int				nstrings = 0;

			memset(newcur,0, smbios_table_descriptions[i].len);
			while (handles[(nexthandle)/8] & (1 << ((nexthandle) % 8))) {
				nexthandle++;
			}
			newcur->handle = nexthandle;
			handles[nexthandle / 8] |= 1 << (nexthandle % 8);
			newcur->type = smbios_table_descriptions[i].type;
			newcur->length = smbios_table_descriptions[i].len;
			newtablesptr += smbios_table_descriptions[i].len;
			for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
				const char	*str;
				int		size;
				int		num;
				char		altname[40];

				sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
				if (smbios_properties[j].table_type == newcur->type) {
					switch (smbios_properties[j].value_type) {
					case SMSTRING:
						if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
						    getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
						{
							memcpy(newtablesptr, str, size);
							newtablesptr[size] = 0;
							newtablesptr += size + 1;
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
						} else if (do_auto && smbios_properties[j].auto_str) {
							str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
							size = strlen(str);
							memcpy(newtablesptr, str, size);
							newtablesptr[size] = 0;
							newtablesptr += size + 1;
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
						}
						break;

					case SMOWORD:
						if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
						    getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
						{
							int		k=0, t=0, kk=0;
							const char	*ptr = str;

							memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
							while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
								ptr++;
							}
							if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
								ptr += 2;
							}
							for (;ptr-str<size && *ptr && k<16;ptr++) {
								if (*ptr>='0' && *ptr<='9') {
									(t=(t<<4)|(*ptr-'0')),kk++;
								}
								if (*ptr>='a' && *ptr<='f') {
									(t=(t<<4)|(*ptr-'a'+10)),kk++;
								}
								if (*ptr>='A' && *ptr<='F') {
									(t=(t<<4)|(*ptr-'A'+10)),kk++;
								}
								if (kk == 2) {
									*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
									k++;
									kk = 0;
									t = 0;
								}
							}
						}
						break;
						
					case SMBYTE:
						if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
						    getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
						{
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
						} else if (do_auto && smbios_properties[j].auto_int) {
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						}
						break;
						
					case SMWORD:
						if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
						    getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
						{
							*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
						} else if (do_auto && smbios_properties[j].auto_int) {
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						}
						break;
					}
				}
			}
			if (nstrings == 0) {
				newtablesptr[0] = 0;
				newtablesptr++;
			}
			newtablesptr[0] = 0;
			newtablesptr++;
			tablespresent[smbios_table_descriptions[i].type]++;
		}
	}

        // calculate new checksums
	newsmbios->dmi.checksum = 0;
	newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi));
	newsmbios->checksum = 0;
	newsmbios->checksum = 256 - checksum8(newsmbios, sizeof(*newsmbios));
	verbose("Patched DMI Table\n");
}
Пример #8
0
bool setOemProperties(IOService *provider)
{
    SMBEntryPoint* eps = 0;
	IOMemoryDescriptor* dmiMemory = 0;
	IOItemCount dmiStructureCount = 0;
    
  	UInt8* biosAddress = NULL;	
    
    IOMemoryDescriptor * biosMemory = 0;
    IOMemoryMap * biosMap = 0;
    
    biosMemory = IOMemoryDescriptor::withPhysicalAddress( 0xf0000,0xfffff-0xf0000+1,kIODirectionOutIn);
    
    if(biosMemory)
    {
        biosMap = biosMemory->map();
        
        if(biosMap)
        {
            biosAddress = (UInt8 *) biosMap->getVirtualAddress();
        }
    }
    
    
	// Search 0x0f0000 - 0x0fffff for SMBIOS Ptr
	if(biosAddress)
        for (UInt32 Address = 0; Address < biosMap->getLength(); Address += 0x10) {
            if (*(UInt32 *)(biosAddress + Address) == SMBIOS_PTR) {
                eps = (SMBEntryPoint *)(biosAddress + Address);
                continue;
            }
        }
    
    if(eps)
        if (memcmp(eps->anchor, "_SM_", 4) == 0)
        {
            UInt8 csum;
            
            csum = checksum8(eps, sizeof(SMBEntryPoint));
            
            /*HWSensorsDebugLog("DMI checksum       = 0x%x", csum);
             HWSensorsDebugLog("DMI tableLength    = %d",
             eps->dmi.tableLength);
             HWSensorsDebugLog("DMI tableAddress   = 0x%x",
             (uint32_t) eps->dmi.tableAddress);
             HWSensorsDebugLog("DMI structureCount = %d",
             eps->dmi.structureCount);
             HWSensorsDebugLog("DMI bcdRevision    = %x",
             eps->dmi.bcdRevision);*/
            
            if (csum == 0 && eps->dmi.tableLength &&
                eps->dmi.structureCount)
            {
                dmiStructureCount = eps->dmi.structureCount;
                dmiMemory = IOMemoryDescriptor::withPhysicalAddress(
                                                                    eps->dmi.tableAddress, eps->dmi.tableLength,
                                                                    kIODirectionOutIn );
            }
            /*else
             {
             HWSensorsDebugLog("no DMI structure found");
             }*/
        }
    
    if (biosMap)
        OSSafeReleaseNULL(biosMap);
    
    if(biosMemory)
        OSSafeReleaseNULL(biosMemory);
    
    if ( dmiMemory )
    {
        if (IOMemoryMap *fDMIMemoryMap = dmiMemory->map())        {
            decodeSMBIOSTable(provider, (void *) fDMIMemoryMap->getVirtualAddress(), fDMIMemoryMap->getLength(), dmiStructureCount );
        
            OSSafeReleaseNULL(fDMIMemoryMap);
        }
        
        OSSafeReleaseNULL(dmiMemory);
    }
    
    return true;
}
Пример #9
0
void setupSMBIOS(void)
{
    _SMBIOS_DEBUG_DUMP("Entering setupSMBIOS(static)\n");

    // Allocate 1 page of kernel memory (sufficient for a stripped SMBIOS table).
    void * kernelMemory = (void *)AllocateKernelMemory(4096);

    // Setup a new Entry Point Structure at the beginning of the newly allocated memory page.
    struct SMBEntryPoint * newEPS = (struct SMBEntryPoint *) kernelMemory;

    // Include additional/conditional code snippet.
#include "smbios/static_data.h"

    newEPS->anchor[0]			= 0x5f;		// _
    newEPS->anchor[1]			= 0x53;		// S
    newEPS->anchor[2]			= 0x4d;		// M
    newEPS->anchor[3]			= 0x5f;		// _
    newEPS->checksum			= 0;
    newEPS->entryPointLength	= 0x1f;		// sizeof(* newEPS)
    newEPS->majorVersion		= 2;
    newEPS->minorVersion		= 4;
    newEPS->maxStructureSize	= STATIC_SMBIOS_SM_MAX_STRUCTURE_SIZE;	// Defined in RevoBoot/i386/config/SMBIOS/data-template.h
    newEPS->entryPointRevision	= 0;

    newEPS->formattedArea[0]	= 0;
    newEPS->formattedArea[1]	= 0;
    newEPS->formattedArea[2]	= 0;
    newEPS->formattedArea[3]	= 0;
    newEPS->formattedArea[4]	= 0;

    newEPS->dmi.anchor[0]		= 0x5f;		// _
    newEPS->dmi.anchor[1]		= 0x44;		// D
    newEPS->dmi.anchor[2]		= 0x4d;		// M
    newEPS->dmi.anchor[3]		= 0x49;		// I
    newEPS->dmi.anchor[4]		= 0x5f;		// _
    newEPS->dmi.checksum		= 0;
    newEPS->dmi.tableLength		= tableLength;
    newEPS->dmi.tableAddress	= (uint32_t) (kernelMemory + sizeof(struct SMBEntryPoint));
    newEPS->dmi.bcdRevision		= 0x24;
    newEPS->dmi.structureCount	= STATIC_SMBIOS_DMI_STRUCTURE_COUNT;	// Defined in RevoBoot/i386/config/SMBIOS/[data-template/MacModelNN].h

    // Safety measure to protect people from doing something that breaks the boot process.
    // #define FORCED_CHECK ((STATIC_SMBIOS_DMI_STRUCTURE_COUNT == 0) || (SET_MAX_STRUCTURE_LENGTH && (STATIC_SMBIOS_SM_MAX_STRUCTURE_SIZE == 0)))
#define FORCED_CHECK	((STATIC_SMBIOS_DMI_STRUCTURE_COUNT == 0) || SET_MAX_STRUCTURE_LENGTH)

#if (LOAD_MODEL_SPECIFIC_SMBIOS_DATA || FORCED_CHECK)
    /*
     * Get number of SMBIOS table structures from the loaded model specific SMBIOS data, or
     * when we have 0 values in: RevoBoot/i386/config/SMBIOS/[data-template/MacModelNN].bin
     */
    if ((fileSize > 0) || FORCED_CHECK)
    {
        UInt16 structureCount = 0;

        char * structurePtr = (char *)newEPS->dmi.tableAddress;
        char * structureEnd = (structurePtr + newEPS->dmi.tableLength);

        while (structureEnd > (structurePtr + sizeof(SMBStructHeader)))
        {
            struct SMBStructHeader * header = (struct SMBStructHeader *) structurePtr;

#if SET_MAX_STRUCTURE_LENGTH
            char * stringsPtr = structurePtr;
#if DEBUG_SMBIOS
            SMBByte currentStructureType = header->type;
#endif
#endif
            // Skip the formatted area of the structure.
            structurePtr += header->length;

            /*
             * Skip the unformatted structure area at the end (strings).
             * Using word comparison instead of checking two bytes (thanks to Kabyl).
             */
            for (; ((uint16_t *)structurePtr)[0] != 0; structurePtr++);

            // Adjust pointer after locating the double 0 terminator.
            structurePtr += 2;

            // Update structure counter.
            structureCount++;

            _SMBIOS_DEBUG_DUMP("structureCount: %d\n", structureCount);

#if SET_MAX_STRUCTURE_LENGTH
            UInt16 maxStructureSize = (structurePtr - stringsPtr);

            if (newEPS->maxStructureSize < maxStructureSize)
            {
                newEPS->maxStructureSize = maxStructureSize;
            }

            _SMBIOS_DEBUG_DUMP("Structure (%d) length: %3d bytes.\n", currentStructureType, maxStructureSize);
            _SMBIOS_DEBUG_SLEEP(1);
#endif	// #if SET_MAX_STRUCTURE_LENGTH
        }
        // Uodate number of structures (boot hang without the correct value).
        newEPS->dmi.structureCount = structureCount;
    }
#endif	// #if (LOAD_MODEL_SPECIFIC_SMBIOS_DATA || FORCED_CHECK)
    /*
     * newEPS->dmi.tableLength represents the length of the static data, or the size
     * of the model specific SMBIOS data file from: /Extra/SMBIOS/MacModelNN.bin
     */
    _SMBIOS_DEBUG_DUMP("newEPS->dmi.structureCount: %d\nnewEPS.dmi.tableLength: %d\n", newEPS->dmi.structureCount, newEPS->dmi.tableLength);

    // Take care of possible checksum errors
    newEPS->dmi.checksum		= 256 - checksum8(&newEPS->dmi, sizeof(newEPS->dmi));
    newEPS->checksum			= 256 - checksum8(newEPS, sizeof(* newEPS));

    // Used to update the EFI Configuration Table (in efi.c) which is
    // what AppleSMBIOS.kext reads to setup the SMBIOS table for OS X.
    gPlatform.SMBIOS.BaseAddress = (uint32_t) newEPS;

    _SMBIOS_DEBUG_DUMP("New SMBIOS replacement setup.\n");
    _SMBIOS_DEBUG_SLEEP(5);
}