From patchwork Thu May 27 05:20:03 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: Improve i82830 MBI SMI Handler - take 2 Date: Thu, 27 May 2010 05:20:03 -0000 From: Joseph Smith X-Patchwork-Id: 1403 Message-Id: <4BFE0103.6000608@settoplinux.org> To: coreboot@coreboot.org Hello, Let's try this again. This way is as dynamic as possibly possible. This patch improves the i82830 MBI SMI Handler. It is now able to load Intel vbios VBT and Flexaim modules. Build and boot tested. Signed-off-by: Joseph Smith Index: src/include/cpu/x86/smm.h =================================================================== --- src/include/cpu/x86/smm.h (revision 5593) +++ src/include/cpu/x86/smm.h (working copy) @@ -258,6 +258,8 @@ void southbridge_smi_set_eos(void); +u8 find_name_len_size(unsigned int name_len_start, unsigned int name_len_end); + void __attribute__((weak)) cpu_smi_handler(unsigned int node, smm_state_save_area_t *state_save); void __attribute__((weak)) northbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save); void __attribute__((weak)) southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save); Index: src/northbridge/intel/i82830/i82830_smihandler.c =================================================================== --- src/northbridge/intel/i82830/i82830_smihandler.c (revision 5593) +++ src/northbridge/intel/i82830/i82830_smihandler.c (working copy) @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2010 coresystems GmbH + * Copyright (C) 2010 Joseph Smith * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -147,16 +148,28 @@ u32 buffer; } __attribute__((packed)) get_object_t; + + +u8 find_name_len_size(unsigned int name_len_start, unsigned int name_len_end) +{ + u8 name_len_size = 0; + name_len_end &= 0xfffffff0; + name_len_end |= 0x0000000f; + name_len_size = name_len_end - name_len_start; + + return name_len_size; +} + static void mbi_call(u8 subf, banner_id_t *banner_id) { #ifdef DEBUG_SMI_I82830 printk(BIOS_DEBUG, "MBI\n"); - printk(BIOS_DEBUG, "|- sub function %x\n", subf); - printk(BIOS_DEBUG, "|- banner id @ %x\n", (u32)banner_id); - printk(BIOS_DEBUG, "| |- mhid %x\n", banner_id->mhid); - printk(BIOS_DEBUG, "| |- function %x\n", banner_id->function); - printk(BIOS_DEBUG, "| |- return status %x\n", banner_id->retsts); - printk(BIOS_DEBUG, "| |- rfu %x\n", banner_id->rfu); + printk(BIOS_DEBUG, "|- sub function %02x\n", subf); + printk(BIOS_DEBUG, "|- banner id @ %08x\n", (u32)banner_id); + printk(BIOS_DEBUG, "| |- mhid %08x\n", banner_id->mhid); + printk(BIOS_DEBUG, "| |- function %08x\n", banner_id->function); + printk(BIOS_DEBUG, "| |- return status %08x\n", banner_id->retsts); + printk(BIOS_DEBUG, "| |- rfu %08x\n", banner_id->rfu); #endif switch(banner_id->function) { @@ -172,19 +185,20 @@ } case 0x0002: printk(BIOS_DEBUG, "|- MBI_Attach\n"); - printk(BIOS_DEBUG, "|  |- Not Implemented!\n"); + printk(BIOS_DEBUG, "| |- Not Implemented!\n"); break; case 0x0003: printk(BIOS_DEBUG, "|- MBI_Detach\n"); - printk(BIOS_DEBUG, "|  |- Not Implemented!\n"); + printk(BIOS_DEBUG, "| |- Not Implemented!\n"); break; case 0x0201: { obj_header_t *obj_header = (obj_header_t *)banner_id; mbi_header_t *mbi_header = NULL; printk(BIOS_DEBUG, "|- MBI_GetObjectHeader\n"); - printk(BIOS_DEBUG, "| |- objnum = %d\n", obj_header->objnum); + printk(BIOS_DEBUG, "| |- objnum = %08x\n", obj_header->objnum); - int i, count=0; + int i, count = 0; + u8 actual_name_len = 0; obj_header->banner.retsts = MSH_IF_NOT_FOUND; for (i=0; isize * 16) + sizeof(mbi_header) + mbi_header->name_len, 16); + actual_name_len = find_name_len_size((u32) &(mbi_header->name_len), (u32) &(mbi_header->name_len) + mbi_header->name_len); + len = ALIGN((mbi_header->size * 16) + sizeof(mbi_header) + actual_name_len, 16); if (obj_header->objnum == count) { #ifdef DEBUG_SMI_I82830 + printk(BIOS_DEBUG, "| |- header_id = %04x\n", mbi_header->header_id); + printk(BIOS_DEBUG, "| |- attributes = %04x\n", mbi_header->attributes); + printk(BIOS_DEBUG, "| |- size = %04x\n", (mbi_header->size * 16)); + printk(BIOS_DEBUG, "| |- name_len = %02x\n", mbi_header->name_len); + printk(BIOS_DEBUG, "| |- type = %08x\n", mbi_header->type); + printk(BIOS_DEBUG, "| |- header_ext = %08x\n", mbi_header->header_ext); + printk(BIOS_DEBUG, "| |- name[0] = %02x\n", mbi_header->name[0]); + if (mbi_header->name_len == 0xff) { printk(BIOS_DEBUG, "| |- corrupt.\n"); break; } #endif - int headerlen = ALIGN(sizeof(mbi_header) + mbi_header->name_len + 15, 16); + int headerlen = ALIGN(sizeof(mbi_header) + actual_name_len, 16); #ifdef DEBUG_SMI_I82830 - printk(BIOS_DEBUG, "| |- headerlen = %d\n", headerlen); + printk(BIOS_DEBUG, "| |- headerlen = %04x\n", headerlen); #endif memcpy(&obj_header->header, mbi_header, headerlen); obj_header->banner.retsts = MSH_OK; - printk(BIOS_DEBUG, "| |- MBI module '"); + printk(BIOS_DEBUG, "| |- MBI module '"); int j; for (j=0; j < mbi_header->name_len && mbi_header->name[j]; j++) printk(BIOS_DEBUG, "%c", mbi_header->name[j]); printk(BIOS_DEBUG, "' found.\n"); #ifdef DEBUG_SMI_I82830 - dump(banner_id, sizeof(obj_header_t) + 16); + dump((u8 *)banner_id, sizeof(obj_header_t) + actual_name_len); #endif break; } @@ -225,7 +248,7 @@ count++; } if (obj_header->banner.retsts == MSH_IF_NOT_FOUND) - printk(BIOS_DEBUG, "| |- MBI object #%d not found.\n", obj_header->objnum); + printk(BIOS_DEBUG, "| |- MBI object #%08x not found.\n", obj_header->objnum); break; } case 0x0203: { @@ -233,15 +256,16 @@ mbi_header_t *mbi_header = NULL; printk(BIOS_DEBUG, "|- MBI_GetObject\n"); #ifdef DEBUG_SMI_I82830 - printk(BIOS_DEBUG, "| |- handle = %016lx\n", getobj->handle); + printk(BIOS_DEBUG, "| |- handle = %Lx\n", getobj->handle); #endif - printk(BIOS_DEBUG, "| |- objnum = %d\n", getobj->objnum); - printk(BIOS_DEBUG, "| |- start = %x\n", getobj->start); - printk(BIOS_DEBUG, "| |- numbytes = %x\n", getobj->numbytes); - printk(BIOS_DEBUG, "| |- buflen = %x\n", getobj->buflen); - printk(BIOS_DEBUG, "| |- buffer = %x\n", getobj->buffer); + printk(BIOS_DEBUG, "| |- objnum = %08x\n", getobj->objnum); + printk(BIOS_DEBUG, "| |- start = %08x\n", getobj->start); + printk(BIOS_DEBUG, "| |- numbytes = %08x\n", getobj->numbytes); + printk(BIOS_DEBUG, "| |- buflen = %08x\n", getobj->buflen); + printk(BIOS_DEBUG, "| |- buffer = %08x\n", getobj->buffer); - int i, count=0; + int i, count = 0; + u8 actual_name_len = 0; getobj->banner.retsts = MSH_IF_NOT_FOUND; for (i=0; i< mbi_len;) { @@ -253,17 +277,25 @@ } mbi_header = (mbi_header_t *)&mbi[i]; - len = ALIGN((mbi_header->size * 16) + sizeof(mbi_header) + mbi_header->name_len, 16); + actual_name_len = find_name_len_size((u32) &(mbi_header->name_len), (u32) &(mbi_header->name_len) + mbi_header->name_len); + len = ALIGN((mbi_header->size * 16) + sizeof(mbi_header) + actual_name_len, 16); if (getobj->objnum == count) { - printk(BIOS_DEBUG, "| |- len = %x\n", len); + + int headerlen = ALIGN(sizeof(mbi_header) + actual_name_len, 16); + int objectlen = ALIGN((mbi_header->size * 16), 16); +#ifdef DEBUG_SMI_I82830 + printk(BIOS_DEBUG, "| |- headerlen = %04x\n", headerlen); +#endif + printk(BIOS_DEBUG, "| |- objectlen = %04x\n", objectlen); + memcpy((void *)(getobj->buffer + OBJ_OFFSET), - ((char *)mbi_header) + 0x20 , (len > getobj->buflen) ? getobj->buflen : len); + ((char *)mbi_header) + headerlen, (objectlen > getobj->buflen) ? getobj->buflen : objectlen); getobj->banner.retsts = MSH_OK; #ifdef DEBUG_SMI_I82830 - dump(banner_id, sizeof(*getobj)); - dump(getobj->buffer + OBJ_OFFSET, len); + dump((u8 *)banner_id, sizeof(*getobj)); + dump((u8 *)getobj->buffer + OBJ_OFFSET, objectlen); #endif break; } @@ -271,11 +303,11 @@ count++; } if (getobj->banner.retsts == MSH_IF_NOT_FOUND) - printk(BIOS_DEBUG, "MBI module %d not found.\n", getobj->objnum); + printk(BIOS_DEBUG, "MBI module %08x not found.\n", getobj->objnum); break; } default: - printk(BIOS_DEBUG, "|- function %x\n", banner_id->function); + printk(BIOS_DEBUG, "|- function %08x\n", banner_id->function); printk(BIOS_DEBUG, "| |- Unknown Function!\n"); break; }