Index: branches/andyvand/i386/libsaio/bootstruct.h =================================================================== --- branches/andyvand/i386/libsaio/bootstruct.h (revision 140) +++ branches/andyvand/i386/libsaio/bootstruct.h (revision 141) @@ -125,11 +125,11 @@ char config[CONFIG_SIZE]; config_file_t bootConfig; // boot.plist - config_file_t overrideConfig; // additional boot.plist which can override bootConfig keys config_file_t themeConfig; // theme.plist config_file_t smbiosConfig; // smbios.plist config_file_t helperConfig; // boot helper partition's boot.plist config_file_t ramdiskConfig; // RAMDisk.plist + config_file_t pciConfig; // pci.plist } PrivateBootInfo_t; extern PrivateBootInfo_t *bootInfo; Index: branches/andyvand/i386/libsaio/device_inject.c =================================================================== --- branches/andyvand/i386/libsaio/device_inject.c (revision 140) +++ branches/andyvand/i386/libsaio/device_inject.c (revision 141) @@ -29,6 +29,16 @@ uint8_t *stringdata = 0; uint32_t stringlength = 0; +typedef struct DeviceEntryStruct DeviceEntry_t; + +struct DeviceEntryStruct { + DeviceEntry_t* next; + const char* path; + struct DevPropDevice* device; +}; + +DeviceEntry_t* TheDeviceRegistry = NULL; + char *efi_inject_get_devprop_string(uint32_t *len) { if(string) { @@ -86,6 +96,7 @@ struct DevPropDevice *device; const char pciroot_string[] = "PciRoot(0x"; const char pci_device_string[] = "Pci(0x"; + DeviceEntry_t* newDeviceEntry; if (string == NULL || path == NULL) { return NULL; @@ -177,6 +188,13 @@ string->entries[string->numentries++] = (struct DevPropDevice*)malloc(sizeof(device)); string->entries[string->numentries-1] = device; + // Register the device to the device entries + newDeviceEntry = malloc(sizeof(DeviceEntry_t)); + newDeviceEntry->next = TheDeviceRegistry; + TheDeviceRegistry = newDeviceEntry; + newDeviceEntry->path = strdup(path); + newDeviceEntry->device = device; + return device; } @@ -358,3 +376,15 @@ } } } + + +struct DevPropDevice *devprop_find_device(char *path) +{ + DeviceEntry_t* entry; + + for (entry = TheDeviceRegistry; entry; entry = entry->next) + if (strcmp(entry->path, path) == 0) + return entry->device; + return NULL; +} + Index: branches/andyvand/i386/libsaio/device_inject.h =================================================================== --- branches/andyvand/i386/libsaio/device_inject.h (revision 140) +++ branches/andyvand/i386/libsaio/device_inject.h (revision 141) @@ -70,5 +70,6 @@ int devprop_add_value(struct DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len); char *devprop_generate_string(struct DevPropString *string); void devprop_free_string(struct DevPropString *string); +struct DevPropDevice *devprop_find_device(char *path); #endif /* !__LIBSAIO_DEVICE_INJECT_H */ Index: branches/andyvand/i386/libsaio/pci_setup.c =================================================================== --- branches/andyvand/i386/libsaio/pci_setup.c (revision 140) +++ branches/andyvand/i386/libsaio/pci_setup.c (revision 141) @@ -5,6 +5,7 @@ #include "nvidia.h" #include "ati.h" #include "gma.h" +#include "device_inject.h" extern void set_eth_builtin(pci_dt_t *eth_dev); extern int ehci_acquire(pci_dt_t *pci_dev); @@ -12,11 +13,51 @@ extern int uhci_reset(pci_dt_t *pci_dev); extern void force_enable_hpet(pci_dt_t *lpc_dev); +static int PciToEfiOverride(const char * propKey, + unsigned long numbers[], + unsigned long maxArrayCount ) +{ + char * propStr; + unsigned long count = 0; + + propStr = newStringForKey( (char *) propKey , &bootInfo->pciConfig ); + if ( propStr ) + { + char * delimiter = propStr; + char * p = propStr; + + while ( count < maxArrayCount && *p != '\0' ) + { + unsigned long val = strtoul( p, &delimiter, 16 ); + if ( p != delimiter ) + { + numbers[count++] = val; + p = delimiter; + } + while ( ( *p != '\0' ) && !isdigit(*p) ) + p++; + } + + free( propStr ); + } + + return count; +} + +int hasPciToEfiMapping = -1; /* -1: not loaded, 0: does not exist, 1: loaded */ + void setup_pci_devs(pci_dt_t *pci_dt) { char *devicepath; bool do_eth_devprop, do_gfx_devprop, fix_ehci, fix_legoff, fix_uhci, fix_usb, do_enable_hpet; pci_dt_t *current = pci_dt; + char override_key[512]; + unsigned long id_array[4]; + int id_count; + char* id_keys[4] = { "vendor-id", "device-id", "subsystem-vendor-id", "subsystem-id" }; + int i; + struct DevPropDevice* device; + struct DevPropString *deviceString; do_eth_devprop = do_gfx_devprop = fix_ehci = fix_legoff = fix_uhci = fix_usb = do_enable_hpet = false; @@ -31,6 +72,15 @@ getBoolForKey(kUSBLegacyOff, &fix_legoff, &bootInfo->bootConfig); getBoolForKey(kForceHPET, &do_enable_hpet, &bootInfo->bootConfig); + // Get some PCI stuff + + if (hasPciToEfiMapping == -1) + { + hasPciToEfiMapping = (loadSystemConfig("", &bootInfo->pciConfig, "pci.plist", true) == 0 ? 1 : 0); + if (hasPciToEfiMapping) + verbose("pci.plist is found.\n"); + } + while (current) { devicepath = get_pci_dev_path(current); @@ -91,6 +141,50 @@ } setup_pci_devs(current->children); - current = current->next; - } + + if (hasPciToEfiMapping) + { + /* Device ID override injection */ + memset(id_array, sizeof(id_array), 0); + sprintf(override_key, "pci%04x,%04x", current->vendor_id, current->device_id); + id_count = PciToEfiOverride(override_key, id_array, 4); + device = NULL; + + for (i = 0; i < id_count; i++) + { + uint8_t fourOctets[4]; + uint32_t id = id_array[i]; + if (id == 0) + { + if (i == 0) + id = current->vendor_id; + else if (i == 1) + id = current->device_id; + else + continue; + } + + fourOctets[0] = id; + fourOctets[1] = id >> 8; + fourOctets[2] = 0; + fourOctets[3] = 0; + if (id != 0) + { + if (device == NULL) + { + device = devprop_find_device(devicepath); + if (device == NULL) + { + deviceString = devprop_create_string(); + device = devprop_add_device(deviceString, devicepath); + } + } + devprop_add_value(device, id_keys[i], fourOctets, sizeof(fourOctets)); + verbose("%s: %s 0x%02x\n", override_key, id_keys[i], id); + } + } + } + + current = current->next; + } } Index: branches/andyvand/i386/libsaio/stringTable.c =================================================================== --- branches/andyvand/i386/libsaio/stringTable.c (revision 140) +++ branches/andyvand/i386/libsaio/stringTable.c (revision 141) @@ -481,41 +481,10 @@ bool getValueForKey( const char *key, const char **val, int *size, config_file_t *config ) { - const char *overrideVal; - int overrideSize; - bool override, ret; - if (getValueForBootKey(bootArgs->CommandLine, key, val, size)) return true; - ret = getValueForConfigTableKey(config, key, val, size); - - // Try to find alternate keys in bootInfo->overrideConfig - // and prefer its values with the exceptions for - // "Kernel"="mach_kernel" and "Kernel Flags"="". - - if (config->canOverride) - { - if (getValueForConfigTableKey(&bootInfo->overrideConfig, key, &overrideVal, &overrideSize)) - { - override = true; - - if (ret && (strcmp(key, "Kernel") == 0) && (strcmp(overrideVal, "mach_kernel") == 0)) - override = false; - - if (ret && (strcmp(key, "Kernel Flags") == 0) && (overrideSize == 0)) - override = false; - - if (override) - { - *val = overrideVal; - *size = overrideSize; - return true; - } - } - } - - return ret; + return getValueForConfigTableKey(config, key, val, size); } @@ -601,78 +570,106 @@ /* loadSystemConfig * + * filename == NULL: + * You are loading from com.apple.Boot.plist somewhere in the universe. + * Also, bootarg's "config=" is considerd as replacement name. + * + * filename != NULL: + * Use it as file name. + * * Returns 0 - successful. * -1 - unsuccesful. */ -int loadSystemConfig(config_file_t *config) +#define MAX_DIRSPECS (8) + +int loadSystemConfig(const char* bootargs, config_file_t *config, const char* filename, bool override) { - char *dirspec[] = { - "/Extra/com.apple.Boot.plist", - "bt(0,0)/Extra/com.apple.Boot.plist", - "/Library/Preferences/SystemConfiguration/com.apple.Boot.plist", - "/com.apple.boot.P/Library/Preferences/SystemConfiguration/com.apple.Boot.plist", - "/com.apple.boot.R/Library/Preferences/SystemConfiguration/com.apple.Boot.plist", - "/com.apple.boot.S/Library/Preferences/SystemConfiguration/com.apple.Boot.plist" + char config_filename[512]; // Will be filled with the name of boot.plist + + char *defaultDirspec[MAX_DIRSPECS] = { + "/Extra/", + "bt(0,0)/Extra/", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL }; - int i, fd, count, ret=-1; + char *overrideDirspec[MAX_DIRSPECS] = { + "rd(0,0)/Extra/", + "/Extra/", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL + }; - for(i = 0; i< sizeof(dirspec)/sizeof(dirspec[0]); i++) - { - if ((fd = open(dirspec[i], 0)) >= 0) - { - // read file - count = read(fd, config->plist, IO_CONFIG_DATA_SIZE); - close(fd); - - // build xml dictionary - ParseXMLFile(config->plist, &config->dictionary); - sysConfigValid = true; - ret=0; - - // enable canOverride flag - config->canOverride = true; - - break; - } - } - return ret; -} - -/* loadOverrideConfig - * - * Returns 0 - successful. - * -1 - unsuccesful. - */ -int loadOverrideConfig(config_file_t *config) -{ - char *dirspec[] = { - "rd(0,0)/Extra/com.apple.Boot.plist", - "/Extra/com.apple.Boot.plist", + char* moreBootPlist[4] = { "/Library/Preferences/SystemConfiguration/com.apple.Boot.plist", "/com.apple.boot.P/Library/Preferences/SystemConfiguration/com.apple.Boot.plist", "/com.apple.boot.R/Library/Preferences/SystemConfiguration/com.apple.Boot.plist", - "/com.apple.boot.S/Library/Preferences/SystemConfiguration/com.apple.Boot.plist" + "/com.apple.boot.S/Library/Preferences/SystemConfiguration/com.apple.Boot.plist", }; - int i, fd, count, ret=-1; + int i, j, fd, count, size; + const char* val; + char filespec[512]; + char *dirspec[MAX_DIRSPECS]; - for(i = 0; i< sizeof(dirspec)/sizeof(dirspec[0]); i++) + if (override) + memcpy(dirspec, overrideDirspec, sizeof(overrideDirspec)); + else + memcpy(dirspec, defaultDirspec, sizeof(defaultDirspec)); + + + if (filename) { - if ((fd = open(dirspec[i], 0)) >= 0) + strcpy(config_filename, filename); + } + else + { + strcpy(config_filename, "com.apple.Boot.plist"); + for (j = 0; dirspec[j]; j++) /* noop */; + memcpy(&dirspec[j], moreBootPlist, sizeof(moreBootPlist)); + // If there is a config designated, point boot.plist to something else. + if (bootargs && getValueForBootKey(bootargs, "config", &val, &size)) + { + if (size > 480) size = 480; + if (size > 0) + { + memcpy(config_filename, val, size); + config_filename[size] = 0; + } + } + } + + for(i = 0; dirspec[i]; i++) + { + strcpy(filespec, dirspec[i]); + /* If the last char is / then append the boot.plist name */ + if (filespec[strlen(filespec)-1] == '/') { + strcat(filespec, config_filename); + } + + if ((fd = open(filespec, 0)) >= 0) + { // read file count = read(fd, config->plist, IO_CONFIG_DATA_SIZE); close(fd); // build xml dictionary ParseXMLFile(config->plist, &config->dictionary); - sysConfigValid = true; - ret=0; - break; + sysConfigValid=true; + verbose("Config file %s loaded\n", filespec); + return 0; } } - return ret; + return -1; } /* loadHelperConfig @@ -770,3 +767,5 @@ return ptr; } + + Index: branches/andyvand/i386/libsaio/saio_types.h =================================================================== --- branches/andyvand/i386/libsaio/saio_types.h (revision 140) +++ branches/andyvand/i386/libsaio/saio_types.h (revision 141) @@ -64,7 +64,6 @@ typedef struct { char plist[4096]; // buffer for plist TagPtr dictionary; // buffer for xml dictionary - bool canOverride; // flag to mark a dictionary can be overriden } config_file_t; /* Index: branches/andyvand/i386/libsaio/saio_internal.h =================================================================== --- branches/andyvand/i386/libsaio/saio_internal.h (revision 140) +++ branches/andyvand/i386/libsaio/saio_internal.h (revision 141) @@ -156,9 +156,8 @@ extern bool getColorForKey(const char *key, unsigned int *val, config_file_t *configBuff); extern bool getDimensionForKey( const char *key, unsigned int *value, config_file_t *config, unsigned int dimension_max, unsigned int object_size ); extern int loadConfigFile(const char *configFile, config_file_t *configBuff); -extern int loadSystemConfig(config_file_t *configBuff); +extern int loadSystemConfig(const char* bootargs, config_file_t *configBuff, const char* filename, bool override); extern int loadHelperConfig(config_file_t *configBuff); -extern int loadOverrideConfig(config_file_t *configBuff); extern char * newString(const char *oldString); extern char * getNextArg(char ** ptr, char * val); extern int ParseXMLFile( char * buffer, TagPtr * dict ); @@ -204,6 +203,9 @@ extern BVRef gBootVolume; extern BVRef gBIOSBootVolume; +/* pci_root.c */ +extern int search_and_get_acpi_fd(const char * filename, const char ** outDirspec); + // Function pointer to be filled in if ramdisks are available extern int (*p_get_ramdisk_info)(int biosdev, struct driveInfo *dip); extern int (*p_ramdiskReadBytes)( int biosdev, unsigned int blkno, Index: branches/andyvand/i386/boot2/boot.c =================================================================== --- branches/andyvand/i386/boot2/boot.c (revision 140) +++ branches/andyvand/i386/boot2/boot.c (revision 141) @@ -266,8 +266,10 @@ bvChain = getBVChainForBIOSDev(gBIOSDev); setBootGlobals(bvChain); - // Load boot.plist config file - status = loadSystemConfig(&bootInfo->bootConfig); + // Load boot.plist config file. + // At this point, since the boot args are not typed in yet, just use + // empty string so that loadSystemConfig gets the default. + status = loadSystemConfig("", &bootInfo->bootConfig, NULL, false); if (getBoolForKey(kQuietBootKey, &quiet, &bootInfo->bootConfig) && quiet) { gBootMode |= kBootModeQuiet; Index: branches/andyvand/i386/boot2/drivers.c =================================================================== --- branches/andyvand/i386/boot2/drivers.c (revision 140) +++ branches/andyvand/i386/boot2/drivers.c (revision 141) @@ -163,6 +163,8 @@ long LoadDrivers( char * dirSpec ) { + int len, i; + const char *string; char dirSpecExtra[1024]; bool loadTestDrivers = false; @@ -198,7 +200,25 @@ } // Next try to load Extra extensions from the selected root partition. + for (i = 0 ; i < 2; i++) { strcpy(dirSpecExtra, "/Extra/"); + + if (i == 1) { + len = 0; + // Second time around, see if I really want to load + if (!getValueForKey( "AdditionalExtensions", &string, &len, &bootInfo->bootConfig )) { + len = 0; + } + // Make sure there is something there. + if (len > 0 && string) { + strcpy(dirSpecExtra, string); + if (dirSpecExtra[strlen(dirSpecExtra)-1] != '/') strcat(dirSpecExtra, "/"); + } + else { + break; + } + } + if (FileLoadDrivers(dirSpecExtra, 0) != 0) { // If failed, then try to load Extra extensions from the boot partition @@ -216,6 +236,7 @@ } } } + } // Also try to load Extensions from boot helper partitions. strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/"); Index: branches/andyvand/i386/boot2/options.c =================================================================== --- branches/andyvand/i386/boot2/options.c (revision 140) +++ branches/andyvand/i386/boot2/options.c (revision 141) @@ -1180,12 +1180,9 @@ cnt = 0; } - // Load com.apple.Boot.plist from the selected volume - // and use its contents to override default bootConfig. - // This is not a mandatory opeartion anymore. + // reload the config, this time with the boot arg + loadSystemConfig(gBootArgs, &bootInfo->bootConfig, NULL, true); - loadOverrideConfig(&bootInfo->overrideConfig); - // Use the kernel name specified by the user, or fetch the name // in the config table, or use the default if not specified. // Specifying a kernel name on the command line, or specifying Index: branches/andyvand/i386/libsa/libsa.h =================================================================== --- branches/andyvand/i386/libsa/libsa.h (revision 140) +++ branches/andyvand/i386/libsa/libsa.h (revision 141) @@ -105,6 +105,10 @@ extern char * strerror(int errnum); /* + * strdup.c + */ +extern char * strdup (const char * str); +/* * strtol.c */ extern long strtol(const char * nptr, char ** endptr, int base); Index: branches/andyvand/i386/libsa/string.c =================================================================== --- branches/andyvand/i386/libsa/string.c (revision 140) +++ branches/andyvand/i386/libsa/string.c (revision 141) @@ -241,6 +241,18 @@ return(strncat(s1, s2, strlen(s2))); } +char * strdup (const char * str) +{ + char *clone; + size_t size; + + size = strlen (str) + 1; + clone = malloc (size); + memcpy (clone, str, size); + + return clone; +} + #if STRNCASECMP int strncasecmp(const char *s1, const char *s2, size_t len) { @@ -264,4 +276,3 @@ return csum; } - Index: branches/andyvand/revision =================================================================== --- branches/andyvand/revision (revision 140) +++ branches/andyvand/revision (revision 141) @@ -1 +1 @@ -69:119 \ No newline at end of file +69:140 \ No newline at end of file