Index: branches/meklort/efisysinst.sh =================================================================== --- branches/meklort/efisysinst.sh (revision 504) +++ branches/meklort/efisysinst.sh (revision 505) @@ -1,31 +0,0 @@ -#!/bin/sh - -# efisysinst.sh -# -# -# Created by mackerintel on 2/2/09. -# Copyright 2009 mackerintel. All rights reserved. - -if [[ x$1 == x ]]; then - echo Usage: $0 disknumber; - exit 0; -fi - -if [[ `dd if=/dev/disk${1}s1 count=8 bs=1 skip=82 | uuencode -m -|head -n 2|tail -n 1` != "RkFUMzIgICA=" ]]; then - echo "/dev/disk${1}s1" "isn't" a FAT32 partition; - exit 1; -fi - -if [ ! -f boot1f32 ]; then - echo "boot1f32 not found"; - exit 1; -fi -if [ ! -f boot0 ]; then - echo "boot0 not found"; - exit 1; -fi -dd if=/dev/disk${1}s1 count=1 bs=512 of=/tmp/origbs -cp boot1f32 /tmp/newbs -dd if=/tmp/origbs of=/tmp/newbs skip=3 seek=3 bs=1 count=87 conv=notrunc -dd of=/dev/disk${1}s1 count=1 bs=512 if=/tmp/newbs -dd if=boot0 of=/dev/disk${1} count=430 bs=1 Index: branches/meklort/doc/BootHelp.txt =================================================================== --- branches/meklort/doc/BootHelp.txt (revision 504) +++ branches/meklort/doc/BootHelp.txt (revision 505) @@ -14,8 +14,9 @@ kernel: kernel name (e.g. "mach_kernel" - must be in "/" ) - flags: -v (verbose) -s (single user mode), - -x (safe mode) -F (ignore boot configuration file) + flags: -v (verbose) -s (single user mode) + -x (safe mode) -f (ignore caches) + -F (ignore "Kernel Flags" specified in boot configuration file) "Graphics Mode"="WIDTHxHEIGHTxDEPTH" (e.g. "1024x768x32") @@ -47,13 +48,18 @@ "Instant Menu"=Yes Force displaying the partition selection menu. "Default Partition" Sets the default boot partition, - =hd(x,y) where 'x' & 'y' are the disk and partition numbers. + =hd(x,y)|UUID|"Label" Specified as a disk/partition pair, an UUID, or a + label enclosed in quotes. + "Hide Partition" Remove unwanted partition(s) from the boot menu. - =hd(x,y) [hd(m,n)] only non mac osx boot partitions can be hidden. + =partition Specified, possibly multiple times, as hd(x,y), an + [;partition2 ...] UUID or label enclosed in quotes. + + "Rename Partition" Rename partition(s) for the boot menu. + =partition Where partition is hd(x,y), UUID or label enclosed + [;partition2 in quotes. The alias can optionally be quoted too. + ...] - "Rename Partition" Rename partition(s) for the boot menu. - =hd(x,y) [;hd(m,n) ...] - GUI=No Disable the GUI (enabled by default). "Boot Banner"=Yes|No Show boot banner in GUI mode (enabled by default). "Legacy Logo"=Yes|No Use the legacy grey apple logo (disabled by default). @@ -70,9 +76,11 @@ EthernetBuiltIn=Yes|No Automatic "built-in"=yes device-properties generation for ethernet interfaces. - USBBusFix=Yes Enable the EHCI and UHCI fixes (disabled by default). + USBBusFix=Yes Enable all USB fixes below: EHCIacquire=Yes Enable the EHCI fix (disabled by default). UHCIreset=Yes Enable the UHCI fix (disabled by default). + USBLegacyOff=Yes Enable the USB Legacy fix (disabled by default). + ForceHPET=Yes|No Force Enable HPET. Wake=No Disable wake up after hibernation (default: enabled). @@ -82,11 +90,10 @@ DropSSDT=Yes Skip the SSDT tables while relocating the ACPI tables. DSDT= Use an alternate DSDT.aml file - (default path: /DSDT.aml /Extra/DSDT.aml). + (default path: /DSDT.aml /Extra/DSDT.aml bt(0,0)/Extra/DSDT.aml). - SMBIOS= Use an alternate smbios.plist file - (default path: /smbios.plist /Extra/smbios.plist - bt(0,0)/Extra/smbios.plist). + SMBIOS= Use an alternate SMBIOS.plist file + (default path: /Extra/SMBIOS.plist bt(0,0)/Extra/SMBIOS.plist). SMBIOSdefaults=No Don't use the Default values for SMBIOS overriding if smbios.plist doesn't exist, factory @@ -100,3 +107,5 @@ SMUUID in smbios config (reserved field) isn't used. SystemType= Set the system type where n is between 0..6 (default =1 (Desktop) + md0= Load raw img file into memory for use as XNU's md0 + ramdisk. /Extra/Postboot.img is used otherwise. Index: branches/meklort/doc/README =================================================================== --- branches/meklort/doc/README (revision 504) +++ branches/meklort/doc/README (revision 505) @@ -18,8 +18,7 @@ - automatic FSB detection code even for recent AMD CPUs. - Apple Software RAID support. - stage2 loader (boot) can be placed as a regular file in the boot - partition's root folder. It has precedence over the embedded - startupfile. + partition's root folder. Installation @@ -31,7 +30,7 @@ Suppose that your installation is on /dev/disk0s2 - Install boot0 to the MBR: - sudo fdisk -f boot0 -u -y /dev/rdisk0 + sudo ./fdisk440 -f boot0 -u -y /dev/rdisk0 - Install boot1h to the partition's bootsector: sudo dd if=boot1h of=/dev/rdisk0s2 @@ -52,8 +51,8 @@ namely /dev/disk0s3 and /dev/disk1s3 - Install boot0 to the MBR of both disks: - sudo fdisk -f boot0 -u -y /dev/rdisk0 - sudo fdisk -f boot0 -u -y /dev/rdisk1 + sudo ./fdisk440 -f boot0 -u -y /dev/rdisk0 + sudo ./fdisk440 -f boot0 -u -y /dev/rdisk1 - Install boot1h to the bootsector of each boot partition: sudo dd if=boot1h of=/dev/rdisk0s3 @@ -66,14 +65,7 @@ diskutil mount disk1s3 cp boot /Volumes/Boot\ OSX diskutil unmount disk1s3 - - - Add "rd=uuid boot-uuid=506D8F03-0596-32D8-BE0B-E3A4E7D5C72A" to your kernel flags - (replace with your root volume's UUID; find out using "Disk Utility.app", right - click on your root volume, then Get Info"): - nano /Library/Preferences/SystemConfiguration/com.apple.Boot.plist - touch /System/Library/Extensions - Support: -------- @@ -93,5 +85,3 @@ Chameleon is released under the terms and conditions of Apple Public Source License (see APPLE_LICENSE). - To use "Chameleon" for commercial purposes please contact us at: - http://chameleon.osx86.hu/contact Index: branches/meklort/version =================================================================== --- branches/meklort/version (revision 504) +++ branches/meklort/version (revision 505) @@ -1 +1 @@ -2.0-RC5pre11 \ No newline at end of file +2.0-RC5 \ No newline at end of file Index: branches/meklort/CHANGES =================================================================== --- branches/meklort/CHANGES (revision 504) +++ branches/meklort/CHANGES (revision 505) @@ -1,12 +1,20 @@ -- Added module hooks + callback system. Main code still needs ot be populated with hooks -- Added module support -- Fixed lapic_init patch. Fixed _cpuid_set_info patch to work on the 10.6.0 / 10.6.1 kernel (patches cpumodel) -- Added USB Legacy Off patch. Modified to run immediately *before* the kernel is executed, that - way no files need to be loaded after the usb device is reset. -- Backup original dsdt to /dsdt/originaldsdt in the IORegistery -- Added kernel patcher, removes the CPUID check panic in the kernel. Forces _cpuid_set_info to - return Penryn / cpuid model 23 - +- Added Booter Log Dump Tool +- Added Booter message Logging (":/boot-log" ioreg property) +- Removed obsolete -f option, use -x instead +- Removed -x32 option, use arch=i386 instead +- Added automatic SMBusspeed detection for lga1156 core i5/7 cpus +- Added new iMac11,1 sbios default model for lga1156 core i5/17 mobos +- md0 code. Notified xnu when an md ramdisk is specified +- Added rollover image support for selected device icons. + Use device__o.png in theme folder. Credits goes to Blackosx. +- Revisited theme resource embedding. Using the device_ icons are optional with + the exception of device_generic. +- Optimized memory detection speed +- Added displaying source device and partition number for file read operations. +- Increased boot2's maximum size from 383.5k to 447.5k. + Updated stage 1 loaders for handling the new size limit. +- Added alternate format for setting the default partition. The user can specify the selected + volume UUID for the "Default Partition" key. - Implemented SPD memory automatic detection and injection,seems to work really great ... - Factorized code to prepare a dynamic memory detection algorithm ... - Optimized smbios table address search Index: branches/meklort/i386/libsaio/dsdt_patcher.c =================================================================== --- branches/meklort/i386/libsaio/dsdt_patcher.c (revision 504) +++ branches/meklort/i386/libsaio/dsdt_patcher.c (revision 505) @@ -1,545 +0,0 @@ -/* - * Copyright 2008 mackerintel - */ - -#include "libsaio.h" -#include "boot.h" -#include "bootstruct.h" -#include "acpi.h" -#include "efi_tables.h" -#include "fake_efi.h" -#include "dsdt_patcher.h" -#include "platform.h" - -#ifndef DEBUG_DSDT -#define DEBUG_DSDT 0 -#endif - -#if DEBUG_DSDT==2 -#define DBG(x...) {printf(x); sleep(1);} -#elif DEBUG_DSDT==1 -#define DBG(x...) printf(x) -#else -#define DBG(x...) -#endif - -/* 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; -} - -/* 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; -} -/** The folowing ACPI Table search algo. should be reused anywhere needed:*/ -int search_and_get_acpi_fd(const char * filename, const char ** outDirspec) -{ - int fd=0; - const char * overriden_pathname=NULL; - static char dirspec[512]=""; - static bool first_time =true; - int len=0; - - /// Take in accound user overriding if it's DSDT only - if (strstr(filename, "DSDT") && - getValueForKey(kDSDT, &overriden_pathname, &len, - &bootInfo->bootConfig)) - { - sprintf(dirspec, "%s", overriden_pathname); - fd=open (dirspec,0); - if (fd>=0) goto success_fd; - } - // Check that dirspec is not already assigned with a path - if (!first_time && *dirspec) - { // it is so start searching this cached patch first - //extract path - for (len=strlen(dirspec)-1; len; len--) - if (dirspec[len]=='/' || len==0) - { - dirspec[len]='\0'; - break; - } - // now concat with the filename - strncat(dirspec, "/", sizeof(dirspec)); - strncat(dirspec, filename, sizeof(dirspec)); - // and test to see if we don't have our big boy here: - fd=open (dirspec,0); - if (fd>=0) - { - // printf("ACPI file search cache hit: file found at %s\n", dirspec); - goto success_fd; - } - } - // Start searching any potential location for ACPI Table - // search the Extra folders first - sprintf(dirspec,"/Extra/%s",filename); - fd=open (dirspec,0); - if (fd>=0) goto success_fd; - - sprintf(dirspec,"bt(0,0)/Extra/%s",filename); - fd=open (dirspec,0); - if (fd>=0) goto success_fd; - - sprintf(dirspec, "%s", filename); // search current dir - fd=open (dirspec,0); - if (fd>=0) goto success_fd; - - sprintf(dirspec, "/%s", filename); // search root - fd=open (dirspec,0); - if (fd>=0) goto success_fd; - - // NOT FOUND: - verbose("ACPI Table not found: %s\n", filename); - if (outDirspec) *outDirspec = ""; - first_time = false; - return -1; - // FOUND -success_fd: - first_time = false; - if (outDirspec) *outDirspec = dirspec; - return fd; -} - -void *loadACPITable (const char * filename) -{ - void *tableAddr; - const char * dirspec=NULL; - - int fd = search_and_get_acpi_fd(filename, &dirspec); - - if (fd>=0) - { - tableAddr=(void*)AllocateKernelMemory(file_size (fd)); - if (tableAddr) - { - if (read (fd, tableAddr, file_size (fd))!=file_size (fd)) - { - printf("Couldn't read table %s\n",dirspec); - free (tableAddr); - close (fd); - return NULL; - } - - DBG("Table %s read and stored at: %x\n", dirspec, tableAddr); - close (fd); - return tableAddr; - } - close (fd); - printf("Couldn't allocate memory for table \n", dirspec); - } - printf("Couldn't find table %s\n", filename); - return NULL; -} - - -struct acpi_2_fadt * -patch_fadt(struct acpi_2_fadt *fadt, void *new_dsdt) -{ - - extern void setupSystemType(); - - struct acpi_2_fadt *fadt_mod; - bool fadt_rev2_needed = false; - bool fix_restart; - const char * value; - - // Restart Fix - if (Platform.CPU.Vendor == 0x756E6547) { /* Intel */ - fix_restart = true; - getBoolForKey(kRestartFix, &fix_restart, &bootInfo->bootConfig); - } else { - verbose ("Not an Intel platform: Restart Fix not applied !!!\n"); - fix_restart = false; - } - - if (fix_restart) fadt_rev2_needed = true; - - // Allocate new fadt table - if (fadt->Length < 0x84 && fadt_rev2_needed) - { - fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84); - memcpy(fadt_mod, fadt, fadt->Length); - fadt_mod->Length = 0x84; - fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions) - } - else - { - fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length); - memcpy(fadt_mod, fadt, fadt->Length); - } - // Determine system type / PM_Model - if ( (value=getStringForKey(kSystemType, &bootInfo->bootConfig))!=NULL) - { - if (Platform.Type > 6) - { - if(fadt_mod->PM_Profile<=6) - Platform.Type = fadt_mod->PM_Profile; // get the fadt if correct - else - Platform.Type = 1; /* Set a fixed value (Desktop) */ - verbose("Error: system-type must be 0..6. Defaulting to %d !\n", Platform.Type); - } - else - Platform.Type = (unsigned char) strtoul(value, NULL, 10); - } - // Set PM_Profile from System-type if only if user wanted this value to be forced - if (fadt_mod->PM_Profile != Platform.Type) - { - if (value) - { // user has overriden the SystemType so take care of it in FACP - verbose("FADT: changing PM_Profile from 0x%02x to 0x%02x\n", fadt_mod->PM_Profile, Platform.Type); - fadt_mod->PM_Profile = Platform.Type; - } - else - { // PM_Profile has a different value and no override has been set, so reflect the user value to ioregs - Platform.Type = fadt_mod->PM_Profile <= 6 ? fadt_mod->PM_Profile : 1; - } - } - // We now have to write the systemm-type in ioregs: we cannot do it before in setupDeviceTree() - // because we need to take care of facp original content, if it is correct. - setupSystemType(); - - // Patch FADT to fix restart - if (fix_restart) - { - fadt_mod->Flags|= 0x400; - fadt_mod->Reset_SpaceID = 0x01; // System I/O - fadt_mod->Reset_BitWidth = 0x08; // 1 byte - fadt_mod->Reset_BitOffset = 0x00; // Offset 0 - fadt_mod->Reset_AccessWidth = 0x01; // Byte access - fadt_mod->Reset_Address = 0x0cf9; // Address of the register - fadt_mod->Reset_Value = 0x06; // Value to write to reset the system - verbose("FADT: Restart Fix applied !\n"); - } - - // Save old DSDT to the IORegistery - Node* node = DT__FindNode("/", false); - if(node != NULL) - { - node = DT__AddChild(node, "dsdt"); - - struct acpi_2_dsdt *dsdt; - dsdt = (struct acpi_2_dsdt*) (fadt_mod->DSDT); - DT__AddProperty(node, "originaldsdt", (dsdt->Length + sizeof(struct acpi_2_dsdt) - 1), (void*)dsdt); /// Insert old dsdt. Length is header length (36) + dsdt length - - } - - - // Patch DSDT Address - DBG("DSDT: Old @%x,%x, ",fadt_mod->DSDT,fadt_mod->X_DSDT); - - - fadt_mod->DSDT=(uint32_t)new_dsdt; - if ((uint32_t)(&(fadt_mod->X_DSDT))-(uint32_t)fadt_mod+8<=fadt_mod->Length) - fadt_mod->X_DSDT=(uint32_t)new_dsdt; - - DBG("New @%x,%x\n",fadt_mod->DSDT,fadt_mod->X_DSDT); - - // Correct the checksum - fadt_mod->Checksum=0; - fadt_mod->Checksum=256-checksum8(fadt_mod,fadt_mod->Length); - - return fadt_mod; -} - -/* Setup ACPI without replacing DSDT. */ -int setupAcpiNoMod() -{ -// addConfigurationTable(&gEfiAcpiTableGuid, getAddressOfAcpiTable(), "ACPI"); -// addConfigurationTable(&gEfiAcpi20TableGuid, getAddressOfAcpi20Table(), "ACPI_20"); - /* XXX aserebln why uint32 cast if pointer is uint64 ? */ - acpi10_p = (uint32_t)getAddressOfAcpiTable(); - acpi20_p = (uint32_t)getAddressOfAcpi20Table(); - addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI"); - if(acpi20_p) addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20"); - return 1; -} - -/* Setup ACPI. Replace DSDT if DSDT.aml is found */ -int setupAcpi(void) -{ - int version; - void *new_dsdt; - - bool drop_ssdt; - - // Load replacement DSDT - new_dsdt=loadACPITable("DSDT.aml"); - if (!new_dsdt) - { - return setupAcpiNoMod(); - } - - DBG("New DSDT Loaded in memory\n"); - - { - bool tmp; - drop_ssdt=getBoolForKey(kDropSSDT, &tmp, &bootInfo->bootConfig)&&tmp; - } - - // Do the same procedure for both versions of ACPI - for (version=0; version<2; version++) { - struct acpi_2_rsdp *rsdp, *rsdp_mod; - struct acpi_2_rsdt *rsdt, *rsdt_mod; - int rsdplength; - - // Find original rsdp - rsdp=(struct acpi_2_rsdp *)(version?getAddressOfAcpi20Table():getAddressOfAcpiTable()); - if (!rsdp) - { - DBG("No ACPI version %d found. Ignoring\n", version+1); - if (version) - addConfigurationTable(&gEfiAcpi20TableGuid, NULL, "ACPI_20"); - else - addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI"); - continue; - } - rsdplength=version?rsdp->Length:20; - - DBG("RSDP version %d found @%x. Length=%d\n",version+1,rsdp,rsdplength); - - /* FIXME: no check that memory allocation succeeded - * Copy and patch RSDP,RSDT, XSDT and FADT - * For more info see ACPI Specification pages 110 and following - */ - - rsdp_mod=(struct acpi_2_rsdp *) AllocateKernelMemory(rsdplength); - memcpy(rsdp_mod, rsdp, rsdplength); - rsdt=(struct acpi_2_rsdt *)(rsdp->RsdtAddress); - - DBG("RSDT @%x, Length %d\n",rsdt, rsdt->Length); - - if (rsdt && (uint32_t)rsdt !=0xffffffff && rsdt->Length<0x10000) - { - uint32_t *rsdt_entries; - int rsdt_entries_num; - int dropoffset=0, i; - - rsdt_mod=(struct acpi_2_rsdt *)AllocateKernelMemory(rsdt->Length); - memcpy (rsdt_mod, rsdt, rsdt->Length); - rsdp_mod->RsdtAddress=(uint32_t)rsdt_mod; - rsdt_entries_num=(rsdt_mod->Length-sizeof(struct acpi_2_rsdt))/4; - rsdt_entries=(uint32_t *)(rsdt_mod+1); - for (i=0;iLength); - - if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000) - { - printf("FADT incorrect. Not modified\n"); - continue; - } - - fadt_mod = patch_fadt(fadt, new_dsdt); - rsdt_entries[i-dropoffset]=(uint32_t)fadt_mod; - continue; - } - } - DBG("\n"); - - // Correct the checksum of RSDT - rsdt_mod->Length-=4*dropoffset; - - DBG("RSDT: Original checksum %d, ", rsdt_mod->Checksum); - - rsdt_mod->Checksum=0; - rsdt_mod->Checksum=256-checksum8(rsdt_mod,rsdt_mod->Length); - - DBG("New checksum %d at %x\n", rsdt_mod->Checksum,rsdt_mod); - } - else - { - rsdp_mod->RsdtAddress=0; - printf("RSDT not found or RSDT incorrect\n"); - } - - if (version) - { - struct acpi_2_xsdt *xsdt, *xsdt_mod; - - // FIXME: handle 64-bit address correctly - - xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress); - DBG("XSDT @%x;%x, Length=%d\n", (uint32_t)(rsdp->XsdtAddress>>32),(uint32_t)rsdp->XsdtAddress, - xsdt->Length); - if (xsdt && (uint64_t)rsdp->XsdtAddress<0xffffffff && xsdt->Length<0x10000) - { - uint64_t *xsdt_entries; - int xsdt_entries_num, i; - int dropoffset=0; - - xsdt_mod=(struct acpi_2_xsdt*)AllocateKernelMemory(xsdt->Length); - memcpy(xsdt_mod, xsdt, xsdt->Length); - rsdp_mod->XsdtAddress=(uint32_t)xsdt_mod; - xsdt_entries_num=(xsdt_mod->Length-sizeof(struct acpi_2_xsdt))/8; - xsdt_entries=(uint64_t *)(xsdt_mod+1); - for (i=0;i>32),fadt, - fadt->Length); - - if (!fadt || (uint64_t)xsdt_entries[i] >= 0xffffffff || fadt->Length>0x10000) - { - verbose("FADT incorrect or after 4GB. Dropping XSDT\n"); - goto drop_xsdt; - } - - fadt_mod = patch_fadt(fadt, new_dsdt); - xsdt_entries[i-dropoffset]=(uint32_t)fadt_mod; - - DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]); - - continue; - } - - DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]); - - } - - // Correct the checksum of XSDT - xsdt_mod->Length-=8*dropoffset; - xsdt_mod->Checksum=0; - xsdt_mod->Checksum=256-checksum8(xsdt_mod,xsdt_mod->Length); - } - else - { - drop_xsdt: - - DBG("About to drop XSDT\n"); - - /*FIXME: Now we just hope that if MacOS doesn't find XSDT it reverts to RSDT. - * A Better strategy would be to generate - */ - - rsdp_mod->XsdtAddress=0xffffffffffffffffLL; - verbose("XSDT not found or XSDT incorrect\n"); - } - } - - // Correct the checksum of RSDP - - DBG("RSDP: Original checksum %d, ", rsdp_mod->Checksum); - - rsdp_mod->Checksum=0; - rsdp_mod->Checksum=256-checksum8(rsdp_mod,20); - - DBG("New checksum %d\n", rsdp_mod->Checksum); - - if (version) - { - DBG("RSDP: Original extended checksum %d", rsdp_mod->ExtendedChecksum); - - rsdp_mod->ExtendedChecksum=0; - rsdp_mod->ExtendedChecksum=256-checksum8(rsdp_mod,rsdp_mod->Length); - - DBG("New extended checksum %d\n", rsdp_mod->ExtendedChecksum); - - } - - verbose("Patched ACPI version %d DSDT\n", version+1); - if (version) - { - /* XXX aserebln why uint32 cast if pointer is uint64 ? */ - acpi20_p = (uint32_t)rsdp_mod; - addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20"); - } - else - { - /* XXX aserebln why uint32 cast if pointer is uint64 ? */ - acpi10_p = (uint32_t)rsdp_mod; - addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI"); - } - } -#if DEBUG_DSDT - printf("Press a key to continue... (DEBUG_DSDT)\n"); - getc(); -#endif - return 1; -} Index: branches/meklort/i386/libsaio/dsdt_patcher.h =================================================================== --- branches/meklort/i386/libsaio/dsdt_patcher.h (revision 504) +++ branches/meklort/i386/libsaio/dsdt_patcher.h (revision 505) @@ -1,20 +0,0 @@ -/* - * Copyright 2008 mackerintel - */ - -#ifndef __LIBSAIO_DSDT_PATCHER_H -#define __LIBSAIO_DSDT_PATCHER_H - -#include "libsaio.h" - -uint64_t acpi10_p; -uint64_t acpi20_p; -uint64_t smbios_p; -extern int setupAcpi(); - -extern EFI_STATUS addConfigurationTable(); - -extern EFI_GUID gEfiAcpiTableGuid; -extern EFI_GUID gEfiAcpi20TableGuid; - -#endif /* !__LIBSAIO_DSDT_PATCHER_H */ Index: branches/meklort/i386/libsaio/fake_efi.h =================================================================== --- branches/meklort/i386/libsaio/fake_efi.h (revision 504) +++ branches/meklort/i386/libsaio/fake_efi.h (revision 505) @@ -8,7 +8,6 @@ /* Set up space for up to 10 configuration table entries */ #define MAX_CONFIGURATION_TABLE_ENTRIES 10 -extern void -setupFakeEfi(void); +extern void setupFakeEfi(void); #endif /* !__LIBSAIO_FAKE_EFI_H */ Index: branches/meklort/i386/libsaio/xml.c =================================================================== --- branches/meklort/i386/libsaio/xml.c (revision 504) +++ branches/meklort/i386/libsaio/xml.c (revision 505) @@ -110,7 +110,64 @@ return 0; } +/* Function for basic XML character entities parsing */ +char* +XMLDecode(const char* src) +{ + typedef const struct XMLEntity { + const char* name; + size_t nameLen; + char value; + } XMLEntity; + + /* This is ugly, but better than specifying the lengths by hand */ + #define _e(str,c) {str,sizeof(str)-1,c} + const XMLEntity ents[] = { + _e("quot;",'"'), _e("apos;",'\''), + _e("lt;", '<'), _e("gt;", '>'), + _e("amp;", '&') + }; + + size_t len; + const char *s; + char *out, *o; + + if ( !src || !(len = strlen(src)) || !(out = malloc(len+1)) ) + return 0; + + o = out; + s = src; + while (s <= src+len) /* Make sure the terminator is also copied */ + { + if ( *s == '&' ) + { + bool entFound = false; + int i; + + s++; + for ( i = 0; i < sizeof(ents); i++) + { + if ( strncmp(s, ents[i].name, ents[i].nameLen) == 0 ) + { + entFound = true; + break; + } + } + if ( entFound ) + { + *o++ = ents[i].value; + s += ents[i].nameLen; + continue; + } + } + + *o++ = *s++; + } + + return out; +} + #if UNUSED //========================================================================== // XMLParseFile Index: branches/meklort/i386/libsaio/console.c =================================================================== --- branches/meklort/i386/libsaio/console.c (revision 504) +++ branches/meklort/i386/libsaio/console.c (revision 505) @@ -52,6 +52,67 @@ bool gVerboseMode; bool gErrors; +/* Kabyl: BooterLog */ +#define BOOTER_LOG_SIZE (64 * 1024) +#define SAFE_LOG_SIZE 80 + +char *msgbuf = 0; +char *cursor = 0; + +struct putc_info { + char * str; + char * last_str; +}; + +static void sputc(int c, struct putc_info * pi) +{ + if (pi->last_str) + if (pi->str == pi->last_str) + { + *(pi->str) = '\0'; + return; + } + *(pi->str)++ = c; +} + +void initBooterLog(void) +{ + msgbuf = malloc(BOOTER_LOG_SIZE); + bzero(msgbuf, BOOTER_LOG_SIZE); + cursor = msgbuf; +} + +void msglog(const char * fmt, ...) +{ + va_list ap; + struct putc_info pi; + + if (!msgbuf) + return; + + if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE))) + return; + + va_start(ap, fmt); + pi.str = cursor; + pi.last_str = 0; + prf(fmt, ap, sputc, &pi); + va_end(ap); + cursor += strlen((char *)cursor); +} + +void setupBooterLog(void) +{ + if (!msgbuf) + return; + + Node *node = DT__FindNode("/", false); + if (node) + DT__AddProperty(node, "boot-log", strlen((char *)msgbuf) + 1, msgbuf); +} +/* Kabyl: !BooterLog */ + + /* * write one character to console */ @@ -103,6 +164,22 @@ prf(fmt, ap, putchar, 0); else vprf(fmt, ap); + + { + /* Kabyl: BooterLog */ + struct putc_info pi; + + if (!msgbuf) + return 0; + + if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE))) + return 0; + pi.str = cursor; + pi.last_str = 0; + prf(fmt, ap, sputc, &pi); + cursor += strlen((char *)cursor); + } + va_end(ap); return 0; } @@ -111,15 +188,31 @@ { va_list ap; + va_start(ap, fmt); if (gVerboseMode) { - va_start(ap, fmt); if (bootArgs->Video.v_display == VGA_TEXT_MODE) prf(fmt, ap, putchar, 0); else vprf(fmt, ap); - va_end(ap); } + + { + /* Kabyl: BooterLog */ + struct putc_info pi; + + if (!msgbuf) + return 0; + + if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE))) + return 0; + pi.str = cursor; + pi.last_str = 0; + prf(fmt, ap, sputc, &pi); + cursor += strlen((char *)cursor); + } + + va_end(ap); return(0); } Index: branches/meklort/i386/libsaio/xml.h =================================================================== --- branches/meklort/i386/libsaio/xml.h (revision 504) +++ branches/meklort/i386/libsaio/xml.h (revision 505) @@ -73,6 +73,7 @@ TagPtr XMLGetProperty( TagPtr dict, const char * key ); long XMLParseNextTag(char *buffer, TagPtr *tag); void XMLFreeTag(TagPtr tag); +char* XMLDecode(const char *in); //========================================================================== // XMLParseFile // Expects to see one dictionary in the XML file. Index: branches/meklort/i386/libsaio/ntfs_private.h =================================================================== --- branches/meklort/i386/libsaio/ntfs_private.h (revision 504) +++ branches/meklort/i386/libsaio/ntfs_private.h (revision 505) @@ -275,8 +275,10 @@ cn_t bf_mftmirrcn; /* $MFTMirr cn */ u_int8_t bf_mftrecsz; /* MFT record size (clust) */ /* 0xF6 inducates 1/4 */ - u_int32_t bf_ibsz; /* index buffer size */ - u_int32_t bf_volsn; /* volume ser. num. */ + u_int8_t reserved5[3]; + u_int8_t bf_ibsz; /* index buffer size */ + u_int8_t reserved6[3]; + u_int64_t bf_volsn; /* volume ser. num. */ }; /* Index: branches/meklort/i386/libsaio/hfs.c =================================================================== --- branches/meklort/i386/libsaio/hfs.c (revision 504) +++ branches/meklort/i386/libsaio/hfs.c (revision 505) @@ -80,16 +80,16 @@ static long GetCatalogEntryInfo(void *entry, long *flags, long *time, FinderInfo *finderInfo, long *infoValid); static long ResolvePathToCatalogEntry(char *filePath, long *flags, - void *entry, long dirID, long *dirIndex); + void *entry, long dirID, long long *dirIndex); -static long GetCatalogEntry(long *dirIndex, char **name, +static long GetCatalogEntry(long long *dirIndex, char **name, long *flags, long *time, FinderInfo *finderInfo, long *infoValid); static long ReadCatalogEntry(char *fileName, long dirID, void *entry, - long *dirIndex); + long long *dirIndex); static long ReadExtentsEntry(long fileID, long startBlock, void *entry); -static long ReadBTreeEntry(long btree, void *key, char *entry, long *dirIndex); +static long ReadBTreeEntry(long btree, void *key, char *entry, long long *dirIndex); static void GetBTreeRecord(long index, char *nodeBuffer, long nodeSize, char **key, char **data); @@ -264,10 +264,11 @@ long HFSReadFile(CICell ih, char * filePath, void *base, uint64_t offset, uint64_t length) { char entry[512]; + char devStr[12]; long dirID, result, flags; if (HFSInitPartition(ih) == -1) return -1; - + dirID = kHFSRootFolderID; // Skip a lead '\'. Start in the system folder if there are two. if (filePath[0] == '/') { @@ -298,13 +299,14 @@ return -1; } - verbose("Loaded HFS%s file: [%s] %d bytes from %x.\n", - (gIsHFSPlus ? "+" : ""), filePath, (uint32_t)length, ih); + getDeviceDescription(ih, devStr); + verbose("Read HFS%s file: [%s/%s] %d bytes.\n", + (gIsHFSPlus ? "+" : ""), devStr, filePath, (uint32_t)length); return length; } -long HFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex, char ** name, +long HFSGetDirEntry(CICell ih, char * dirPath, long long * dirIndex, char ** name, long * flags, long * time, FinderInfo * finderInfo, long * infoValid) { @@ -346,7 +348,7 @@ UInt16 nodeSize; UInt32 firstLeafNode; - long dirIndex; + long long dirIndex; char *name; long flags, time; @@ -360,7 +362,7 @@ nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize); firstLeafNode = SWAP_BE32(gBTHeaders[kBTreeCatalog]->firstLeafNode); - dirIndex = firstLeafNode * nodeSize; + dirIndex = (long long) firstLeafNode * nodeSize; GetCatalogEntry(&dirIndex, &name, &flags, &time, 0, 0); @@ -526,10 +528,11 @@ } static long ResolvePathToCatalogEntry(char * filePath, long * flags, - void * entry, long dirID, long * dirIndex) + void * entry, long dirID, long long * dirIndex) { char *restPath; - long result, cnt, subFolderID = 0, tmpDirIndex; + long result, cnt, subFolderID = 0; + long long tmpDirIndex; HFSPlusCatalogFile *hfsPlusFile; // Copy the file name to gTempStr @@ -576,7 +579,7 @@ return result; } -static long GetCatalogEntry(long * dirIndex, char ** name, +static long GetCatalogEntry(long long * dirIndex, char ** name, long * flags, long * time, FinderInfo * finderInfo, long * infoValid) { @@ -597,12 +600,12 @@ nodeBuf = (char *)malloc(nodeSize); node = (BTNodeDescriptor *)nodeBuf; - index = *dirIndex % nodeSize; - curNode = *dirIndex / nodeSize; + index = (long) (*dirIndex % nodeSize); + curNode = (long) (*dirIndex / nodeSize); // Read the BTree node and get the record for index. ReadExtent(extent, extentSize, kHFSCatalogFileID, - (long long)curNode * nodeSize, nodeSize, nodeBuf, 1); + (long long) curNode * nodeSize, nodeSize, nodeBuf, 1); GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &entry); GetCatalogEntryInfo(entry, flags, time, finderInfo, infoValid); @@ -626,7 +629,7 @@ index = 0; curNode = SWAP_BE32(node->fLink); } - *dirIndex = curNode * nodeSize + index; + *dirIndex = (long long) curNode * nodeSize + index; free(nodeBuf); @@ -634,7 +637,7 @@ } static long ReadCatalogEntry(char * fileName, long dirID, - void * entry, long * dirIndex) + void * entry, long long * dirIndex) { long length; char key[sizeof(HFSPlusCatalogKey)]; @@ -680,7 +683,7 @@ return ReadBTreeEntry(kBTreeExtents, &key, entry, 0); } -static long ReadBTreeEntry(long btree, void * key, char * entry, long * dirIndex) +static long ReadBTreeEntry(long btree, void * key, char * entry, long long * dirIndex) { long extentSize; void *extent; @@ -732,7 +735,7 @@ while (1) { // Read the current node. ReadExtent(extent, extentSize, extentFile, - (long long)curNode * nodeSize, nodeSize, nodeBuf, 1); + (long long) curNode * nodeSize, nodeSize, nodeBuf, 1); // Find the matching key. lowerBound = 0; @@ -800,7 +803,7 @@ index = 0; curNode = SWAP_BE32(node->fLink); } - *dirIndex = curNode * nodeSize + index; + *dirIndex = (long long) curNode * nodeSize + index; } free(nodeBuf); Index: branches/meklort/i386/libsaio/acpi_patcher.c =================================================================== --- branches/meklort/i386/libsaio/acpi_patcher.c (revision 0) +++ branches/meklort/i386/libsaio/acpi_patcher.c (revision 505) @@ -0,0 +1,1027 @@ +/* + * Copyright 2008 mackerintel + */ + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "acpi.h" +#include "efi_tables.h" +#include "fake_efi.h" +#include "acpi_patcher.h" +#include "platform.h" +#include "cpu.h" +#include "aml_generator.h" + +#ifndef DEBUG_ACPI +#define DEBUG_ACPI 0 +#endif + +#if DEBUG_ACPI==2 +#define DBG(x...) {printf(x); sleep(1);} +#elif DEBUG_ACPI==1 +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif + +// Slice: New signature compare function +boolean_t tableSign(char *table, const char *sgn) +{ + int i; + for (i=0; i<4; i++) { + if ((table[i] &~0x20) != (sgn[i] &~0x20)) { + return false; + } + } + return true; +} + +/* 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; +} + +/* 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; +} +/** The folowing ACPI Table search algo. should be reused anywhere needed:*/ +int search_and_get_acpi_fd(const char * filename, const char ** outDirspec) +{ + int fd = 0; + char dirSpec[512] = ""; + + // Try finding 'filename' in the usual places + // Start searching any potential location for ACPI Table + sprintf(dirSpec, "%s", filename); + fd = open(dirSpec, 0); + if (fd < 0) + { + sprintf(dirSpec, "/Extra/%s", filename); + fd = open(dirSpec, 0); + if (fd < 0) + { + sprintf(dirSpec, "bt(0,0)/Extra/%s", filename); + fd = open(dirSpec, 0); + } + } + + if (fd < 0) + { + // NOT FOUND: + verbose("ACPI table not found: %s\n", filename); + *dirSpec = '\0'; + } + + if (outDirspec) *outDirspec = dirSpec; + return fd; +} + + +void *loadACPITable (const char * filename) +{ + void *tableAddr; + const char * dirspec=NULL; + + int fd = search_and_get_acpi_fd(filename, &dirspec); + + if (fd>=0) + { + tableAddr=(void*)AllocateKernelMemory(file_size (fd)); + if (tableAddr) + { + if (read (fd, tableAddr, file_size (fd))!=file_size (fd)) + { + printf("Couldn't read table %s\n",dirspec); + free (tableAddr); + close (fd); + return NULL; + } + + DBG("Table %s read and stored at: %x\n", dirspec, tableAddr); + close (fd); + return tableAddr; + } + close (fd); + printf("Couldn't allocate memory for table \n", dirspec); + } + //printf("Couldn't find table %s\n", filename); + return NULL; +} + +uint8_t acpi_cpu_count = 0; +char* acpi_cpu_name[32]; + +void get_acpi_cpu_names(unsigned char* dsdt, uint32_t length) +{ + uint32_t i; + + for (i=0; i> 6); + + bool add_name = true; + + uint8_t j; + + for (j=0; j<4; j++) + { + char c = dsdt[offset+j]; + + if (!aml_isvalidchar(c)) + { + add_name = false; + verbose("Invalid character found in ProcessorOP 0x%x!\n", c); + break; + } + } + + if (add_name) + { + acpi_cpu_name[acpi_cpu_count] = malloc(4); + memcpy(acpi_cpu_name[acpi_cpu_count], dsdt+offset, 4); + i = offset + 5; + + verbose("Found ACPI CPU: %c%c%c%c\n", acpi_cpu_name[acpi_cpu_count][0], acpi_cpu_name[acpi_cpu_count][1], acpi_cpu_name[acpi_cpu_count][2], acpi_cpu_name[acpi_cpu_count][3]); + + if (++acpi_cpu_count == 32) return; + } + } + } +} + +struct acpi_2_ssdt *generate_cst_ssdt(struct acpi_2_fadt* fadt) +{ + char ssdt_header[] = + { + 0x53, 0x53, 0x44, 0x54, 0xE7, 0x00, 0x00, 0x00, /* SSDT.... */ + 0x01, 0x17, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x41, /* ..PmRefA */ + 0x43, 0x70, 0x75, 0x43, 0x73, 0x74, 0x00, 0x00, /* CpuCst.. */ + 0x00, 0x10, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* ....INTL */ + 0x31, 0x03, 0x10, 0x20 /* 1.._ */ + }; + + char cstate_resource_template[] = + { + 0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F, + 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x79, 0x00 + }; + + if (Platform.CPU.Vendor != 0x756E6547) { + verbose ("Not an Intel platform: C-States will not be generated !!!\n"); + return NULL; + } + + if (fadt == NULL) { + verbose ("FACP not exists: C-States will not be generated !!!\n"); + return NULL; + } + + struct acpi_2_dsdt* dsdt = (void*)fadt->DSDT; + + if (dsdt == NULL) { + verbose ("DSDT not found: C-States will not be generated !!!\n"); + return NULL; + } + + if (acpi_cpu_count == 0) + get_acpi_cpu_names((void*)dsdt, dsdt->Length); + + if (acpi_cpu_count > 0) + { + bool c2_enabled = fadt->C2_Latency < 100; + bool c3_enabled = fadt->C3_Latency < 1000; + bool c4_enabled = false; + + getBoolForKey(kEnableC4States, &c4_enabled, &bootInfo->bootConfig); + + unsigned char cstates_count = 1 + (c2_enabled ? 1 : 0) + (c3_enabled ? 1 : 0); + + struct aml_chunk* root = aml_create_node(NULL); + aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header + struct aml_chunk* scop = aml_add_scope(root, "\\_PR_"); + struct aml_chunk* name = aml_add_name(scop, "CST_"); + struct aml_chunk* pack = aml_add_package(name); + aml_add_byte(pack, cstates_count); + + struct aml_chunk* tmpl = aml_add_package(pack); + cstate_resource_template[11] = 0x00; // C1 + aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template)); + aml_add_byte(tmpl, 0x01); // C1 + aml_add_byte(tmpl, 0x01); // Latency + aml_add_word(tmpl, 0x03e8); // Power + + // C2 + if (c2_enabled) + { + tmpl = aml_add_package(pack); + cstate_resource_template[11] = 0x10; // C2 + aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template)); + aml_add_byte(tmpl, 0x02); // C2 + aml_add_byte(tmpl, fadt->C2_Latency); + aml_add_word(tmpl, 0x01f4); // Power + } + // C4 + if (c4_enabled) + { + tmpl = aml_add_package(pack); + cstate_resource_template[11] = 0x30; // C4 + aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template)); + aml_add_byte(tmpl, 0x04); // C4 + aml_add_word(tmpl, fadt->C3_Latency / 2); // TODO: right latency for C4 + aml_add_byte(tmpl, 0xfa); // Power + } + else + // C3 + if (c3_enabled) + { + tmpl = aml_add_package(pack); + cstate_resource_template[11] = 0x20; // C3 + aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template)); + aml_add_byte(tmpl, 0x03); // C3 + aml_add_word(tmpl, fadt->C3_Latency); + aml_add_word(tmpl, 0x015e); // Power + } + + + // Aliaces + int i; + for (i = 0; i < acpi_cpu_count; i++) + { + char name[9]; + sprintf(name, "_PR_%c%c%c%c", acpi_cpu_name[i][0], acpi_cpu_name[i][1], acpi_cpu_name[i][2], acpi_cpu_name[i][3]); + + scop = aml_add_scope(root, name); + aml_add_alias(scop, "CST_", "_CST"); + } + + aml_calculate_size(root); + + struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size); + + aml_write_node(root, (void*)ssdt, 0); + + ssdt->Length = root->Size; + ssdt->Checksum = 0; + ssdt->Checksum = 256 - checksum8(ssdt, ssdt->Length); + + aml_destroy_node(root); + + //dumpPhysAddr("C-States SSDT content: ", ssdt, ssdt->Length); + + verbose ("SSDT with CPU C-States generated successfully\n"); + + return ssdt; + } + else + { + verbose ("ACPI CPUs not found: C-States not generated !!!\n"); + } + + return NULL; +} + +struct acpi_2_ssdt *generate_pss_ssdt(struct acpi_2_dsdt* dsdt) +{ + char ssdt_header[] = + { + 0x53, 0x53, 0x44, 0x54, 0x7E, 0x00, 0x00, 0x00, /* SSDT.... */ + 0x01, 0x6A, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x00, /* ..PmRef. */ + 0x43, 0x70, 0x75, 0x50, 0x6D, 0x00, 0x00, 0x00, /* CpuPm... */ + 0x00, 0x30, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* .0..INTL */ + 0x31, 0x03, 0x10, 0x20, /* 1.._ */ + }; + + if (Platform.CPU.Vendor != 0x756E6547) { + verbose ("Not an Intel platform: P-States will not be generated !!!\n"); + return NULL; + } + + if (!(Platform.CPU.Features & CPU_FEATURE_MSR)) { + verbose ("Unsupported CPU: P-States will not be generated !!!\n"); + return NULL; + } + + if (acpi_cpu_count == 0) + get_acpi_cpu_names((void*)dsdt, dsdt->Length); + + if (acpi_cpu_count > 0) + { + struct p_state initial, maximum, minimum, p_states[32]; + uint8_t p_states_count = 0; + + // Retrieving P-States, ported from code by superhai (c) + switch (Platform.CPU.Family) { + case 0x06: + { + switch (Platform.CPU.Model) + { + case 0x0D: // ? + case CPU_MODEL_YONAH: // Yonah + case CPU_MODEL_MEROM: // Merom + case CPU_MODEL_PENRYN: // Penryn + case CPU_MODEL_ATOM: // Intel Atom (45nm) + { + bool cpu_dynamic_fsb = false; + + if (rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 27)) + { + wrmsr64(MSR_IA32_EXT_CONFIG, (rdmsr64(MSR_IA32_EXT_CONFIG) | (1 << 28))); + delay(1); + cpu_dynamic_fsb = rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 28); + } + + bool cpu_noninteger_bus_ratio = (rdmsr64(MSR_IA32_PERF_STATUS) & (1ULL << 46)); + + initial.Control = rdmsr64(MSR_IA32_PERF_STATUS); + + maximum.Control = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 32) & 0x1F3F) | (0x4000 * cpu_noninteger_bus_ratio); + maximum.CID = ((maximum.FID & 0x1F) << 1) | cpu_noninteger_bus_ratio; + + minimum.FID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 24) & 0x1F) | (0x80 * cpu_dynamic_fsb); + minimum.VID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 48) & 0x3F); + + if (minimum.FID == 0) + { + uint64_t msr; + uint8_t i; + // Probe for lowest fid + for (i = maximum.FID; i >= 0x6; i--) + { + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (i << 8) | minimum.VID); + intel_waitforsts(); + minimum.FID = (rdmsr64(MSR_IA32_PERF_STATUS) >> 8) & 0x1F; + delay(1); + } + + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID); + intel_waitforsts(); + } + + if (minimum.VID == maximum.VID) + { + uint64_t msr; + uint8_t i; + // Probe for lowest vid + for (i = maximum.VID; i > 0xA; i--) + { + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (minimum.FID << 8) | i); + intel_waitforsts(); + minimum.VID = rdmsr64(MSR_IA32_PERF_STATUS) & 0x3F; + delay(1); + } + + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID); + intel_waitforsts(); + } + + minimum.CID = ((minimum.FID & 0x1F) << 1) >> cpu_dynamic_fsb; + + // Sanity check + if (maximum.CID < minimum.CID) + { + DBG("Insane FID values!"); + p_states_count = 1; + } + else + { + // Finalize P-States + // Find how many P-States machine supports + p_states_count = maximum.CID - minimum.CID + 1; + + if (p_states_count > 32) + p_states_count = 32; + + uint8_t vidstep; + uint8_t i = 0, u, invalid = 0; + + vidstep = ((maximum.VID << 2) - (minimum.VID << 2)) / (p_states_count - 1); + + for (u = 0; u < p_states_count; u++) + { + i = u - invalid; + + p_states[i].CID = maximum.CID - u; + p_states[i].FID = (p_states[i].CID >> 1); + + if (p_states[i].FID < 0x6) + { + if (cpu_dynamic_fsb) + p_states[i].FID = (p_states[i].FID << 1) | 0x80; + } + else if (cpu_noninteger_bus_ratio) + { + p_states[i].FID = p_states[i].FID | (0x40 * (p_states[i].CID & 0x1)); + } + + if (i && p_states[i].FID == p_states[i-1].FID) + invalid++; + + p_states[i].VID = ((maximum.VID << 2) - (vidstep * u)) >> 2; + + uint32_t multiplier = p_states[i].FID & 0x1f; // = 0x08 + bool half = p_states[i].FID & 0x40; // = 0x01 + bool dfsb = p_states[i].FID & 0x80; // = 0x00 + uint32_t fsb = Platform.CPU.FSBFrequency / 1000000; // = 400 + uint32_t halffsb = (fsb + 1) >> 1; // = 200 + uint32_t frequency = (multiplier * fsb); // = 3200 + + p_states[i].Frequency = (frequency + (half * halffsb)) >> dfsb; // = 3200 + 200 = 3400 + } + + p_states_count -= invalid; + } + } break; + case CPU_MODEL_FIELDS: + case CPU_MODEL_DALES: + case CPU_MODEL_DALES_32NM: + case CPU_MODEL_NEHALEM: + case CPU_MODEL_NEHALEM_EX: + case CPU_MODEL_WESTMERE: + case CPU_MODEL_WESTMERE_EX: + default: + verbose ("Unsupported CPU: P-States not generated !!!\n"); + break; + } + } + } + + // Generating SSDT + if (p_states_count > 0) + { + int i; + + struct aml_chunk* root = aml_create_node(NULL); + aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header + struct aml_chunk* scop = aml_add_scope(root, "\\_PR_"); + struct aml_chunk* name = aml_add_name(scop, "PSS_"); + struct aml_chunk* pack = aml_add_package(name); + + for (i = 0; i < p_states_count; i++) + { + struct aml_chunk* pstt = aml_add_package(pack); + + aml_add_dword(pstt, p_states[i].Frequency); + aml_add_dword(pstt, 0x00000000); // Power + aml_add_dword(pstt, 0x0000000A); // Latency + aml_add_dword(pstt, 0x0000000A); // Latency + aml_add_dword(pstt, p_states[i].Control); + aml_add_dword(pstt, i+1); // Status + } + + // Add aliaces + for (i = 0; i < acpi_cpu_count; i++) + { + char name[9]; + sprintf(name, "_PR_%c%c%c%c", acpi_cpu_name[i][0], acpi_cpu_name[i][1], acpi_cpu_name[i][2], acpi_cpu_name[i][3]); + + scop = aml_add_scope(root, name); + aml_add_alias(scop, "PSS_", "_PSS"); + } + + aml_calculate_size(root); + + struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size); + + aml_write_node(root, (void*)ssdt, 0); + + ssdt->Length = root->Size; + ssdt->Checksum = 0; + ssdt->Checksum = 256 - checksum8(ssdt, ssdt->Length); + + aml_destroy_node(root); + + //dumpPhysAddr("P-States SSDT content: ", ssdt, ssdt->Length); + + verbose ("SSDT with CPU P-States generated successfully\n"); + + return ssdt; + } + } + else + { + verbose ("ACPI CPUs not found: P-States not generated !!!\n"); + } + + return NULL; +} + +struct acpi_2_fadt *patch_fadt(struct acpi_2_fadt *fadt, struct acpi_2_dsdt *new_dsdt) +{ + extern void setupSystemType(); + + struct acpi_2_fadt *fadt_mod; + bool fadt_rev2_needed = false; + bool fix_restart; + const char * value; + + // Restart Fix + if (Platform.CPU.Vendor == 0x756E6547) { /* Intel */ + fix_restart = true; + getBoolForKey(kRestartFix, &fix_restart, &bootInfo->bootConfig); + } else { + verbose ("Not an Intel platform: Restart Fix not applied !!!\n"); + fix_restart = false; + } + + if (fix_restart) fadt_rev2_needed = true; + + // Allocate new fadt table + if (fadt->Length < 0x84 && fadt_rev2_needed) + { + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84); + memcpy(fadt_mod, fadt, fadt->Length); + fadt_mod->Length = 0x84; + fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions) + } + else + { + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length); + memcpy(fadt_mod, fadt, fadt->Length); + } + // Determine system type / PM_Model + if ( (value=getStringForKey(kSystemType, &bootInfo->bootConfig))!=NULL) + { + if (Platform.Type > 6) + { + if(fadt_mod->PM_Profile<=6) + Platform.Type = fadt_mod->PM_Profile; // get the fadt if correct + else + Platform.Type = 1; /* Set a fixed value (Desktop) */ + verbose("Error: system-type must be 0..6. Defaulting to %d !\n", Platform.Type); + } + else + Platform.Type = (unsigned char) strtoul(value, NULL, 10); + } + // Set PM_Profile from System-type if only user wanted this value to be forced + if (fadt_mod->PM_Profile != Platform.Type) + { + if (value) + { // user has overriden the SystemType so take care of it in FACP + verbose("FADT: changing PM_Profile from 0x%02x to 0x%02x\n", fadt_mod->PM_Profile, Platform.Type); + fadt_mod->PM_Profile = Platform.Type; + } + else + { // PM_Profile has a different value and no override has been set, so reflect the user value to ioregs + Platform.Type = fadt_mod->PM_Profile <= 6 ? fadt_mod->PM_Profile : 1; + } + } + // We now have to write the systemm-type in ioregs: we cannot do it before in setupDeviceTree() + // because we need to take care of facp original content, if it is correct. + setupSystemType(); + + // Patch FADT to fix restart + if (fix_restart) + { + fadt_mod->Flags|= 0x400; + fadt_mod->Reset_SpaceID = 0x01; // System I/O + fadt_mod->Reset_BitWidth = 0x08; // 1 byte + fadt_mod->Reset_BitOffset = 0x00; // Offset 0 + fadt_mod->Reset_AccessWidth = 0x01; // Byte access + fadt_mod->Reset_Address = 0x0cf9; // Address of the register + fadt_mod->Reset_Value = 0x06; // Value to write to reset the system + verbose("FADT: Restart Fix applied!\n"); + } + + // Patch DSDT Address if we have loaded DSDT.aml + if(new_dsdt) + { + DBG("DSDT: Old @%x,%x, ",fadt_mod->DSDT,fadt_mod->X_DSDT); + + fadt_mod->DSDT=(uint32_t)new_dsdt; + if ((uint32_t)(&(fadt_mod->X_DSDT))-(uint32_t)fadt_mod+8<=fadt_mod->Length) + fadt_mod->X_DSDT=(uint32_t)new_dsdt; + + DBG("New @%x,%x\n",fadt_mod->DSDT,fadt_mod->X_DSDT); + + verbose("FADT: Using custom DSDT!\n"); + } + + // Correct the checksum + fadt_mod->Checksum=0; + fadt_mod->Checksum=256-checksum8(fadt_mod,fadt_mod->Length); + + return fadt_mod; +} + +/* Setup ACPI without replacing DSDT. */ +int setupAcpiNoMod() +{ + // addConfigurationTable(&gEfiAcpiTableGuid, getAddressOfAcpiTable(), "ACPI"); + // addConfigurationTable(&gEfiAcpi20TableGuid, getAddressOfAcpi20Table(), "ACPI_20"); + /* XXX aserebln why uint32 cast if pointer is uint64 ? */ + acpi10_p = (uint32_t)getAddressOfAcpiTable(); + acpi20_p = (uint32_t)getAddressOfAcpi20Table(); + addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI"); + if(acpi20_p) addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20"); + return 1; +} + +/* Setup ACPI. Replace DSDT if DSDT.aml is found */ +int setupAcpi(void) +{ + int version; + void *new_dsdt; + + const char *filename; + char dirSpec[128]; + int len = 0; + + // Try using the file specified with the DSDT option + if (getValueForKey(kDSDT, &filename, &len, &bootInfo->bootConfig)) + { + sprintf(dirSpec, filename); + } + else + { + sprintf(dirSpec, "DSDT.aml"); + } + + // Load replacement DSDT + new_dsdt = loadACPITable(dirSpec); + // Mozodojo: going to patch FACP and load SSDT's even if DSDT.aml is not present + /*if (!new_dsdt) + { + return setupAcpiNoMod(); + }*/ + + // Mozodojo: Load additional SSDTs + struct acpi_2_ssdt *new_ssdt[32]; // 30 + 2 additional tables for pss & cst + int ssdt_count=0; + + // SSDT Options + bool drop_ssdt=false, generate_pstates=false, generate_cstates=false; + + getBoolForKey(kDropSSDT, &drop_ssdt, &bootInfo->bootConfig); + getBoolForKey(kGeneratePStates, &generate_pstates, &bootInfo->bootConfig); + getBoolForKey(kGenerateCStates, &generate_cstates, &bootInfo->bootConfig); + + { + int i; + + for (i=0; i<30; i++) + { + char filename[512]; + + sprintf(filename, i>0?"SSDT-%d.aml":"SSDT.aml", i); + + if(new_ssdt[ssdt_count] = loadACPITable(filename)) + { + ssdt_count++; + } + else + { + break; + } + } + } + + // Do the same procedure for both versions of ACPI + for (version=0; version<2; version++) { + struct acpi_2_rsdp *rsdp, *rsdp_mod; + struct acpi_2_rsdt *rsdt, *rsdt_mod; + int rsdplength; + + // Find original rsdp + rsdp=(struct acpi_2_rsdp *)(version?getAddressOfAcpi20Table():getAddressOfAcpiTable()); + if (!rsdp) + { + DBG("No ACPI version %d found. Ignoring\n", version+1); + if (version) + addConfigurationTable(&gEfiAcpi20TableGuid, NULL, "ACPI_20"); + else + addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI"); + continue; + } + rsdplength=version?rsdp->Length:20; + + DBG("RSDP version %d found @%x. Length=%d\n",version+1,rsdp,rsdplength); + + /* FIXME: no check that memory allocation succeeded + * Copy and patch RSDP,RSDT, XSDT and FADT + * For more info see ACPI Specification pages 110 and following + */ + + rsdp_mod=(struct acpi_2_rsdp *) AllocateKernelMemory(rsdplength); + memcpy(rsdp_mod, rsdp, rsdplength); + rsdt=(struct acpi_2_rsdt *)(rsdp->RsdtAddress); + + DBG("RSDT @%x, Length %d\n",rsdt, rsdt->Length); + + if (rsdt && (uint32_t)rsdt !=0xffffffff && rsdt->Length<0x10000) + { + uint32_t *rsdt_entries; + int rsdt_entries_num; + int dropoffset=0, i; + + // mozo: using malloc cos I didn't found how to free already allocated kernel memory + rsdt_mod=(struct acpi_2_rsdt *)malloc(rsdt->Length); + memcpy (rsdt_mod, rsdt, rsdt->Length); + rsdp_mod->RsdtAddress=(uint32_t)rsdt_mod; + rsdt_entries_num=(rsdt_mod->Length-sizeof(struct acpi_2_rsdt))/4; + rsdt_entries=(uint32_t *)(rsdt_mod+1); + for (i=0;iLength); + + if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000) + { + printf("FADT incorrect. Not modified\n"); + continue; + } + + fadt_mod = patch_fadt(fadt, new_dsdt); + rsdt_entries[i-dropoffset]=(uint32_t)fadt_mod; + + // Generate _CST SSDT + if (generate_cstates && (new_ssdt[ssdt_count] = generate_cst_ssdt(fadt_mod))) + { + generate_cstates = false; // Generate SSDT only once! + ssdt_count++; + } + + // Generating _PSS SSDT + if (generate_pstates && (new_ssdt[ssdt_count] = generate_pss_ssdt((void*)fadt_mod->DSDT))) + { + generate_pstates = false; // Generate SSDT only once! + ssdt_count++; + } + + continue; + } + } + DBG("\n"); + + // Allocate rsdt in Kernel memory area + rsdt_mod->Length += 4*ssdt_count - 4*dropoffset; + struct acpi_2_rsdt *rsdt_copy = (struct acpi_2_rsdt *)AllocateKernelMemory(rsdt_mod->Length); + memcpy (rsdt_copy, rsdt_mod, rsdt_mod->Length); + free(rsdt_mod); rsdt_mod = rsdt_copy; + rsdp_mod->RsdtAddress=(uint32_t)rsdt_mod; + rsdt_entries_num=(rsdt_mod->Length-sizeof(struct acpi_2_rsdt))/4; + rsdt_entries=(uint32_t *)(rsdt_mod+1); + + // Mozodojo: Insert additional SSDTs into RSDT + if(ssdt_count>0) + { + int j; + + for (j=0; jChecksum); + + rsdt_mod->Checksum=0; + rsdt_mod->Checksum=256-checksum8(rsdt_mod,rsdt_mod->Length); + + DBG("New checksum %d at %x\n", rsdt_mod->Checksum,rsdt_mod); + } + else + { + rsdp_mod->RsdtAddress=0; + printf("RSDT not found or RSDT incorrect\n"); + } + + if (version) + { + struct acpi_2_xsdt *xsdt, *xsdt_mod; + + // FIXME: handle 64-bit address correctly + + xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress); + DBG("XSDT @%x;%x, Length=%d\n", (uint32_t)(rsdp->XsdtAddress>>32),(uint32_t)rsdp->XsdtAddress, + xsdt->Length); + if (xsdt && (uint64_t)rsdp->XsdtAddress<0xffffffff && xsdt->Length<0x10000) + { + uint64_t *xsdt_entries; + int xsdt_entries_num, i; + int dropoffset=0; + + // mozo: using malloc cos I didn't found how to free already allocated kernel memory + xsdt_mod=(struct acpi_2_xsdt*)malloc(xsdt->Length); + memcpy(xsdt_mod, xsdt, xsdt->Length); + rsdp_mod->XsdtAddress=(uint32_t)xsdt_mod; + xsdt_entries_num=(xsdt_mod->Length-sizeof(struct acpi_2_xsdt))/8; + xsdt_entries=(uint64_t *)(xsdt_mod+1); + for (i=0;i>32),fadt, + fadt->Length); + + if (!fadt || (uint64_t)xsdt_entries[i] >= 0xffffffff || fadt->Length>0x10000) + { + verbose("FADT incorrect or after 4GB. Dropping XSDT\n"); + goto drop_xsdt; + } + + fadt_mod = patch_fadt(fadt, new_dsdt); + xsdt_entries[i-dropoffset]=(uint32_t)fadt_mod; + + DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]); + + // Generate _CST SSDT + if (generate_cstates && (new_ssdt[ssdt_count] = generate_cst_ssdt(fadt_mod))) + { + generate_cstates = false; // Generate SSDT only once! + ssdt_count++; + } + + // Generating _PSS SSDT + if (generate_pstates && (new_ssdt[ssdt_count] = generate_pss_ssdt((void*)fadt_mod->DSDT))) + { + generate_pstates = false; // Generate SSDT only once! + ssdt_count++; + } + + continue; + } + + DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]); + + } + + // Allocate xsdt in Kernel memory area + xsdt_mod->Length += 8*ssdt_count - 8*dropoffset; + struct acpi_2_xsdt *xsdt_copy = (struct acpi_2_xsdt *)AllocateKernelMemory(xsdt_mod->Length); + memcpy(xsdt_copy, xsdt_mod, xsdt_mod->Length); + free(xsdt_mod); xsdt_mod = xsdt_copy; + rsdp_mod->XsdtAddress=(uint32_t)xsdt_mod; + xsdt_entries_num=(xsdt_mod->Length-sizeof(struct acpi_2_xsdt))/8; + xsdt_entries=(uint64_t *)(xsdt_mod+1); + + // Mozodojo: Insert additional SSDTs into XSDT + if(ssdt_count>0) + { + int j; + + for (j=0; jChecksum=0; + xsdt_mod->Checksum=256-checksum8(xsdt_mod,xsdt_mod->Length); + } + else + { + drop_xsdt: + + DBG("About to drop XSDT\n"); + + /*FIXME: Now we just hope that if MacOS doesn't find XSDT it reverts to RSDT. + * A Better strategy would be to generate + */ + + rsdp_mod->XsdtAddress=0xffffffffffffffffLL; + verbose("XSDT not found or XSDT incorrect\n"); + } + } + + // Correct the checksum of RSDP + + DBG("RSDP: Original checksum %d, ", rsdp_mod->Checksum); + + rsdp_mod->Checksum=0; + rsdp_mod->Checksum=256-checksum8(rsdp_mod,20); + + DBG("New checksum %d\n", rsdp_mod->Checksum); + + if (version) + { + DBG("RSDP: Original extended checksum %d", rsdp_mod->ExtendedChecksum); + + rsdp_mod->ExtendedChecksum=0; + rsdp_mod->ExtendedChecksum=256-checksum8(rsdp_mod,rsdp_mod->Length); + + DBG("New extended checksum %d\n", rsdp_mod->ExtendedChecksum); + + } + + //verbose("Patched ACPI version %d DSDT\n", version+1); + if (version) + { + /* XXX aserebln why uint32 cast if pointer is uint64 ? */ + acpi20_p = (uint32_t)rsdp_mod; + addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20"); + } + else + { + /* XXX aserebln why uint32 cast if pointer is uint64 ? */ + acpi10_p = (uint32_t)rsdp_mod; + addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI"); + } + } +#if DEBUG_ACPI + printf("Press a key to continue... (DEBUG_ACPI)\n"); + getc(); +#endif + return 1; +} Index: branches/meklort/i386/libsaio/hfs.h =================================================================== --- branches/meklort/i386/libsaio/hfs.h (revision 504) +++ branches/meklort/i386/libsaio/hfs.h (revision 505) @@ -23,7 +23,7 @@ extern long HFSInitPartition(CICell ih); extern long HFSLoadFile(CICell ih, char * filePath); extern long HFSReadFile(CICell ih, char * filePath, void *base, uint64_t offset, uint64_t length); -extern long HFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex, +extern long HFSGetDirEntry(CICell ih, char * dirPath, long long * dirIndex, char ** name, long * flags, long * time, FinderInfo * finderInfo, long * infoValid); extern void HFSGetDescription(CICell ih, char *str, long strMaxLen); Index: branches/meklort/i386/libsaio/spd.c =================================================================== --- branches/meklort/i386/libsaio/spd.c (revision 504) +++ branches/meklort/i386/libsaio/spd.c (revision 505) @@ -1,6 +1,9 @@ /* * spd.c - serial presence detect memory information - * (restored from pcefi10.5) + * + * Originally restored from pcefi10.5 + * Dynamic mem detection original impl. by Rekursor + * System profiler fix and other fixes by Mozodojo. */ #include "libsaio.h" @@ -85,35 +88,64 @@ while (!( inb(base + SMBHSTSTS) & 0x02)) // wait til command finished { rdtsc(l2, h2); - t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform.CPU.TSCFrequency / 40); - if (t > 10) - break; // break after 10ms + t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform.CPU.TSCFrequency / 100); + if (t > 5) + break; // break after 5ms } return inb(base + SMBHSTDAT); } +/* SPD i2c read optimization: prefetch only what we need, read non prefetcheable bytes on the fly */ +#define READ_SPD(spd, base, slot, x) spd[x] = smb_read_byte_intel(base, 0x50 + slot, x) + +int spd_indexes[] = { + SPD_MEMORY_TYPE, + SPD_DDR3_MEMORY_BANK, + SPD_DDR3_MEMORY_CODE, + SPD_NUM_ROWS, + SPD_NUM_COLUMNS, + SPD_NUM_DIMM_BANKS, + SPD_NUM_BANKS_PER_SDRAM, + 4,7,8,9,12,64, /* TODO: give names to these values */ + 95,96,97,98, 122,123,124,125 /* UIS */ +}; +#define SPD_INDEXES_SIZE (sizeof(spd_indexes) / sizeof(int)) + +/** Read from spd *used* values only*/ +static void init_spd(char * spd, uint32_t base, int slot) +{ + int i; + for (i=0; i< SPD_INDEXES_SIZE; i++) { + READ_SPD(spd, base, slot, spd_indexes[i]); + } +} + /** Get Vendor Name from spd, 2 cases handled DDR3 and DDR2, have different formats, always return a valid ptr.*/ -const char * getVendorName(RamSlotInfo_t* slot) +const char * getVendorName(RamSlotInfo_t* slot, uint32_t base, int slot_num) { uint8_t bank = 0; uint8_t code = 0; int i = 0; - const char * spd = slot->spd; + uint8_t * spd = (uint8_t *) slot->spd; if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) { // DDR3 - bank = spd[0x75]; - code = spd[0x76]; + bank = (spd[SPD_DDR3_MEMORY_BANK] & 0x07f); // constructors like Patriot use b7=1 + code = spd[SPD_DDR3_MEMORY_CODE]; for (i=0; i < VEN_MAP_SIZE; i++) if (bank==vendorMap[i].bank && code==vendorMap[i].code) return vendorMap[i].name; } else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) { - if(spd[0x40]==0x7f) { - for (i=0x40; i<0x48 && spd[i]==0x7f;i++) bank++; + if(spd[64]==0x7f) { + for (i=64; i<72 && spd[i]==0x7f;i++) { + bank++; + READ_SPD(spd, base, slot_num,i+1); // prefetch next spd byte to read for next loop + } + READ_SPD(spd, base, slot_num,i); code = spd[i]; } else { - code = spd[0x40]; + code = spd[64]; bank = 0; } for (i=0; i < VEN_MAP_SIZE; i++) @@ -158,61 +190,62 @@ return 800; // default freq for unknown types } -#define UIS(a) ((uint32_t)spd[a]) +#define SMST(a) ((uint8_t)((spd[a] & 0xf0) >> 4)) +#define SLST(a) ((uint8_t)(spd[a] & 0x0f)) /** Get DDR3 or DDR2 serial number, 0 most of the times, always return a valid ptr */ const char *getDDRSerial(const char* spd) { static char asciiSerial[16]; - static uint8_t serialnum=0; - uint32_t ret=0; - - if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) {// DDR3 - ret = UIS(122) | (UIS(123)<<8) | (UIS(124)<<16) | ((UIS(125)&0x7f)<<24); + + if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) // DDR3 + { + sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(122) /*& 0x7*/, SLST(122), SMST(123), SLST(123), SMST(124), SLST(124), SMST(125), SLST(125)); } - else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) { // DDR2 or DDR - ret = UIS(95) | (UIS(96)<<8) | (UIS(97)<<16) | ((UIS(98)&0x7f)<<24); + else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) // DDR2 or DDR + { + sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(95) /*& 0x7*/, SLST(95), SMST(96), SLST(96), SMST(97), SLST(97), SMST(98), SLST(98)); } - if (!ret) sprintf(asciiSerial, "10000000%d", serialnum++); - else sprintf(asciiSerial, "%d", ret); - - return asciiSerial; + return strdup(asciiSerial); } /** Get DDR3 or DDR2 Part Number, always return a valid ptr */ -const char * getDDRPartNum(const char* spd) +const char * getDDRPartNum(char* spd, uint32_t base, int slot) { - const char * sPart = NULL; - int i; - bool bZero = false; + static char asciiPartNo[32]; + int i, start=0, index = 0; - if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) - sPart = &spd[128]; - else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) - sPart = &spd[73]; - if (sPart) { // Check that the spd part name is zero terminated and that it is ascii: - for (i=0; i<32; i++) { - if (sPart[i]==0) { - bZero = true; - break; - } - else if ( !isascii(sPart[i]) ) { - sPart = NULL; - break; - } - } - } - return ( sPart==NULL || !(*sPart) || !bZero ) ? - "N/A" : sPart; + if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) { + start = 128; + } + else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) { + start = 73; + } + + // Check that the spd part name is zero terminated and that it is ascii: + bzero(asciiPartNo, sizeof(asciiPartNo)); + char c; + for (i=start; i < start + sizeof(asciiPartNo); i++) { + READ_SPD(spd, base, slot, i); // only read once the corresponding model part (ddr3 or ddr2) + c = spd[i]; + if (isalpha(c) || isdigit(c) || ispunct(c)) // It seems that System Profiler likes only letters and digits... + asciiPartNo[index++] = c; + else if (!isascii(c)) + break; + } + + return strdup(asciiPartNo); + return NULL; } int mapping []= {0,2,1,3,4,6,5,7,8,10,9,11}; + /** Read from smbus the SPD content and interpret it for detecting memory attributes */ static void read_smb_intel(pci_dt_t *smbus_dev) { - int i, x, speed; + int i, speed; uint8_t spd_size, spd_type; uint32_t base; bool dump = false; @@ -225,23 +258,24 @@ bool fullBanks = // needed at least for laptops Platform.DMI.MemoryModules == Platform.DMI.MaxMemorySlots; // Search MAX_RAM_SLOTS slots + char spdbuf[256]; + for (i = 0; i < MAX_RAM_SLOTS; i++){ slot = &Platform.RAM.DIMM[i]; spd_size = smb_read_byte_intel(base, 0x50 + i, 0); - // Check spd is present if (spd_size && (spd_size != 0xff) ) { - slot->spd = malloc(spd_size); - if (slot->spd == NULL) continue; + slot->spd = spdbuf; slot->InUse = true; bzero(slot->spd, spd_size); // Copy spd data into buffer - for (x = 0; x < spd_size; x++) - slot->spd[x] = smb_read_byte_intel(base, 0x50 + i, x); + //for (x = 0; x < spd_size; x++) slot->spd[x] = smb_read_byte_intel(base, 0x50 + i, x); + init_spd(slot->spd, base, i); + switch (slot->spd[SPD_MEMORY_TYPE]) { case SPD_MEMORY_TYPE_SDRAM_DDR2: @@ -260,15 +294,30 @@ spd_type = (slot->spd[SPD_MEMORY_TYPE] < ((char) 12) ? slot->spd[SPD_MEMORY_TYPE] : 0); slot->Type = spd_mem_to_smbios[spd_type]; - slot->PartNo = strdup(getDDRPartNum(slot->spd) ); - slot->Vendor = strdup(getVendorName(slot) ); - slot->SerialNo = strdup(getDDRSerial(slot->spd)); + slot->PartNo = getDDRPartNum(slot->spd, base, i); + slot->Vendor = getVendorName(slot, base, i); + slot->SerialNo = getDDRSerial(slot->spd); // determine spd speed speed = getDDRspeedMhz(slot->spd); - if (speed > slot->Frequency) slot->Frequency = speed; // just in case dmi wins on spd - if(dump) { - printf("Slot %d Type %d %dMB (%s) %dMHz Vendor=%s, PartNo=%s SerialNo=%s\n", + if (slot->FrequencyFrequency = speed; + + // pci memory controller if available, is more reliable + if (Platform.RAM.Frequency > 0) { + uint32_t freq = (uint32_t)Platform.RAM.Frequency / 500000; + // now round off special cases + uint32_t fmod100 = freq %100; + switch(fmod100) { + case 1: freq--; break; + case 32: freq++; break; + case 65: freq++; break; + case 98: freq+=2;break; + case 99: freq++; break; + } + slot->Frequency = freq; + } + + verbose("Slot: %d Type %d %dMB (%s) %dMHz Vendor=%s\n PartNo=%s SerialNo=%s\n", i, (int)slot->Type, slot->ModuleSize, @@ -277,7 +326,8 @@ slot->Vendor, slot->PartNo, slot->SerialNo); - dumpPhysAddr("spd content: ",slot->spd, spd_size); + if(DEBUG_SPD) { + dumpPhysAddr("spd content: ",slot->spd, spd_size); getc(); } } @@ -287,10 +337,7 @@ i>0 && Platform.RAM.DIMM[1].InUse==false && fullBanks && Platform.DMI.MaxMemorySlots==2 ? mapping[i] : i; // for laptops case, mapping setup would need to be more generic than this - if (slot->spd) { - free(slot->spd); - slot->spd = NULL; - } + slot->spd = NULL; } // for } @@ -320,7 +367,7 @@ int i; while (current) { -#if DEBUG_SPD +#if 0 printf("%02x:%02x.%x [%04x] [%04x:%04x] :: %s\n", current->dev.bits.bus, current->dev.bits.dev, current->dev.bits.func, current->class_id, current->vendor_id, current->device_id, Index: branches/meklort/i386/libsaio/acpi_patcher.h =================================================================== --- branches/meklort/i386/libsaio/acpi_patcher.h (revision 0) +++ branches/meklort/i386/libsaio/acpi_patcher.h (revision 505) @@ -0,0 +1,37 @@ +/* + * Copyright 2008 mackerintel + */ + +#ifndef __LIBSAIO_ACPI_PATCHER_H +#define __LIBSAIO_ACPI_PATCHER_H + +#include "libsaio.h" + +uint64_t acpi10_p; +uint64_t acpi20_p; +uint64_t smbios_p; + +extern int setupAcpi(); + +extern EFI_STATUS addConfigurationTable(); + +extern EFI_GUID gEfiAcpiTableGuid; +extern EFI_GUID gEfiAcpi20TableGuid; + +struct p_state +{ + union + { + uint16_t Control; + struct + { + uint8_t VID; // Voltage ID + uint8_t FID; // Frequency ID + }; + }; + + uint8_t CID; // Compare ID + uint32_t Frequency; +}; + +#endif /* !__LIBSAIO_ACPI_PATCHER_H */ Index: branches/meklort/i386/libsaio/spd.h =================================================================== --- branches/meklort/i386/libsaio/spd.h (revision 504) +++ branches/meklort/i386/libsaio/spd.h (revision 505) @@ -94,6 +94,8 @@ #define SPD_MANUFACTURER_SPECIFIC_DATA 99 /* Manufacturer specific data (bytes 99-125) */ #define SPD_INTEL_SPEC_FOR_FREQUENCY 126 /* Intel specification for frequency */ #define SPD_INTEL_SPEC_100_MHZ 127 /* Intel specification details for 100MHz support */ +#define SPD_DDR3_MEMORY_BANK 0x75 +#define SPD_DDR3_MEMORY_CODE 0x76 /* DRAM specifications use the following naming conventions for SPD locations */ #define SPD_tRP SPD_MIN_ROW_PRECHARGE_TIME Index: branches/meklort/i386/libsaio/Makefile =================================================================== --- branches/meklort/i386/libsaio/Makefile (revision 504) +++ branches/meklort/i386/libsaio/Makefile (revision 505) @@ -39,11 +39,11 @@ ufs.o ufs_byteorder.o \ vbe.o nbp.o hfs.o hfs_compare.o \ xml.o ntfs.o msdos.o md5c.o device_tree.o \ - cpu.o platform.o dsdt_patcher.o \ + cpu.o platform.o acpi_patcher.o \ smbios_patcher.o fake_efi.o ext2fs.o \ - hpet.o spd.o usb.o pci_setup.o \ + hpet.o dram_controllers.o spd.o usb.o pci_setup.o \ device_inject.o nvidia.o ati.o pci_root.o \ - convert.o mem.o edid.o resolution.o + convert.o mem.o aml_generator.o resolution.o edid.o SAIO_EXTERN_OBJS = console.o Index: branches/meklort/i386/libsaio/ufs.c =================================================================== --- branches/meklort/i386/libsaio/ufs.c (revision 504) +++ branches/meklort/i386/libsaio/ufs.c (revision 505) @@ -46,7 +46,7 @@ static long ResolvePathToInode(char *filePath, long *flags, InodePtr fileInode, InodePtr dirInode); static long ReadDirEntry(InodePtr dirInode, long *fileInodeNum, - long *dirIndex, char **name); + long long *dirIndex, char **name); static long FindFileInDir(char *fileName, long *flags, InodePtr fileInode, InodePtr dirInode); static char *ReadFileBlock(InodePtr fileInode, long fragNum, long blockOffset, @@ -223,7 +223,7 @@ #ifndef BOOT1 -long UFSGetDirEntry( CICell ih, char * dirPath, long * dirIndex, +long UFSGetDirEntry( CICell ih, char * dirPath, long long * dirIndex, char ** name, long * flags, long * time, FinderInfo * finderInfo, long * infoValid) { @@ -383,18 +383,18 @@ } static long ReadDirEntry( InodePtr dirInode, long * fileInodeNum, - long * dirIndex, char ** name ) + long long * dirIndex, char ** name ) { struct direct *dir; char *buffer; - long index; + long long index; long dirBlockNum, dirBlockOffset; while (1) { index = *dirIndex; - dirBlockOffset = index % DIRBLKSIZ; - dirBlockNum = index / DIRBLKSIZ; + dirBlockOffset = (long) (index % DIRBLKSIZ); + dirBlockNum = (long) (index / DIRBLKSIZ); buffer = ReadFileBlock(dirInode, dirBlockNum, 0, DIRBLKSIZ, 0, 1); if (buffer == 0) return -1; @@ -418,7 +418,8 @@ static long FindFileInDir( char * fileName, long * flags, InodePtr fileInode, InodePtr dirInode ) { - long ret, inodeNum, index = 0; + long ret, inodeNum; + long long index = 0; char *name; while (1) { Index: branches/meklort/i386/libsaio/ufs.h =================================================================== --- branches/meklort/i386/libsaio/ufs.h (revision 504) +++ branches/meklort/i386/libsaio/ufs.h (revision 505) @@ -23,7 +23,7 @@ extern long UFSInitPartition(CICell ih); extern long UFSLoadFile(CICell ih, char * filePath); extern long UFSReadFile( CICell ih, char * filePath, void * base, uint64_t offset, uint64_t length ); -extern long UFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex, +extern long UFSGetDirEntry(CICell ih, char * dirPath, long long * dirIndex, char ** name, long * flags, long * time, FinderInfo * finderInfo, long * infoValid); extern void UFSGetDescription(CICell ih, char *str, long strMaxLen); Index: branches/meklort/i386/libsaio/smbios_patcher.c =================================================================== --- branches/meklort/i386/libsaio/smbios_patcher.c (revision 504) +++ branches/meklort/i386/libsaio/smbios_patcher.c (revision 505) @@ -10,6 +10,7 @@ #include "fake_efi.h" #include "platform.h" #include "smbios_patcher.h" +#include "pci.h" #ifndef DEBUG_SMBIOS #define DEBUG_SMBIOS 0 @@ -88,19 +89,49 @@ // defaults for a Mac Pro static const SMStrEntryPair const sm_macpro_defaults[]={ - {"SMbiosvendor", "Apple Computer, Inc." }, - {"SMbiosversion", "MP31.88Z.006C.B05.0802291410" }, - {"SMbiosdate", "04/01/2008" }, - {"SMmanufacter", "Apple Computer, Inc." }, - {"SMproductname", "MacPro3,1" }, - {"SMsystemversion", "1.0" }, - {"SMserial", "SOMESRLNMBR" }, - {"SMfamily", "MacPro" }, - {"SMboardmanufacter", "Apple Computer, Inc." }, - {"SMboardproduct", "Mac-F4208DC8" }, + {"SMbiosvendor", "Apple Computer, Inc." }, + {"SMbiosversion", "MP31.88Z.006C.B05.0802291410" }, + {"SMbiosdate", "04/01/2008" }, + {"SMmanufacter", "Apple Computer, Inc." }, + {"SMproductname", "MacPro3,1" }, + {"SMsystemversion", "1.0" }, + {"SMserial", "SOMESRLNMBR" }, + {"SMfamily", "MacPro" }, + {"SMboardmanufacter", "Apple Computer, Inc." }, + {"SMboardproduct", "Mac-F4208DC8" }, { "","" } }; +// defaults for an iMac11,1 core i3/i5/i7 +static const SMStrEntryPair const sm_imac_core_defaults[]={ + {"SMbiosvendor", "Apple Inc." }, + {"SMbiosversion", "IM111.88Z.0034.B00.0802091538" }, + {"SMbiosdate", "06/01/2009" }, + {"SMmanufacter", "Apple Inc." }, + {"SMproductname", "iMac11,1" }, + {"SMsystemversion", "1.0" }, + {"SMserial", "SOMESRLNMBR" }, + {"SMfamily", "iMac" }, + {"SMboardmanufacter", "Apple Computer, Inc." }, + {"SMboardproduct", "Mac-F2268DAE" }, + { "","" } +}; + +// defaults for a Mac Pro 4,1 core i7/Xeon +static const SMStrEntryPair const sm_macpro_core_defaults[]={ + {"SMbiosvendor", "Apple Computer, Inc." }, + {"SMbiosversion", "MP41.88Z.0081.B04.0903051113" }, + {"SMbiosdate", "11/06/2009" }, + {"SMmanufacter", "Apple Computer, Inc." }, + {"SMproductname", "MacPro4,1" }, + {"SMsystemversion", "1.0" }, + {"SMserial", "SOMESRLNMBR" }, + {"SMfamily", "MacPro" }, + {"SMboardmanufacter", "Apple Computer, Inc." }, + {"SMboardproduct", "Mac-F4208DC8" }, + { "","" } +}; + static const char* sm_get_defstr(const char * key, int table_num) { int i; @@ -113,13 +144,49 @@ sm_defaults=sm_macbook_defaults; } } else { - switch (Platform.CPU.NoCores) { - case 1: sm_defaults=sm_macmini_defaults; break; - case 2: sm_defaults=sm_imac_defaults; break; - default: sm_defaults=sm_macpro_defaults; break; + switch (Platform.CPU.NoCores) + { + case 1: + sm_defaults=sm_macmini_defaults; + break; + case 2: + sm_defaults=sm_imac_defaults; + break; + default: + { + switch (Platform.CPU.Family) + { + case 0x06: + { + switch (Platform.CPU.Model) + { + case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm) + case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ??? + case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) (Clarkdale, Arrandale) + case 0x19: // Intel Core i5 650 @3.20 Ghz + sm_defaults=sm_imac_core_defaults; + break; + case CPU_MODEL_NEHALEM: + case CPU_MODEL_NEHALEM_EX: + case CPU_MODEL_WESTMERE: + case CPU_MODEL_WESTMERE_EX: + sm_defaults=sm_macpro_core_defaults; + break; + default: + sm_defaults=sm_macpro_defaults; + break; + } + break; + } + default: + sm_defaults=sm_macpro_defaults; + break; + } + break; + } } } - + for (i=0; sm_defaults[i].key[0]; i++) { if (!strcmp (sm_defaults[i].key, key)) { return sm_defaults[i].value; @@ -142,17 +209,152 @@ return Platform.CPU.CPUFrequency/1000000; } +static int sm_get_bus_speed (const char *name, int table_num) +{ + if (Platform.CPU.Vendor == 0x756E6547) // Intel + { + switch (Platform.CPU.Family) + { + case 0x06: + { + switch (Platform.CPU.Model) + { + case 0x0D: // ? + case CPU_MODEL_YONAH: // Yonah 0x0E + case CPU_MODEL_MEROM: // Merom 0x0F + case CPU_MODEL_PENRYN: // Penryn 0x17 + case CPU_MODEL_ATOM: // Atom 45nm 0x1C + return 0; // TODO: populate bus speed for these processors + +// case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm) +// if (strstr(Platform.CPU.BrandString, "Core(TM) i5")) +// return 2500; // Core i5 +// return 4800; // Core i7 + +// case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm) +// case CPU_MODEL_NEHALEM_EX: +// case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ??? +// return 4800; // GT/s / 1000 +// + case CPU_MODEL_WESTMERE_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ??? + return 0; // TODO: populate bus speed for these processors + +// case 0x19: // Intel Core i5 650 @3.20 Ghz +// return 2500; // why? Intel spec says 2.5GT/s + + case 0x19: // Intel Core i5 650 @3.20 Ghz + case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm) + case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm) + case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ??? + case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) + case CPU_MODEL_WESTMERE: // Intel Core i7 LGA1366 (32nm) 6 Core + case CPU_MODEL_NEHALEM_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ??? + { // thanks to dgobe for i3/i5/i7 bus speed detection + int nhm_bus = 0x3F; + static long possible_nhm_bus[] = {0xFF, 0x7F, 0x3F}; + unsigned long did, vid; + int i; + + // Nehalem supports Scrubbing + // First, locate the PCI bus where the MCH is located + for(i = 0; i < sizeof(possible_nhm_bus); i++) + { + vid = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x00); + did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x02); + vid &= 0xFFFF; + did &= 0xFF00; + + if(vid == 0x8086 && did >= 0x2C00) + nhm_bus = possible_nhm_bus[i]; + } + + unsigned long qpimult, qpibusspeed; + qpimult = pci_config_read32(PCIADDR(nhm_bus, 2, 1), 0x50); + qpimult &= 0x7F; + DBG("qpimult %d\n", qpimult); + qpibusspeed = (qpimult * 2 * (Platform.CPU.FSBFrequency/1000000)); + // Rek: rounding decimals to match original mac profile info + if (qpibusspeed%100 != 0)qpibusspeed = ((qpibusspeed+50)/100)*100; + DBG("qpibusspeed %d\n", qpibusspeed); + return qpibusspeed; + } + } + } + } + } + return 0; +} + +static int sm_get_simplecputype() +{ + if (Platform.CPU.NoCores >= 4) + { + return 0x0501; // Quad-Core Xeon + } + else if (Platform.CPU.NoCores == 1) + { + return 0x0201; // Core Solo + }; + + return 0x0301; // Core 2 Duo +} + static int sm_get_cputype (const char *name, int table_num) { - if (Platform.CPU.NoCores == 1) { - return 0x0101; // <01 01> Intel Core Solo? - } else if (Platform.CPU.NoCores == 2) { - return 0x0301; // <01 03> Intel Core 2 Duo - } else if (Platform.CPU.NoCores >= 4) { - return 0x0501; // <01 05> Quad-Core Intel Xeon - } else { - return 0x0301; // Default to Core 2 Duo + static bool done = false; + + if (Platform.CPU.Vendor == 0x756E6547) // Intel + { + if (!done) { + verbose("CPU is %s, family 0x%x, model 0x%x\n", Platform.CPU.BrandString, Platform.CPU.Family, Platform.CPU.Model); + done = true; + } + + switch (Platform.CPU.Family) + { + case 0x06: + { + switch (Platform.CPU.Model) + { + case 0x0D: // ? + case CPU_MODEL_YONAH: // Yonah + case CPU_MODEL_MEROM: // Merom + case CPU_MODEL_PENRYN: // Penryn + case CPU_MODEL_ATOM: // Intel Atom (45nm) + return sm_get_simplecputype(); + + case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm) + return 0x0701; // Core i7 + + case CPU_MODEL_FIELDS: // Lynnfield, Clarksfield, Jasper + if (strstr(Platform.CPU.BrandString, "Core(TM) i5")) + return 0x601; // Core i5 + return 0x701; // Core i7 + + case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) (Havendale, Auburndale) + if (strstr(Platform.CPU.BrandString, "Core(TM) i5")) + return 0x601; // Core i5 + return 0x0701; // Core i7 + + case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) (Clarkdale, Arrandale) + if (strstr(Platform.CPU.BrandString, "Core(TM) i3")) + return 0x901; // Core i3 + if (strstr(Platform.CPU.BrandString, "Core(TM) i5")) + return 0x601; // Core i5 + return 0x0701; // Core i7 + + case CPU_MODEL_WESTMERE: // Intel Core i7 LGA1366 (32nm) 6 Core (Gulftown, Westmere-EP, Westmere-WS) + case CPU_MODEL_WESTMERE_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ??? + return 0x0701; // Core i7 + + case 0x19: // Intel Core i5 650 @3.20 Ghz + return 0x601; // Core i5 + } + } + } } + + return sm_get_simplecputype(); } static int sm_get_memtype (const char *name, int table_num) @@ -166,6 +368,7 @@ return Platform.RAM.DIMM[map].Type; } } + return SMB_MEM_TYPE_DDR2; } @@ -255,7 +458,7 @@ {.name="SMmemserial", .table_type=17, .value_type=SMSTRING, .offset=0x18, .auto_str=sm_get_memserial}, {.name="SMmempart", .table_type=17, .value_type=SMSTRING, .offset=0x1A, .auto_str=sm_get_mempartno}, {.name="SMcputype", .table_type=131,.value_type=SMWORD, .offset=0x04, .auto_int=sm_get_cputype}, - {.name="SMbusspeed", .table_type=132,.value_type=SMWORD, .offset=0x04, .auto_str=0 } + {.name="SMbusspeed", .table_type=132,.value_type=SMWORD, .offset=0x04, .auto_int=sm_get_bus_speed} }; struct smbios_table_description smbios_table_descriptions[]= @@ -457,9 +660,11 @@ int i, j; int tablespresent[256]; bool do_auto=true; - - extern void dumpPhysAddr(const char * title, void * a, int len); + + static bool done = false; // IMPROVEME: called twice via getSmbios(), but only the second call can get all necessary info ! + extern void dumpPhysAddr(const char * title, void * a, int len); + bzero(tablespresent, sizeof(tablespresent)); bzero(handles, sizeof(handles)); @@ -729,7 +934,11 @@ 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"); + + if (!done) { + verbose("Patched DMI Table\n"); + done=true; + } } #define MAX_DMI_TABLES 96 @@ -777,7 +986,7 @@ DmiTablePairCount++; } else { - printf("DMI table entries list is full! next entries won't be stored\n"); + printf("DMI table entries list is full! Next entries won't be stored.\n"); } #if DEBUG_SMBIOS printf("DMI header found for table type %d, length = %d\n", dmihdr->type, dmihdr->length); Index: branches/meklort/i386/libsaio/aml_generator.c =================================================================== --- branches/meklort/i386/libsaio/aml_generator.c (revision 0) +++ branches/meklort/i386/libsaio/aml_generator.c (revision 505) @@ -0,0 +1,498 @@ +/* + * aml_generator.c + * Chameleon + * + * Created by Mozodojo on 20/07/10. + * Copyright 2010 mozo. All rights reserved. + * + */ + +#include "aml_generator.h" + +bool aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node) +{ + if (parent && node) + { + switch (parent->Type) + { + case AML_CHUNK_NONE: + case AML_CHUNK_BYTE: + case AML_CHUNK_WORD: + case AML_CHUNK_DWORD: + case AML_CHUNK_QWORD: + case AML_CHUNK_ALIAS: + verbose("aml_add_to_parent: Node isn't supports child nodes!"); + return FALSE; + case AML_CHUNK_NAME: + if (parent->First) + { + verbose("aml_add_to_parent: Name node could have only one child node!"); + return FALSE; + } + break; + + default: + break; + } + + if (!parent->First) + parent->First = node; + + if (parent->Last) + parent->Last->Next = node; + + parent->Last = node; + + return TRUE; + } + + return FALSE; +} + +struct aml_chunk* aml_create_node(struct aml_chunk* parent) +{ + struct aml_chunk* node = (struct aml_chunk*)malloc(sizeof(struct aml_chunk)); + + aml_add_to_parent(parent, node); + + return node; +} + +void aml_destroy_node(struct aml_chunk* node) +{ + // Delete child nodes + struct aml_chunk* child = node->First; + + while (child) + { + struct aml_chunk* next = child->Next; + + if (child->Buffer) + free(child->Buffer); + + free(child); + + child = next; + } + + // Free node + if (node->Buffer) + free(node->Buffer); + + free(node); +} + +struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_NONE; + node->Length = size; + node->Buffer = malloc(node->Length); + memcpy(node->Buffer, buffer, node->Length); + } + + return node; +} + +struct aml_chunk* aml_add_byte(struct aml_chunk* parent, unsigned char value) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_BYTE; + + node->Length = 1; + node->Buffer = malloc(node->Length); + node->Buffer[0] = value; + } + + return node; +} + +struct aml_chunk* aml_add_word(struct aml_chunk* parent, unsigned int value) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_WORD; + node->Length = 2; + node->Buffer = malloc(node->Length); + node->Buffer[0] = value & 0xff; + node->Buffer[1] = value >> 8; + } + + return node; +} + +struct aml_chunk* aml_add_dword(struct aml_chunk* parent, unsigned long value) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_DWORD; + node->Length = 4; + node->Buffer = malloc(node->Length); + node->Buffer[0] = value & 0xff; + node->Buffer[1] = (value >> 8) & 0xff; + node->Buffer[2] = (value >> 16) & 0xff; + node->Buffer[3] = (value >> 24) & 0xff; + } + + return node; +} + +struct aml_chunk* aml_add_qword(struct aml_chunk* parent, unsigned long long value) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_QWORD; + node->Length = 8; + node->Buffer = malloc(node->Length); + node->Buffer[0] = value & 0xff; + node->Buffer[1] = (value >> 8) & 0xff; + node->Buffer[2] = (value >> 16) & 0xff; + node->Buffer[3] = (value >> 24) & 0xff; + node->Buffer[4] = (value >> 32) & 0xff; + node->Buffer[5] = (value >> 40) & 0xff; + node->Buffer[6] = (value >> 48) & 0xff; + node->Buffer[7] = (value >> 56) & 0xff; + } + + return node; +} + +unsigned int aml_fill_simple_name(char* buffer, const char* name) +{ + if (strlen(name) < 4) + { + verbose("aml_fill_simple_name: simple name %s has incorrect lengh! Must be 4", name); + return 0; + } + + memcpy(buffer, name, 4); + return 4; +} + +unsigned int aml_fill_name(struct aml_chunk* node, const char* name) +{ + if (!node) + return 0; + + int len = strlen(name), offset = 0, count = len / 4; + + if ((len % 4) > 1 || count == 0) + { + verbose("aml_fill_name: pathname %s has incorrect length! Must be 4, 8, 12, 16 etc.", name); + return 0; + } + + unsigned int root = 0; + + if ((len % 4) == 1 && name[0] == '\\') + root++; + + if (count == 1) + { + node->Length = 4 + root; + node->Buffer = malloc(node->Length); + memcpy(node->Buffer, name, 4 + root); + return node->Length; + } + + if (count == 2) + { + node->Length = 2 + 8; + node->Buffer = malloc(node->Length); + node->Buffer[offset++] = 0x5c; // Root Char + node->Buffer[offset++] = 0x2e; // Double name + memcpy(node->Buffer+offset, name + root, 8); + return node->Length; + } + + node->Length = 3 + count*4; + node->Buffer = malloc(node->Length); + node->Buffer[offset++] = 0x5c; // Root Char + node->Buffer[offset++] = 0x2f; // Multi name + node->Buffer[offset++] = count; // Names count + memcpy(node->Buffer+offset, name + root, count*4); + + return node->Length; +} + +struct aml_chunk* aml_add_scope(struct aml_chunk* parent, const char* name) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_SCOPE; + + aml_fill_name(node, name); + } + + return node; +} + +struct aml_chunk* aml_add_name(struct aml_chunk* parent, const char* name) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_NAME; + + aml_fill_name(node, name); + } + + return node; +} + +struct aml_chunk* aml_add_package(struct aml_chunk* parent) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_PACKAGE; + + node->Length = 1; + node->Buffer = malloc(node->Length); + } + + return node; +} + +struct aml_chunk* aml_add_alias(struct aml_chunk* parent, const char* name1, const char* name2) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_ALIAS; + + node->Length = 8; + node->Buffer = malloc(node->Length); + aml_fill_simple_name(node->Buffer, name1); + aml_fill_simple_name(node->Buffer+4, name2); + } + + return node; +} + +unsigned char aml_get_size_length(unsigned int size) +{ + if (size + 1 <= 0x3f) + return 1; + else if (size + 2 <= 0x3fff) + return 2; + else if (size + 3 <= 0x3fffff) + return 3; + + return 4; +} + +unsigned int aml_calculate_size(struct aml_chunk* node) +{ + if (node) + { + node->Size = 0; + + // Calculate child nodes size + struct aml_chunk* child = node->First; + unsigned char child_count = 0; + + while (child) + { + child_count++; + + node->Size += aml_calculate_size(child); + + child = child->Next; + } + + switch (node->Type) + { + case AML_CHUNK_NONE: + node->Size += node->Length; + break; + case AML_CHUNK_SCOPE: + node->Size += 1 + node->Length; + node->Size += aml_get_size_length(node->Size); + break; + case AML_CHUNK_PACKAGE: + node->Buffer[0] = child_count; + node->Size += 1 + node->Length; + node->Size += aml_get_size_length(node->Size); + break; + + case AML_CHUNK_BYTE: + if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1) + { + node->Size += node->Length; + } + else + { + node->Size += 1 + node->Length; + } + + break; + + case AML_CHUNK_WORD: + case AML_CHUNK_DWORD: + case AML_CHUNK_QWORD: + case AML_CHUNK_ALIAS: + case AML_CHUNK_NAME: + node->Size += 1 + node->Length; + break; + } + + return node->Size; + } + + return 0; +} + +unsigned int aml_write_byte(unsigned char value, char* buffer, unsigned int offset) +{ + buffer[offset++] = value; + + return offset; +} + +unsigned int aml_write_word(unsigned int value, char* buffer, unsigned int offset) +{ + buffer[offset++] = value & 0xff; + buffer[offset++] = value >> 8; + + return offset; +} + +unsigned int aml_write_dword(unsigned long value, char* buffer, unsigned int offset) +{ + buffer[offset++] = value & 0xff; + buffer[offset++] = (value >> 8) & 0xff; + buffer[offset++] = (value >> 16) & 0xff; + buffer[offset++] = (value >> 24) & 0xff; + + return offset; +} + +unsigned int aml_write_qword(unsigned long long value, char* buffer, unsigned int offset) +{ + buffer[offset++] = value & 0xff; + buffer[offset++] = (value >> 8) & 0xff; + buffer[offset++] = (value >> 16) & 0xff; + buffer[offset++] = (value >> 24) & 0xff; + buffer[offset++] = (value >> 32) & 0xff; + buffer[offset++] = (value >> 40) & 0xff; + buffer[offset++] = (value >> 48) & 0xff; + buffer[offset++] = (value >> 56) & 0xff; + + return offset; +} + +unsigned int aml_write_buffer(const char* value, unsigned int size, char* buffer, unsigned int offset) +{ + if (size > 0) + { + memcpy(buffer + offset, value, size); + } + + return offset + size; +} + +unsigned int aml_write_size(unsigned int size, char* buffer, unsigned int offset) +{ + if (size <= 0x3f) + { + buffer[offset++] = size; + } + else if (size <= 0x3fff) + { + buffer[offset++] = 0x40 | (size & 0xf); + buffer[offset++] = (size >> 4) & 0xff; + } + else if (size <= 0x3fffff) + { + buffer[offset++] = 0x80 | (size & 0xf); + buffer[offset++] = (size >> 4) & 0xff; + buffer[offset++] = (size >> 12) & 0xff; + } + else + { + buffer[offset++] = 0xc0 | (size & 0xf); + buffer[offset++] = (size >> 4) & 0xff; + buffer[offset++] = (size >> 12) & 0xff; + buffer[offset++] = (size >> 20) & 0xff; + } + + return offset; +} + +unsigned int aml_write_node(struct aml_chunk* node, char* buffer, unsigned int offset) +{ + if (node && buffer) + { + unsigned int old = offset; + + switch (node->Type) + { + case AML_CHUNK_NONE: + offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset); + break; + + case AML_CHUNK_SCOPE: + case AML_CHUNK_PACKAGE: + offset = aml_write_byte(node->Type, buffer, offset); + offset = aml_write_size(node->Size-1, buffer, offset); + offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset); + break; + + case AML_CHUNK_BYTE: + if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1) + { + offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset); + } + else + { + offset = aml_write_byte(node->Type, buffer, offset); + offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset); + } + break; + + case AML_CHUNK_WORD: + case AML_CHUNK_DWORD: + case AML_CHUNK_QWORD: + case AML_CHUNK_ALIAS: + case AML_CHUNK_NAME: + offset = aml_write_byte(node->Type, buffer, offset); + offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset); + break; + + default: + break; + } + + struct aml_chunk* child = node->First; + + while (child) + { + offset = aml_write_node(child, buffer, offset); + + child = child->Next; + } + + if (offset - old != node->Size) + verbose("Node size incorrect: 0x%x\n", node->Type); + } + + return offset; +} \ No newline at end of file Index: branches/meklort/i386/libsaio/aml_generator.h =================================================================== --- branches/meklort/i386/libsaio/aml_generator.h (revision 0) +++ branches/meklort/i386/libsaio/aml_generator.h (revision 505) @@ -0,0 +1,61 @@ +/* + * aml_generator.h + * Chameleon + * + * Created by Mozodojo on 20/07/10. + * Copyright 2010 mozo. All rights reserved. + * + */ + +#ifndef __LIBSAIO_AML_GENERATOR_H +#define __LIBSAIO_AML_GENERATOR_H + +#include "libsaio.h" + +#define AML_CHUNK_NONE 0xff +#define AML_CHUNK_ZERO 0x00 +#define AML_CHUNK_ONE 0x01 +#define AML_CHUNK_ALIAS 0x06 +#define AML_CHUNK_NAME 0x08 +#define AML_CHUNK_BYTE 0x0A +#define AML_CHUNK_WORD 0x0B +#define AML_CHUNK_DWORD 0x0C +#define AML_CHUNK_STRING 0x0D +#define AML_CHUNK_QWORD 0x0E +#define AML_CHUNK_SCOPE 0x10 +#define AML_CHUNK_PACKAGE 0x12 + +struct aml_chunk +{ + unsigned char Type; + unsigned int Length; + char* Buffer; + + unsigned int Size; + + struct aml_chunk* Next; + struct aml_chunk* First; + struct aml_chunk* Last; +}; + +static inline bool aml_isvalidchar(char c) +{ + return isupper(c) || isdigit(c) || c == '_'; +}; + +bool aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node); +struct aml_chunk* aml_create_node(struct aml_chunk* parent); +void aml_destroy_node(struct aml_chunk* node); +struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size); +struct aml_chunk* aml_add_byte(struct aml_chunk* parent, unsigned char value); +struct aml_chunk* aml_add_word(struct aml_chunk* parent, unsigned int value); +struct aml_chunk* aml_add_dword(struct aml_chunk* parent, unsigned long value); +struct aml_chunk* aml_add_qword(struct aml_chunk* parent, unsigned long long value); +struct aml_chunk* aml_add_scope(struct aml_chunk* parent, const char* name); +struct aml_chunk* aml_add_name(struct aml_chunk* parent, const char* name); +struct aml_chunk* aml_add_package(struct aml_chunk* parent); +struct aml_chunk* aml_add_alias(struct aml_chunk* parent, const char* name1, const char* name2); +unsigned int aml_calculate_size(struct aml_chunk* node); +unsigned int aml_write_node(struct aml_chunk* node, char* buffer, unsigned int offset); + +#endif /* !__LIBSAIO_AML_GENERATOR_H */ \ No newline at end of file Index: branches/meklort/i386/libsaio/memvendors.h =================================================================== --- branches/meklort/i386/libsaio/memvendors.h (revision 504) +++ branches/meklort/i386/libsaio/memvendors.h (revision 505) @@ -410,7 +410,7 @@ { 3, 0x10, "Agere Systems"}, { 3, 0x91, "NeoMagic"}, { 3, 0x92, "AuroraNetics"}, - { 3, 0x13, "Golden Empire"}, + { 3, 0x13, "Geil"}, { 3, 0x94, "Mushkin"}, { 3, 0x15, "Tioga Technologies"}, { 3, 0x16, "Netlist"}, @@ -645,7 +645,7 @@ { 4, 0xfd, "Focus Enhancements"}, { 4, 0xfe, "Xyratex"}, { 5, 0x01, "Specular Networks"}, - { 5, 0x02, "Patriot Memory (PDP Systems)"}, + { 5, 0x02, "PDP Systems"}, { 5, 0x83, "U-Chip Technology Corp."}, { 5, 0x04, "Silicon Optix"}, { 5, 0x85, "Greenfield Networks"}, Index: branches/meklort/i386/libsaio/usb.c =================================================================== --- branches/meklort/i386/libsaio/usb.c (revision 504) +++ branches/meklort/i386/libsaio/usb.c (revision 505) @@ -66,13 +66,11 @@ { int retVal = 1; bool fix_ehci, fix_uhci, fix_usb, fix_legacy; - fix_ehci = fix_uhci = fix_usb = fix_legacy = true; + fix_ehci = fix_uhci = fix_usb = fix_legacy = false; - - if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->bootConfig)) { - fix_ehci = fix_uhci = fix_legacy = fix_usb; // Enable all if none set + fix_ehci = fix_uhci = fix_legacy = fix_usb; // Disable all if none set } else { @@ -81,10 +79,9 @@ getBoolForKey(kLegacyOff, &fix_legacy, &bootInfo->bootConfig); } - struct pciList* current = usbList; - while(current && current->next) + while(current) { switch (pci_config_read8(current->pciDev->dev.addr, PCI_CLASS_PROG)) { @@ -98,6 +95,7 @@ // UHCI case 0x00: if (fix_uhci) retVal &= uhci_reset(current->pciDev); + break; } @@ -200,8 +198,6 @@ return 1; } - - int ehci_acquire (pci_dt_t *pci_dev) { int j, k; Index: branches/meklort/i386/libsaio/dram_controllers.c =================================================================== --- branches/meklort/i386/libsaio/dram_controllers.c (revision 0) +++ branches/meklort/i386/libsaio/dram_controllers.c (revision 505) @@ -0,0 +1,562 @@ +/* + * dram controller access and scan from the pci host controller + * Integrated and adapted for chameleon 2.0 RC5 by Rekursor from bs0d work + * original source comes from: + * + * memtest86 + * + * Released under version 2 of the Gnu Public License. + * By Chris Brady, cbrady@sgi.com + * ---------------------------------------------------- + * MemTest86+ V4.00 Specific code (GPL V2.0) + * By Samuel DEMEULEMEESTER, sdemeule@memtest.org + * http://www.canardpc.com - http://www.memtest.org + */ + +#include "libsaio.h" +#include "bootstruct.h" +#include "pci.h" +#include "platform.h" +#include "dram_controllers.h" + +#ifndef DEBUG_DRAM +#define DEBUG_DRAM 0 +#endif + +#if DEBUG_DRAM +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif + +/* + * Initialise memory controller functions + */ + +// Setup P35 Memory Controller +static void setup_p35(pci_dt_t *dram_dev) +{ + uint32_t dev0; + + // Activate MMR I/O + dev0 = pci_config_read32(dram_dev->dev.addr, 0x48); + if (!(dev0 & 0x1)) + pci_config_write8(dram_dev->dev.addr, 0x48, (dev0 | 1)); +} + +int nhm_bus = 0x3F; + +// Setup Nehalem Integrated Memory Controller +static void setup_nhm(pci_dt_t *dram_dev) +{ + static long possible_nhm_bus[] = {0xFF, 0x7F, 0x3F}; + unsigned long did, vid; + int i; + + // Nehalem supports Scrubbing + // First, locate the PCI bus where the MCH is located + for(i = 0; i < sizeof(possible_nhm_bus); i++) + { + vid = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x00); + did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x02); + vid &= 0xFFFF; + did &= 0xFF00; + + if(vid == 0x8086 && did >= 0x2C00) + nhm_bus = possible_nhm_bus[i]; + } +} + +/* + * Retrieve memory controller fsb functions + */ + + +// Get i965 Memory Speed +static void get_fsb_i965(pci_dt_t *dram_dev) +{ + uint32_t dev0, mch_ratio, mch_cfg, mch_fsb; + + long *ptr; + + // Find Ratio + dev0 = pci_config_read32(dram_dev->dev.addr, 0x48); + dev0 &= 0xFFFFC000; + ptr = (long*)(dev0 + 0xC00); + mch_cfg = *ptr & 0xFFFF; + + mch_ratio = 100000; + + switch (mch_cfg & 7) + { + case 0: mch_fsb = 1066; break; + case 1: mch_fsb = 533; break; + default: + case 2: mch_fsb = 800; break; + case 3: mch_fsb = 667; break; + case 4: mch_fsb = 1333; break; + case 6: mch_fsb = 1600; break; + } + + DBG("mch_fsb %d\n", mch_fsb); + + switch (mch_fsb) + { + case 533: + switch ((mch_cfg >> 4) & 7) + { + case 1: mch_ratio = 200000; break; + case 2: mch_ratio = 250000; break; + case 3: mch_ratio = 300000; break; + } + break; + + default: + case 800: + switch ((mch_cfg >> 4) & 7) + { + case 0: mch_ratio = 100000; break; + case 1: mch_ratio = 125000; break; + case 2: mch_ratio = 166667; break; // 1.666666667 + case 3: mch_ratio = 200000; break; + case 4: mch_ratio = 266667; break; // 2.666666667 + case 5: mch_ratio = 333333; break; // 3.333333333 + } + break; + + case 1066: + switch ((mch_cfg >> 4) & 7) + { + case 1: mch_ratio = 100000; break; + case 2: mch_ratio = 125000; break; + case 3: mch_ratio = 150000; break; + case 4: mch_ratio = 200000; break; + case 5: mch_ratio = 250000; break; + } + break; + + case 1333: + switch ((mch_cfg >> 4) & 7) + { + case 2: mch_ratio = 100000; break; + case 3: mch_ratio = 120000; break; + case 4: mch_ratio = 160000; break; + case 5: mch_ratio = 200000; break; + } + break; + + case 1600: + switch ((mch_cfg >> 4) & 7) + { + case 3: mch_ratio = 100000; break; + case 4: mch_ratio = 133333; break; // 1.333333333 + case 5: mch_ratio = 150000; break; + case 6: mch_ratio = 200000; break; + } + break; + } + + DBG("mch_ratio %d\n", mch_ratio); + + // Compute RAM Frequency + Platform.RAM.Frequency = (Platform.CPU.FSBFrequency * mch_ratio) / 100000; + + DBG("ram_fsb %d\n", Platform.RAM.Frequency); + +} + +// Get i965m Memory Speed +static void get_fsb_im965(pci_dt_t *dram_dev) +{ + uint32_t dev0, mch_ratio, mch_cfg, mch_fsb; + + long *ptr; + + // Find Ratio + dev0 = pci_config_read32(dram_dev->dev.addr, 0x48); + dev0 &= 0xFFFFC000; + ptr = (long*)(dev0 + 0xC00); + mch_cfg = *ptr & 0xFFFF; + + mch_ratio = 100000; + + switch (mch_cfg & 7) + { + case 1: mch_fsb = 533; break; + default: + case 2: mch_fsb = 800; break; + case 3: mch_fsb = 667; break; + case 6: mch_fsb = 1066; break; + } + + switch (mch_fsb) + { + case 533: + switch ((mch_cfg >> 4) & 7) + { + case 1: mch_ratio = 125000; break; + case 2: mch_ratio = 150000; break; + case 3: mch_ratio = 200000; break; + } + break; + + case 667: + switch ((mch_cfg >> 4)& 7) + { + case 1: mch_ratio = 100000; break; + case 2: mch_ratio = 120000; break; + case 3: mch_ratio = 160000; break; + case 4: mch_ratio = 200000; break; + case 5: mch_ratio = 240000; break; + } + break; + + default: + case 800: + switch ((mch_cfg >> 4) & 7) + { + case 1: mch_ratio = 83333; break; // 0.833333333 + case 2: mch_ratio = 100000; break; + case 3: mch_ratio = 133333; break; // 1.333333333 + case 4: mch_ratio = 166667; break; // 1.666666667 + case 5: mch_ratio = 200000; break; + } + break; + case 1066: + switch ((mch_cfg >> 4)&7) { + case 5: mch_ratio = 150000; break; + case 6: mch_ratio = 200000; break; + } + + } + + // Compute RAM Frequency + Platform.RAM.Frequency = (Platform.CPU.FSBFrequency * mch_ratio) / 100000; +} + + +// Get iCore7 Memory Speed +static void get_fsb_nhm(pci_dt_t *dram_dev) +{ + uint32_t mch_ratio, mc_dimm_clk_ratio; + + // Get the clock ratio + mc_dimm_clk_ratio = pci_config_read16(PCIADDR(nhm_bus, 3, 4), 0x54 ); + mch_ratio = (mc_dimm_clk_ratio & 0x1F); + + // Compute RAM Frequency + Platform.RAM.Frequency = Platform.CPU.FSBFrequency * mch_ratio / 2; +} + +/* + * Retrieve memory controller info functions + */ + +// Get i965 Memory Timings +static void get_timings_i965(pci_dt_t *dram_dev) +{ + // Thanks for CDH optis + uint32_t dev0, c0ckectrl, c1ckectrl, offset; + uint32_t ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register, Misc_Register; + + long *ptr; + + // Read MMR Base Address + dev0 = pci_config_read32(dram_dev->dev.addr, 0x48); + dev0 &= 0xFFFFC000; + + ptr = (long*)(dev0 + 0x260); + c0ckectrl = *ptr & 0xFFFFFFFF; + + ptr = (long*)(dev0 + 0x660); + c1ckectrl = *ptr & 0xFFFFFFFF; + + // If DIMM 0 not populated, check DIMM 1 + ((c0ckectrl) >> 20 & 0xF) ? (offset = 0) : (offset = 0x400); + + ptr = (long*)(dev0 + offset + 0x29C); + ODT_Control_Register = *ptr & 0xFFFFFFFF; + + ptr = (long*)(dev0 + offset + 0x250); + Precharge_Register = *ptr & 0xFFFFFFFF; + + ptr = (long*)(dev0 + offset + 0x252); + ACT_Register = *ptr & 0xFFFFFFFF; + + ptr = (long*)(dev0 + offset + 0x258); + Read_Register = *ptr & 0xFFFFFFFF; + + ptr = (long*)(dev0 + offset + 0x244); + Misc_Register = *ptr & 0xFFFFFFFF; + + // 965 Series only support DDR2 + Platform.RAM.Type = SMB_MEM_TYPE_DDR2; + + // CAS Latency (tCAS) + Platform.RAM.CAS = ((ODT_Control_Register >> 17) & 7) + 3; + + // RAS-To-CAS (tRCD) + Platform.RAM.TRC = (Read_Register >> 16) & 0xF; + + // RAS Precharge (tRP) + Platform.RAM.TRP = (ACT_Register >> 13) & 0xF; + + // RAS Active to precharge (tRAS) + Platform.RAM.RAS = (Precharge_Register >> 11) & 0x1F; + + if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) + Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL; + else + Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE; +} + +// Get im965 Memory Timings +static void get_timings_im965(pci_dt_t *dram_dev) +{ + // Thanks for CDH optis + uint32_t dev0, c0ckectrl, c1ckectrl, offset, ODT_Control_Register, Precharge_Register; + long *ptr; + + // Read MMR Base Address + dev0 = pci_config_read32(dram_dev->dev.addr, 0x48); + dev0 &= 0xFFFFC000; + + ptr = (long*)(dev0 + 0x1200); + c0ckectrl = *ptr & 0xFFFFFFFF; + + ptr = (long*)(dev0 + 0x1300); + c1ckectrl = *ptr & 0xFFFFFFFF; + + // If DIMM 0 not populated, check DIMM 1 + ((c0ckectrl) >> 20 & 0xF) ? (offset = 0) : (offset = 0x100); + + ptr = (long*)(dev0 + offset + 0x121C); + ODT_Control_Register = *ptr & 0xFFFFFFFF; + + ptr = (long*)(dev0 + offset + 0x1214); + Precharge_Register = *ptr & 0xFFFFFFFF; + + // Series only support DDR2 + Platform.RAM.Type = SMB_MEM_TYPE_DDR2; + + // CAS Latency (tCAS) + Platform.RAM.CAS = ((ODT_Control_Register >> 23) & 7) + 3; + + // RAS-To-CAS (tRCD) + Platform.RAM.TRC = ((Precharge_Register >> 5) & 7) + 2; + + // RAS Precharge (tRP) + Platform.RAM.TRP= (Precharge_Register & 7) + 2; + + // RAS Active to precharge (tRAS) + Platform.RAM.RAS = (Precharge_Register >> 21) & 0x1F; + + if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) + Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL; + else + Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE; +} + +// Get P35 Memory Timings +static void get_timings_p35(pci_dt_t *dram_dev) +{ + // Thanks for CDH optis + unsigned long dev0, Memory_Check, c0ckectrl, c1ckectrl, offset; + unsigned long ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register, Misc_Register; + long *ptr; + + //Device_ID = pci_config_read16(dram_dev->dev.addr, 0x02); + //Device_ID &= 0xFFFF; + + // Now, read MMR Base Address + dev0 = pci_config_read32(dram_dev->dev.addr, 0x48); + dev0 &= 0xFFFFC000; + + ptr = (long*)(dev0 + 0x260); + c0ckectrl = *ptr & 0xFFFFFFFF; + + ptr = (long*)(dev0 + 0x660); + c1ckectrl = *ptr & 0xFFFFFFFF; + + // If DIMM 0 not populated, check DIMM 1 + ((c0ckectrl) >> 20 & 0xF) ? (offset = 0) : (offset = 0x400); + + ptr = (long*)(dev0 + offset + 0x265); + ODT_Control_Register = *ptr & 0xFFFFFFFF; + + ptr = (long*)(dev0 + offset + 0x25D); + Precharge_Register = *ptr & 0xFFFFFFFF; + + ptr = (long*)(dev0 + offset + 0x252); + ACT_Register = *ptr & 0xFFFFFFFF; + + ptr = (long*)(dev0 + offset + 0x258); + Read_Register = *ptr & 0xFFFFFFFF; + + ptr = (long*)(dev0 + offset + 0x244); + Misc_Register = *ptr & 0xFFFFFFFF; + + ptr = (long*)(dev0 + offset + 0x1E8); + Memory_Check = *ptr & 0xFFFFFFFF; + + // On P45, check 1A8 + if(dram_dev->device_id > 0x2E00) { + ptr = (long*)(dev0 + offset + 0x1A8); + Memory_Check = *ptr & 0xFFFFFFFF; + Memory_Check >>= 2; + Memory_Check &= 1; + Memory_Check = !Memory_Check; + } else { + ptr = (long*)(dev0 + offset + 0x1E8); + Memory_Check = *ptr & 0xFFFFFFFF; + } + + // Determine DDR-II or DDR-III + if (Memory_Check & 1) + Platform.RAM.Type = SMB_MEM_TYPE_DDR2; + else + Platform.RAM.Type = SMB_MEM_TYPE_DDR3; + + // CAS Latency (tCAS) + if(dram_dev->device_id > 0x2E00) + Platform.RAM.CAS = ((ODT_Control_Register >> 8) & 0x3F) - 6; + else + Platform.RAM.CAS = ((ODT_Control_Register >> 8) & 0x3F) - 9; + + // RAS-To-CAS (tRCD) + Platform.RAM.TRC = (Read_Register >> 17) & 0xF; + + // RAS Precharge (tRP) + Platform.RAM.TRP = (ACT_Register >> 13) & 0xF; + + // RAS Active to precharge (tRAS) + Platform.RAM.RAS = Precharge_Register & 0x3F; + + // Channel configuration + if (((c0ckectrl >> 20) & 0xF) && ((c1ckectrl >> 20) & 0xF)) + Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL; + else + Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE; +} + +// Get Nehalem Memory Timings +static void get_timings_nhm(pci_dt_t *dram_dev) +{ + unsigned long mc_channel_bank_timing, mc_control, mc_channel_mrs_value; + int fvc_bn = 4; + + // Find which channels are populated + mc_control = pci_config_read16(PCIADDR(nhm_bus, 3, 0), 0x48); + mc_control = (mc_control >> 8) & 0x7; + + // DDR-III + Platform.RAM.Type = SMB_MEM_TYPE_DDR3; + + // Get the first valid channel + if(mc_control & 1) + fvc_bn = 4; + else if(mc_control & 2) + fvc_bn = 5; + else if(mc_control & 7) + fvc_bn = 6; + + // Now, detect timings + mc_channel_bank_timing = pci_config_read32(PCIADDR(nhm_bus, fvc_bn, 0), 0x88); + mc_channel_mrs_value = pci_config_read32(PCIADDR(nhm_bus, fvc_bn, 0), 0x70); + + // CAS Latency (tCAS) + Platform.RAM.CAS = ((mc_channel_mrs_value >> 4) & 0xF ) + 4; + + // RAS-To-CAS (tRCD) + Platform.RAM.TRC = (mc_channel_bank_timing >> 9) & 0xF; + + // RAS Precharge (tRP) + Platform.RAM.CAS = (mc_channel_bank_timing >> 4) & 0x1F; + + // RAS Active to precharge (tRAS) + Platform.RAM.TRP = mc_channel_bank_timing & 0xF; + + // Single , Dual or Triple Channels + if (mc_control == 1 || mc_control == 2 || mc_control == 4 ) + Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE; + else if (mc_control == 7) + Platform.RAM.Channels = SMB_MEM_CHANNEL_TRIPLE; + else + Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL; +} + +static struct mem_controller_t dram_controllers[] = { + + // Default unknown chipset + { 0, 0, "", NULL, NULL, NULL }, + + // Intel + { 0x8086, 0x7190, "VMWare", NULL, NULL, NULL }, + + { 0x8086, 0x1A30, "i845", NULL, NULL, NULL }, + + { 0x8086, 0x2970, "i946PL/GZ", setup_p35, get_fsb_i965, get_timings_i965 }, + { 0x8086, 0x2990, "Q963/Q965", setup_p35, get_fsb_i965, get_timings_i965 }, + { 0x8086, 0x29A0, "P965/G965", setup_p35, get_fsb_i965, get_timings_i965 }, + + { 0x8086, 0x2A00, "GM965/GL960", setup_p35, get_fsb_im965, get_timings_im965 }, + { 0x8086, 0x2A10, "GME965/GLE960", setup_p35, get_fsb_im965, get_timings_im965 }, + { 0x8086, 0x2A40, "PM/GM45/47", setup_p35, get_fsb_im965, get_timings_im965 }, + + { 0x8086, 0x29B0, "Q35", setup_p35, get_fsb_i965, get_timings_p35 }, + { 0x8086, 0x29C0, "P35/G33", setup_p35, get_fsb_i965, get_timings_p35 }, + { 0x8086, 0x29D0, "Q33", setup_p35, get_fsb_i965, get_timings_p35 }, + { 0x8086, 0x29E0, "X38/X48", setup_p35, get_fsb_i965, get_timings_p35 }, + { 0x8086, 0x2E00, "Eaglelake", setup_p35, get_fsb_i965, get_timings_p35 }, + { 0x8086, 0x2E10, "Q45/Q43", setup_p35, get_fsb_i965, get_timings_p35 }, + { 0x8086, 0x2E20, "P45/G45", setup_p35, get_fsb_i965, get_timings_p35 }, + { 0x8086, 0x2E30, "G41", setup_p35, get_fsb_i965, get_timings_p35 }, + + { 0x8086, 0xD131, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + { 0x8086, 0xD132, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + { 0x8086, 0x3400, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + { 0x8086, 0x3401, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + { 0x8086, 0x3402, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + { 0x8086, 0x3403, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + { 0x8086, 0x3404, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + { 0x8086, 0x3405, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + { 0x8086, 0x3406, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + { 0x8086, 0x3407, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + +}; + +static const char *memory_channel_types[] = +{ + "Unknown", "Single", "Dual", "Triple" +}; + +void scan_dram_controller(pci_dt_t *dram_dev) +{ + int i; + for(i = 1; i < sizeof(dram_controllers) / sizeof(dram_controllers[0]); i++) + if ((dram_controllers[i].vendor == dram_dev->vendor_id) + && (dram_controllers[i].device == dram_dev->device_id)) + { + verbose("%s%s DRAM Controller [%4x:%4x] at %02x:%02x.%x\n", + (dram_dev->vendor_id == 0x8086) ? "Intel " : "" , + dram_controllers[i].name, dram_dev->vendor_id, dram_dev->device_id, + dram_dev->dev.bits.bus, dram_dev->dev.bits.dev, dram_dev->dev.bits.func); + + if (dram_controllers[i].initialise != NULL) + dram_controllers[i].initialise(dram_dev); + + if (dram_controllers[i].poll_timings != NULL) + dram_controllers[i].poll_timings(dram_dev); + + if (dram_controllers[i].poll_speed != NULL) + dram_controllers[i].poll_speed(dram_dev); + + verbose("Frequency detected: %d MHz (%d) %s Channel %d-%d-%d-%d\n", + (uint32_t)Platform.RAM.Frequency / 1000000, + (uint32_t)Platform.RAM.Frequency / 500000, + memory_channel_types[Platform.RAM.Channels], + Platform.RAM.CAS, Platform.RAM.TRC, Platform.RAM.TRP, Platform.RAM.RAS + ); + + } +} Index: branches/meklort/i386/libsaio/ntfs.c =================================================================== --- branches/meklort/i386/libsaio/ntfs.c (revision 504) +++ branches/meklort/i386/libsaio/ntfs.c (revision 505) @@ -295,6 +295,41 @@ return; } +long NTFSGetUUID(CICell ih, char *uuidStr) +{ + bool NTFSProbe(const void*); + + struct bootfile *boot; + void *buf = malloc(MAX_BLOCK_SIZE); + if ( !buf ) + return -1; + + /* + * Read the boot sector, check signatures, and do some minimal + * sanity checking. NOTE: the size of the read below is intended + * to be a multiple of all supported block sizes, so we don't + * have to determine or change the device's block size. + */ + Seek(ih, 0); + Read(ih, (long)buf, MAX_BLOCK_SIZE); + + boot = (struct bootfile *) buf; + + // Check for NTFS signature + if ( memcmp((void*)boot->bf_sysid, NTFS_BBID, NTFS_BBIDLEN) != 0 ) + return -1; + + // Check for non-null volume serial number + if( !boot->bf_volsn ) + return -1; + + // Use UUID like the one you get on Windows + sprintf(uuidStr, "%04X-%04X", (unsigned short)(boot->bf_volsn >> 16) & 0xFFFF, + (unsigned short)boot->bf_volsn & 0xFFFF); + + return 0; +} + bool NTFSProbe(const void * buffer) { bool result = false; @@ -307,5 +342,3 @@ return result; } - - Index: branches/meklort/i386/libsaio/nvidia.c =================================================================== --- branches/meklort/i386/libsaio/nvidia.c (revision 504) +++ branches/meklort/i386/libsaio/nvidia.c (revision 505) @@ -267,11 +267,12 @@ { 0x10DE05E2, "GeForce GTX 260" }, { 0x10DE05E3, "GeForce GTX 285" }, { 0x10DE05E6, "GeForce GTX 275" }, + { 0x10DE05EA, "GeForce GTX 260" }, { 0x10DE05EB, "GeForce GTX 295" }, { 0x10DE05F9, "Quadro CX" }, { 0x10DE05FD, "Quadro FX 5800" }, { 0x10DE05FE, "Quadro FX 4800" }, - { 0x10DE0600, "GeForce 8800 GTS 512" }, + { 0x10DE0600, "GeForce 8800 GTS 512" }, { 0x10DE0602, "GeForce 8800 GT" }, { 0x10DE0604, "GeForce 9800 GX2" }, { 0x10DE0605, "GeForce 9800 GT" }, @@ -290,7 +291,7 @@ { 0x10DE0614, "GeForce 9800 GT" }, { 0x10DE0615, "GeForce GTS 250" }, { 0x10DE0617, "GeForce 9800M GTX" }, - { 0x10DE0618, "GeForce GTX 260M" }, + { 0x10DE0618, "GeForce GTX 260M" }, { 0x10DE061A, "Quadro FX 3700" }, { 0x10DE061C, "Quadro FX 3600M" }, { 0x10DE061D, "Quadro FX 2800M" }, @@ -322,6 +323,10 @@ { 0x10DE065A, "Quadro FX 1700M" }, { 0x10DE065B, "GeForce 9400 GT" }, { 0x10DE065C, "Quadro FX 770M" }, + { 0x10DE06C0, "GeForce GTX 480" }, + { 0x10DE06C4, "GeForce GTX 465" }, + { 0x10DE06CA, "GeForce GTX 480M" }, + { 0x10DE06CD, "GeForce GTX 470" }, { 0x10DE06E0, "GeForce 9300 GE" }, { 0x10DE06E1, "GeForce 9300 GS" }, { 0x10DE06E4, "GeForce 8400 GS" }, @@ -336,10 +341,12 @@ { 0x10DE06F9, "Quadro FX 370 LP" }, { 0x10DE06FA, "Quadro NVS 450" }, { 0x10DE06FD, "Quadro NVS 295" }, - { 0x10DE087D, "ION 9400M" }, - { 0x10DE087E, "ION LE" }, + { 0x10DE086C, "GeForce 9300/nForce 730i" }, + { 0x10DE087D, "ION 9400M" }, + { 0x10DE087E, "ION LE" }, { 0x10DE0A20, "GeForce GT220" }, { 0x10DE0A23, "GeForce 210" }, + { 0x10DE0A28, "GeForce GT 230M" }, { 0x10DE0A2A, "GeForce GT 230M" }, { 0x10DE0A34, "GeForce GT 240M" }, { 0x10DE0A60, "GeForce G210" }, @@ -351,7 +358,14 @@ { 0x10DE0A78, "Quadro FX 380 LP" }, { 0x10DE0CA3, "GeForce GT 240" }, { 0x10DE0CA8, "GeForce GTS 260M" }, - { 0x10DE0CA9, "GeForce GTS 250M" } + { 0x10DE0CA9, "GeForce GTS 250M" }, + { 0x10DE0CA3, "GeForce GT240" }, + { 0x10DE0E22, "GeForce GTX 460" }, + { 0x10DE0E24, "GeForce GTX 460" }, + { 0x10DE06D1, "Tesla C2050" }, // TODO: sub-device id: 0x0771 + { 0x10DE06D1, "Tesla C2070" }, // TODO: sub-device id: 0x0772 + { 0x10DE06DE, "Tesla M2050" }, // TODO: sub-device id: 0x0846 + { 0x10DE06DE, "Tesla M2070" } // TODO: sub-device id: ? }; static uint16_t swap16(uint16_t x) @@ -650,20 +664,43 @@ return 0; } +unsigned long long mem_detect(volatile uint8_t *regs, uint8_t nvCardType, pci_dt_t *nvda_dev) +{ + unsigned long long vram_size = 0; + + if (nvCardType < NV_ARCH_50) { + vram_size = REG32(NV04_PFB_FIFO_DATA); + vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK; + } + else if (nvCardType >= NV_ARCH_C0) { + vram_size = REG32(NVC0_MEM_CTRLR_COUNT); + vram_size *= REG32(NVC0_MEM_CTRLR_RAM_AMOUNT); + vram_size <<= 20; + } + else { + vram_size = REG32(NV04_PFB_FIFO_DATA); + vram_size |= (vram_size & 0xff) << 32; + vram_size &= 0xffffffff00ll; + } + + return vram_size; +} + bool setup_nvidia_devprop(pci_dt_t *nvda_dev) { struct DevPropDevice *device; - char *devicepath; + char *devicepath; struct pci_rom_pci_header_t *rom_pci_header; - volatile uint8_t *regs; + volatile uint8_t *regs; uint8_t *rom; uint8_t *nvRom; - uint32_t videoRam; + uint8_t nvCardType; + unsigned long long videoRam; uint32_t nvBiosOveride; uint32_t bar[7]; uint32_t boot_display; - int nvPatch; - int len; + int nvPatch; + int len; char biosVersion[32]; char nvFilename[32]; char kNVCAP[12]; @@ -674,15 +711,20 @@ devicepath = get_pci_dev_path(nvda_dev); bar[0] = pci_config_read32(nvda_dev->dev.addr, 0x10 ); regs = (uint8_t *) (bar[0] & ~0x0f); + + delay(50); + + // get card type + nvCardType = (REG32(0) >> 20) & 0x1ff; // Amount of VRAM in kilobytes - videoRam = (REG32(0x10020c) & 0xfff00000) >> 10; + videoRam = mem_detect(regs, nvCardType, nvda_dev); model = get_nvidia_model((nvda_dev->vendor_id << 16) | nvda_dev->device_id); - + verbose("nVidia %s %dMB NV%02x [%04x:%04x] :: %s\n", - model, (videoRam / 1024), - (REG32(0) >> 20) & 0x1ff, nvda_dev->vendor_id, nvda_dev->device_id, - devicepath); + model, (uint32_t)(videoRam / 1024 / 1024), + (REG32(0) >> 20) & 0x1ff, nvda_dev->vendor_id, nvda_dev->device_id, + devicepath); rom = malloc(NVIDIA_ROM_SIZE); sprintf(nvFilename, "/Extra/%04x_%04x.rom", (uint16_t)nvda_dev->vendor_id, (uint16_t)nvda_dev->device_id); @@ -768,10 +810,41 @@ uint8_t built_in = 0x01; devprop_add_value(device, "@0,built-in", &built_in, 1); } + + // get bios version + const int MAX_BIOS_VERSION_LENGTH = 32; + char* version_str = (char*)malloc(MAX_BIOS_VERSION_LENGTH); + memset(version_str, 0, MAX_BIOS_VERSION_LENGTH); + int i, version_start; + int crlf_count = 0; + // only search the first 384 bytes + for(i = 0; i < 0x180; i++) { + if(rom[i] == 0x0D && rom[i+1] == 0x0A) { + crlf_count++; + // second 0x0D0A was found, extract bios version + if(crlf_count == 2) { + if(rom[i-1] == 0x20) i--; // strip last " " + for(version_start = i; version_start > (i-MAX_BIOS_VERSION_LENGTH); version_start--) { + // find start + if(rom[version_start] == 0x00) { + version_start++; + + // strip "Version " + if(strncmp((const char*)rom+version_start, "Version ", 8) == 0) { + version_start += 8; + } + + strncpy(version_str, (const char*)rom+version_start, i-version_start); + break; + } + } + break; + } + } + } + + sprintf(biosVersion, "%s", (nvBiosOveride > 0) ? nvFilename : version_str); - videoRam *= 1024; - sprintf(biosVersion, "xx.xx.xx - %s", (nvBiosOveride > 0) ? nvFilename : "internal"); - sprintf(kNVCAP, "NVCAP_%04x", nvda_dev->device_id); if (getValueForKey(kNVCAP, &value, &len, &bootInfo->bootConfig) && len == NVCAP_LEN * 2) { uint8_t new_NVCAP[NVCAP_LEN]; Index: branches/meklort/i386/libsaio/sys.c =================================================================== --- branches/meklort/i386/libsaio/sys.c (revision 504) +++ branches/meklort/i386/libsaio/sys.c (revision 505) @@ -63,7 +63,9 @@ #include "libsaio.h" #include "boot.h" #include "bootstruct.h" +#include "disk.h" #include "ramdisk.h" +#include "xml.h" #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 # include #else @@ -87,17 +89,22 @@ int type; }; +// Device entries must be ordered by bios device numbers. static struct devsw devsw[] = { - { "sd", 0x80, kBIOSDevTypeHardDrive }, /* DEV_SD */ - { "hd", 0x80, kBIOSDevTypeHardDrive }, /* DEV_HD */ - { "fd", 0x00, kBIOSDevTypeFloppy }, /* DEV_FD */ - { "en", 0xE0, kBIOSDevTypeNetwork }, /* DEV_EN */ + { "hd", 0x80, kBIOSDevTypeHardDrive }, /* DEV_HD */ + { "en", 0xE0, kBIOSDevTypeNetwork }, /* DEV_EN */ { "rd", 0x100, kBIOSDevTypeHardDrive }, { "bt", 0x101, kBIOSDevTypeHardDrive }, // turbo - type for booter partition { 0, 0 } }; +// Pseudo BIOS devices +enum { + kPseudoBIOSDevRAMDisk = 0x100, + kPseudoBIOSDevBooter = 0x101 +}; + /* * Max number of file descriptors. */ @@ -111,10 +118,6 @@ BVRef gBIOSBootVolume = NULL; BVRef gBootVolume; -// zef - ramdisk variables -//extern BVRef gRAMDiskVolume; -//extern bool gRAMDiskBTAliased; - //static BVRef getBootVolumeRef( const char * path, const char ** outPath ); static BVRef newBootVolumeRef( int biosdev, int partno ); @@ -294,7 +297,7 @@ // GetDirEntry - LOW-LEVEL FILESYSTEM FUNCTION. // Fetch the next directory entry for the given directory. -long GetDirEntry(const char * dirSpec, long * dirIndex, const char ** name, +long GetDirEntry(const char * dirSpec, long long * dirIndex, const char ** name, long * flags, long * time) { const char * dirPath; @@ -322,7 +325,7 @@ long GetFileInfo(const char * dirSpec, const char * name, long * flags, long * time) { - long index = 0; + long long index = 0; const char * entryName; if (gMakeDirSpec == 0) @@ -403,7 +406,6 @@ return io; } -#if UNUSED //========================================================================== // openmem() @@ -425,7 +427,6 @@ return fdesc; } -#endif //========================================================================== // open() - Open the file specified by 'path' for reading. @@ -516,17 +517,7 @@ } } } - // turbo - bt(0,0) hook - if ((dp->biosdev + unit) == 0x101) { - // zef - use the ramdisk if available and the alias is active. - if (gRAMDiskVolume != NULL && gRAMDiskBTAliased) { - bvr = gRAMDiskVolume; - } else { - bvr = gBIOSBootVolume; - } - } else { - bvr = newBootVolumeRef(dp->biosdev + unit, partition); - } + bvr = newBootVolumeRef(dp->biosdev + unit, partition); return open_bvr(bvr, path, flags); } } @@ -602,6 +593,62 @@ } //========================================================================== +// write() - Write up to 'count' bytes of data to the file descriptor +// from the buffer pointed to by buf. + +int write(int fdesc, const char * buf, int count) +{ + struct iob * io; + + if ((io = iob_from_fdesc(fdesc)) == NULL) + return (-1); + + if ((io->i_offset + count) > (unsigned int)io->i_filesize) + count = io->i_filesize - io->i_offset; + + if (count <= 0) + return 0; // end of file + + bcopy(buf, io->i_buf + io->i_offset, count); + + io->i_offset += count; + + return count; +} + +int writebyte(int fdesc, char value) +{ + struct iob * io; + + if ((io = iob_from_fdesc(fdesc)) == NULL) + return (-1); + + if ((io->i_offset + 1) > (unsigned int)io->i_filesize) + return 0; // end of file + + io->i_buf[io->i_offset++] = value; + + return 1; +} + +int writeint(int fdesc, int value) +{ + struct iob * io; + + if ((io = iob_from_fdesc(fdesc)) == NULL) + return (-1); + + if ((io->i_offset + 4) > (unsigned int)io->i_filesize) + return 0; // end of file + + bcopy(&value, io->i_buf + io->i_offset, 4); + + io->i_offset += 4; + + return 4; +} + +//========================================================================== // file_size() - Returns the size of the file described by the file // descriptor. @@ -762,9 +809,9 @@ BVRef selectBootVolume( BVRef chain ) { - bool filteredChain = false; + bool filteredChain = false; bool foundPrimary = false; - BVRef bvr, bvr1 = 0, bvr2 = 0; + BVRef bvr, bvr1 = 0, bvr2 = 0; if (chain->filtered) filteredChain = true; @@ -774,54 +821,46 @@ return bvr; /* - * Checking "Default Partition" key in system configuration - use format: hd(x,y) - + * Checking "Default Partition" key in system configuration - use format: hd(x,y), the volume UUID or label - * to override the default selection. * We accept only kBVFlagSystemVolume or kBVFlagForeignBoot volumes. */ - const char * val; - char testStr[64]; - int cnt; - - if (getValueForKey(kDefaultPartition, &val, &cnt, &bootInfo->bootConfig) && cnt >= 7 && filteredChain) - { - for ( bvr = chain; bvr; bvr = bvr->next ) - { - *testStr = '\0'; - if ( bvr->biosdev >= 0x80 && bvr->biosdev < 0x100 - && ( bvr->flags & ( kBVFlagSystemVolume|kBVFlagForeignBoot ) ) ) - { - sprintf(testStr, "hd(%d,%d)", bvr->biosdev - 0x80, bvr->part_no); - if (strcmp(testStr, val) == 0) - return bvr; - } + char *val = XMLDecode(getStringForKey(kDefaultPartition, &bootInfo->bootConfig)); + if (val) { + for ( bvr = chain; bvr; bvr = bvr->next ) { + if (matchVolumeToString(bvr, val, false)) { + free(val); + return bvr; + } + } + free(val); } - } - + /* * Scannig the volume chain backwards and trying to find * a HFS+ volume with valid boot record signature. * If not found any active partition then we will * select this volume as the boot volume. */ - for ( bvr = chain; bvr; bvr = bvr->next ) - { - if ( bvr->flags & kBVFlagPrimary && bvr->biosdev == gBIOSDev ) foundPrimary = true; - // zhell -- Undo a regression that was introduced from r491 to 492. - // if gBIOSBootVolume is set already, no change is required - if ( bvr->flags & (kBVFlagBootable|kBVFlagSystemVolume) - && gBIOSBootVolume - && (!filteredChain || (filteredChain && bvr->visible)) - && bvr->biosdev == gBIOSDev ) - bvr2 = bvr; - // zhell -- if gBIOSBootVolume is NOT set, we use the "if" statement - // from r491, - if ( bvr->flags & kBVFlagBootable - && ! gBIOSBootVolume - && bvr->biosdev == gBIOSDev ) - bvr2 = bvr; - } - - + for ( bvr = chain; bvr; bvr = bvr->next ) + { + if ( bvr->flags & kBVFlagPrimary && bvr->biosdev == gBIOSDev ) foundPrimary = true; + // zhell -- Undo a regression that was introduced from r491 to 492. + // if gBIOSBootVolume is set already, no change is required + if ( bvr->flags & (kBVFlagBootable|kBVFlagSystemVolume) + && gBIOSBootVolume + && (!filteredChain || (filteredChain && bvr->visible)) + && bvr->biosdev == gBIOSDev ) + bvr2 = bvr; + // zhell -- if gBIOSBootVolume is NOT set, we use the "if" statement + // from r491, + if ( bvr->flags & kBVFlagBootable + && ! gBIOSBootVolume + && bvr->biosdev == gBIOSDev ) + bvr2 = bvr; + } + + /* * Use the standrad method for selecting the boot volume. */ @@ -832,12 +871,12 @@ if ( bvr->flags & kBVFlagNativeBoot && bvr->biosdev == gBIOSDev ) bvr1 = bvr; if ( bvr->flags & kBVFlagPrimary && bvr->biosdev == gBIOSDev ) bvr2 = bvr; } - } - - bvr = bvr2 ? bvr2 : - bvr1 ? bvr1 : chain; - - return bvr; + } + + bvr = bvr2 ? bvr2 : + bvr1 ? bvr1 : chain; + + return bvr; } //========================================================================== @@ -957,21 +996,8 @@ if (*cp == RP) cp++; biosdev = dp->biosdev + unit; + bvr = newBootVolumeRef(biosdev, part); - // turbo - bt(0,0) hook - if (biosdev == 0x101) - { - // zef - use the ramdisk if available and the alias is active. - if (gRAMDiskVolume != NULL && gRAMDiskBTAliased) - bvr = gRAMDiskVolume; - else - bvr = gBIOSBootVolume; - } - else - { - bvr = newBootVolumeRef(biosdev, part); - } - if(bvr == NULL) return NULL; } @@ -994,27 +1020,69 @@ } //========================================================================== - // Function name is a misnomer as scanBootVolumes usually calls diskScanBootVolumes // which caches the information. So it's only allocated on the first run. static BVRef newBootVolumeRef( int biosdev, int partno ) { - BVRef bvr, bvr1, bvrChain; + BVRef bvr, bvr1, bvrChain; - // Fetch the volume list from the device. + bvr = bvr1 = NULL; - scanBootVolumes( biosdev, NULL ); - bvrChain = getBVChainForBIOSDev(biosdev); + // Try resolving "rd" and "bt" devices first. + if (biosdev == kPseudoBIOSDevRAMDisk) + { + if (gRAMDiskVolume) + bvr1 = gRAMDiskVolume; + } + else if (biosdev == kPseudoBIOSDevBooter) + { + if (gRAMDiskVolume != NULL && gRAMDiskBTAliased) + bvr1 = gRAMDiskVolume; + else + bvr1 = gBIOSBootVolume; + } + else + { + // Fetch the volume list from the device. - // Look for a perfect match based on device and partition number. + scanBootVolumes( biosdev, NULL ); + bvrChain = getBVChainForBIOSDev(biosdev); - for ( bvr1 = NULL, bvr = bvrChain; bvr; bvr = bvr->next ) - { - if ( ( bvr->flags & kBVFlagNativeBoot ) == 0 ) continue; + // Look for a perfect match based on device and partition number. + + for ( bvr1 = NULL, bvr = bvrChain; bvr; bvr = bvr->next ) + { + if ( ( bvr->flags & kBVFlagNativeBoot ) == 0 ) continue; + + bvr1 = bvr; + if ( bvr->part_no == partno ) break; + } + } + + return bvr ? bvr : bvr1; +} + +//========================================================================== +// getDeviceDescription() - Extracts unit number and partition number +// from bvr structure into "dw(u,p)" format. +// Returns length of the out string +int getDeviceDescription(BVRef bvr, char *str) +{ + if(!str) + return 0; - bvr1 = bvr; - if ( bvr->part_no == partno ) break; - } + *str = '\0'; - return bvr ? bvr : bvr1; + if (bvr) + { + const struct devsw *dp = devsw; + while(dp->name && bvr->biosdev >= dp->biosdev) + dp++; + + dp--; + if (dp->name) + return sprintf(str, "%s(%d,%d)", dp->name, bvr->biosdev - dp->biosdev, bvr->part_no); + } + + return 0; } Index: branches/meklort/i386/libsaio/dram_controllers.h =================================================================== --- branches/meklort/i386/libsaio/dram_controllers.h (revision 0) +++ branches/meklort/i386/libsaio/dram_controllers.h (revision 505) @@ -0,0 +1,32 @@ +/* + * dram controller access and scan from the pci host controller + * Integrated and adapted for chameleon 2.0 RC5 by Rekursor from bs0d work + * original source comes from: + * + * memtest86 + * + * Released under version 2 of the Gnu Public License. + * By Chris Brady, cbrady@sgi.com + * ---------------------------------------------------- + * MemTest86+ V4.00 Specific code (GPL V2.0) + * By Samuel DEMEULEMEESTER, sdemeule@memtest.org + * http://www.canardpc.com - http://www.memtest.org + */ + +#ifndef __LIBSAIO_DRAM_CONTROLLERS_H +#define __LIBSAIO_DRAM_CONTROLLERS_H + +#include "libsaio.h" + +void scan_dram_controller(); + +struct mem_controller_t { + uint16_t vendor; + uint16_t device; + char *name; + void (*initialise)(pci_dt_t *dram_dev); + void (*poll_speed)(pci_dt_t *dram_dev); + void (*poll_timings)(pci_dt_t *dram_dev); +}; + +#endif /* !__LIBSAIO_DRAM_CONTROLLERS_H */ Index: branches/meklort/i386/libsaio/nbp.c =================================================================== --- branches/meklort/i386/libsaio/nbp.c (revision 504) +++ branches/meklort/i386/libsaio/nbp.c (revision 505) @@ -96,7 +96,7 @@ /*========================================================================== * GetDirEntry is not supported. */ -static long NBPGetDirEntry(CICell ih, char * dirPath, long * dirIndex, +static long NBPGetDirEntry(CICell ih, char * dirPath, long long * dirIndex, char ** name, long * flags, long * time, FinderInfo * finderInfo, long * infoValid) { Index: branches/meklort/i386/libsaio/ntfs.h =================================================================== --- branches/meklort/i386/libsaio/ntfs.h (revision 504) +++ branches/meklort/i386/libsaio/ntfs.h (revision 505) @@ -22,4 +22,4 @@ extern void NTFSGetDescription(CICell ih, char *str, long strMaxLen); extern bool NTFSProbe (const void *buf); - +extern long NTFSGetUUID(CICell ih, char *uuidStr); Index: branches/meklort/i386/libsaio/nvidia.h =================================================================== --- branches/meklort/i386/libsaio/nvidia.h (revision 504) +++ branches/meklort/i386/libsaio/nvidia.h (revision 505) @@ -67,10 +67,15 @@ uint8_t size; /* Size in multiples of 512 */ }; -#define NV_PROM_OFFSET 0x300000 -#define NV_PROM_SIZE 0x0000ffff -#define NV_PRAMIN_OFFSET 0x00700000 -#define NV_PRAMIN_SIZE 0x00100000 +#define NV_PROM_OFFSET 0x300000 +#define NV_PROM_SIZE 0x0000ffff +#define NV_PRAMIN_OFFSET 0x00700000 +#define NV_PRAMIN_SIZE 0x00100000 +#define NV04_PFB_FIFO_DATA 0x0010020c +#define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000 +#define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20 +#define NVC0_MEM_CTRLR_COUNT 0x00121c74 +#define NVC0_MEM_CTRLR_RAM_AMOUNT 0x0010f20c #define NV_PBUS_PCI_NV_20 0x00001850 #define NV_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED (0 << 0) @@ -87,6 +92,7 @@ #define NV_ARCH_30 0x30 #define NV_ARCH_40 0x40 #define NV_ARCH_50 0x50 +#define NV_ARCH_C0 0xC0 #define CHIPSET_NV03 0x0010 #define CHIPSET_NV04 0x0020 Index: branches/meklort/i386/libsaio/acpi.h =================================================================== --- branches/meklort/i386/libsaio/acpi.h (revision 504) +++ branches/meklort/i386/libsaio/acpi.h (revision 505) @@ -59,6 +59,32 @@ } __attribute__((packed)); // TODO Migrate +struct acpi_2_ssdt { + char Signature[4]; + uint32_t Length; + uint8_t Revision; + uint8_t Checksum; + char OEMID[6]; + char OEMTableId[8]; + uint32_t OEMRevision; + uint32_t CreatorId; + uint32_t CreatorRevision; +} __attribute__((packed)); + +// TODO Migrate +struct acpi_2_dsdt { + char Signature[4]; + uint32_t Length; + uint8_t Revision; + uint8_t Checksum; + char OEMID[6]; + char OEMTableId[8]; + uint32_t OEMRevision; + uint32_t CreatorId; + uint32_t CreatorRevision; +} __attribute__((packed)); + +// TODO Migrate struct acpi_2_fadt { char Signature[4]; uint32_t Length; @@ -73,8 +99,39 @@ uint32_t DSDT; uint8_t Model; // JrCs uint8_t PM_Profile; // JrCs - /*We absolutely don't care about theese fields*/ - uint8_t notimp1[66]; + uint16_t SCI_Interrupt; + uint32_t SMI_Command_Port; + uint8_t ACPI_Enable; + uint8_t ACPI_Disable; + uint8_t S4BIOS_Command; + uint8_t PState_Control; + uint32_t PM1A_Event_Block_Address; + uint32_t PM1B_Event_Block_Address; + uint32_t PM1A_Control_Block_Address; + uint32_t PM1B_Control_Block_Address; + uint32_t PM2_Control_Block_Address; + uint32_t PM_Timer_Block_Address; + uint32_t GPE0_Block_Address; + uint32_t GPE1_Block_Address; + uint8_t PM1_Event_Block_Length; + uint8_t PM1_Control_Block_Length; + uint8_t PM2_Control_Block_Length; + uint8_t PM_Timer_Block_Length; + uint8_t GPE0_Block_Length; + uint8_t GPE1_Block_Length; + uint8_t GPE1_Base_Offset; + uint8_t CST_Support; + uint16_t C2_Latency; + uint16_t C3_Latency; + uint16_t CPU_Cache_Size; + uint16_t Cache_Flush_Stride; + uint8_t Duty_Cycle_Offset; + uint8_t Duty_Cycle_Width; + uint8_t RTC_Day_Alarm_Index; + uint8_t RTC_Month_Alarm_Index; + uint8_t RTC_Century_Index; + uint16_t Boot_Flags; + uint8_t Reserved0; /* Begin Asere */ //Reset Fix uint32_t Flags; @@ -93,18 +150,4 @@ uint8_t notimp2[96]; } __attribute__((packed)); -struct acpi_2_dsdt { - char Signature[4]; - uint32_t Length; - uint8_t Revision; - uint8_t Checksum; - char OEMID[6]; - char OEMTableId[8]; - char OEMRevision[4]; - char CreatorId[4]; - char CreatorRevision[4]; - char dsdtStart; // actual length is .Length -} __attribute__((packed)); - - #endif /* !__LIBSAIO_ACPI_H */ Index: branches/meklort/i386/libsaio/platform.c =================================================================== --- branches/meklort/i386/libsaio/platform.c (revision 504) +++ branches/meklort/i386/libsaio/platform.c (revision 505) @@ -12,6 +12,7 @@ #include "cpu.h" #include "mem.h" #include "spd.h" +#include "dram_controllers.h" #ifndef DEBUG_PLATFORM #define DEBUG_PLATFORM 0 @@ -24,6 +25,7 @@ #endif PlatformInfo_t Platform; +pci_dt_t * dram_controller_dev = NULL; /** Return if a CPU feature specified by feature is activated (true) or not (false) */ bool platformCPUFeature(uint32_t feature) @@ -37,13 +39,21 @@ /** scan mem for memory autodection purpose */ void scan_mem() { - bool useAutodetection = false; + static bool done = false; + if (done) return; + + bool useAutodetection = true; getBoolForKey(kUseMemDetect, &useAutodetection, &bootInfo->bootConfig); if (useAutodetection) { - scan_memory(&Platform); + if (dram_controller_dev!=NULL) { + scan_dram_controller(dram_controller_dev); // Rek: pci dev ram controller direct and fully informative scan ... + } + scan_memory(&Platform); // unfortunately still necesary for some comp where spd cant read correct speed scan_spd(&Platform); + //getc(); } + done = true; } /** @@ -52,11 +62,8 @@ */ void scan_platform(void) { - memset(&Platform, 0, sizeof(Platform)); build_pci_dt(); scan_cpu(&Platform); - // disabled for now as options can't be read yet here: - // scan_mem(); - + //scan_mem(); Rek: called after pci devs init in fake_efi now ... } Index: branches/meklort/i386/libsaio/cpu.c =================================================================== --- branches/meklort/i386/libsaio/cpu.c (revision 504) +++ branches/meklort/i386/libsaio/cpu.c (revision 505) @@ -14,108 +14,10 @@ #if DEBUG_CPU #define DBG(x...) printf(x) #else -#define DBG(x...) +#define DBG(x...) msglog(x) #endif - -static inline uint64_t rdtsc64(void) -{ - uint64_t ret; - __asm__ volatile("rdtsc" : "=A" (ret)); - return ret; -} - -static inline uint64_t rdmsr64(uint32_t msr) -{ - uint64_t ret; - __asm__ volatile("rdmsr" : "=A" (ret) : "c" (msr)); - return ret; -} - -static inline void do_cpuid(uint32_t selector, uint32_t *data) -{ - asm volatile ("cpuid" - : "=a" (data[0]), - "=b" (data[1]), - "=c" (data[2]), - "=d" (data[3]) - : "a" (selector)); -} - -static inline void do_cpuid2(uint32_t selector, uint32_t selector2, uint32_t *data) -{ - asm volatile ("cpuid" - : "=a" (data[0]), - "=b" (data[1]), - "=c" (data[2]), - "=d" (data[3]) - : "a" (selector), "c" (selector2)); -} - -// DFE: enable_PIT2 and disable_PIT2 come from older xnu - /* - * Enable or disable timer 2. - * Port 0x61 controls timer 2: - * bit 0 gates the clock, - * bit 1 gates output to speaker. - */ -static inline void enable_PIT2(void) -{ - /* Enable gate, disable speaker */ - __asm__ volatile( - " inb $0x61,%%al \n\t" - " and $0xFC,%%al \n\t" /* & ~0x03 */ - " or $1,%%al \n\t" - " outb %%al,$0x61 \n\t" - : : : "%al" ); -} - -static inline void disable_PIT2(void) -{ - /* Disable gate and output to speaker */ - __asm__ volatile( - " inb $0x61,%%al \n\t" - " and $0xFC,%%al \n\t" /* & ~0x03 */ - " outb %%al,$0x61 \n\t" - : : : "%al" ); -} - -// DFE: set_PIT2_mode0, poll_PIT2_gate, and measure_tsc_frequency are -// roughly based on Linux code - -/* Set the 8254 channel 2 to mode 0 with the specified value. - In mode 0, the counter will initially set its gate low when the - timer expires. For this to be useful, you ought to set it high - before calling this function. The enable_PIT2 function does this. - */ -static inline void set_PIT2_mode0(uint16_t value) -{ - __asm__ volatile( - " movb $0xB0,%%al \n\t" - " outb %%al,$0x43 \n\t" - " movb %%dl,%%al \n\t" - " outb %%al,$0x42 \n\t" - " movb %%dh,%%al \n\t" - " outb %%al,$0x42" - : : "d"(value) /*: no clobber */ ); -} - -/* Returns the number of times the loop ran before the PIT2 signaled */ -static inline unsigned long poll_PIT2_gate(void) -{ - unsigned long count = 0; - unsigned char nmi_sc_val; - do { - ++count; - __asm__ volatile( - "inb $0x61,%0" - : "=q"(nmi_sc_val) /*:*/ /* no input */ /*:*/ /* no clobber */); - } while( (nmi_sc_val & 0x20) == 0); - return count; -} - -/* * DFE: Measures the TSC frequency in Hz (64-bit) using the ACPI PM timer */ static uint64_t measure_tsc_frequency(void) @@ -218,6 +120,8 @@ } #endif p->CPU.Vendor = p->CPU.CPUID[CPUID_0][1]; + p->CPU.Signature = p->CPU.CPUID[CPUID_1][0]; + p->CPU.Stepping = bitfield(p->CPU.CPUID[CPUID_1][0], 3, 0); p->CPU.Model = bitfield(p->CPU.CPUID[CPUID_1][0], 7, 4); p->CPU.Family = bitfield(p->CPU.CPUID[CPUID_1][0], 11, 8); p->CPU.ExtModel = bitfield(p->CPU.CPUID[CPUID_1][0], 19, 16); @@ -226,7 +130,37 @@ p->CPU.NoCores = bitfield(p->CPU.CPUID[CPUID_4][0], 31, 26) + 1; p->CPU.Model += (p->CPU.ExtModel << 4); - + + /* get brand string (if supported) */ + /* Copyright: from Apple's XNU cpuid.c */ + if (p->CPU.CPUID[CPUID_80][0] > 0x80000004) { + uint32_t reg[4]; + char str[128], *s; + /* + * The brand string 48 bytes (max), guaranteed to + * be NUL terminated. + */ + do_cpuid(0x80000002, reg); + bcopy((char *)reg, &str[0], 16); + do_cpuid(0x80000003, reg); + bcopy((char *)reg, &str[16], 16); + do_cpuid(0x80000004, reg); + bcopy((char *)reg, &str[32], 16); + for (s = str; *s != '\0'; s++) { + if (*s != ' ') break; + } + + strlcpy(p->CPU.BrandString, s, sizeof(p->CPU.BrandString)); + + if (!strncmp(p->CPU.BrandString, CPU_STRING_UNKNOWN, min(sizeof(p->CPU.BrandString), strlen(CPU_STRING_UNKNOWN) + 1))) { + /* + * This string means we have a firmware-programmable brand string, + * and the firmware couldn't figure out what sort of CPU we have. + */ + p->CPU.BrandString[0] = '\0'; + } + } + /* setup features */ if ((bit(23) & p->CPU.CPUID[CPUID_1][3]) != 0) { p->CPU.Features |= CPU_FEATURE_MMX; @@ -249,6 +183,9 @@ if ((bit(29) & p->CPU.CPUID[CPUID_81][3]) != 0) { p->CPU.Features |= CPU_FEATURE_EM64T; } + if ((bit(5) & p->CPU.CPUID[CPUID_1][3]) != 0) { + p->CPU.Features |= CPU_FEATURE_MSR; + } //if ((bit(28) & p->CPU.CPUID[CPUID_1][3]) != 0) { if (p->CPU.NoThreads > p->CPU.NoCores) { p->CPU.Features |= CPU_FEATURE_HTT; @@ -261,7 +198,8 @@ if ((p->CPU.Vendor == 0x756E6547 /* Intel */) && ((p->CPU.Family == 0x06) || (p->CPU.Family == 0x0f))) { if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03)) { /* Nehalem CPU model */ - if (p->CPU.Family == 0x06 && (p->CPU.Model == 0x1a || p->CPU.Model == 0x1e)) { + if (p->CPU.Family == 0x06 && (p->CPU.Model == 0x1a || p->CPU.Model == 0x1e + || p->CPU.Model == 0x1f || p->CPU.Model == 0x25 || p->CPU.Model == 0x2c)) { msr = rdmsr64(MSR_PLATFORM_INFO); DBG("msr(%d): platform_info %08x\n", __LINE__, msr & 0xffffffff); currcoef = (msr >> 8) & 0xff; @@ -279,7 +217,7 @@ } cpuFrequency = tscFrequency; } else { - msr = rdmsr64(IA32_PERF_STATUS); + msr = rdmsr64(MSR_IA32_PERF_STATUS); DBG("msr(%d): ia32_perf_stat 0x%08x\n", __LINE__, msr & 0xffffffff); currcoef = (msr >> 8) & 0x1f; /* Non-integer bus ratio for the max-multi*/ @@ -359,7 +297,7 @@ p->CPU.TSCFrequency = tscFrequency; p->CPU.FSBFrequency = fsbFrequency; p->CPU.CPUFrequency = cpuFrequency; -#if DEBUG_CPU + DBG("CPU: Vendor/Model/ExtModel: 0x%x/0x%x/0x%x\n", p->CPU.Vendor, p->CPU.Model, p->CPU.ExtModel); DBG("CPU: Family/ExtFamily: 0x%x/0x%x\n", p->CPU.Family, p->CPU.ExtFamily); DBG("CPU: MaxCoef/CurrCoef: 0x%x/0x%x\n", p->CPU.MaxCoef, p->CPU.CurrCoef); @@ -369,6 +307,7 @@ DBG("CPU: CPUFreq: %dMHz\n", p->CPU.CPUFrequency / 1000000); DBG("CPU: NoCores/NoThreads: %d/%d\n", p->CPU.NoCores, p->CPU.NoThreads); DBG("CPU: Features: 0x%08x\n", p->CPU.Features); +#if DEBUG_CPU pause(); #endif } Index: branches/meklort/i386/libsaio/platform.h =================================================================== --- branches/meklort/i386/libsaio/platform.h (revision 504) +++ branches/meklort/i386/libsaio/platform.h (revision 505) @@ -23,6 +23,18 @@ #define CPUID_81 6 #define CPUID_MAX 7 +#define CPU_MODEL_YONAH 0x0E +#define CPU_MODEL_MEROM 0x0F +#define CPU_MODEL_PENRYN 0x17 +#define CPU_MODEL_NEHALEM 0x1A +#define CPU_MODEL_ATOM 0x1C +#define CPU_MODEL_FIELDS 0x1E /* Lynnfield, Clarksfield, Jasper */ +#define CPU_MODEL_DALES 0x1F /* Havendale, Auburndale */ +#define CPU_MODEL_DALES_32NM 0x25 /* Clarkdale, Arrandale */ +#define CPU_MODEL_WESTMERE 0x2C /* Gulftown, Westmere-EP, Westmere-WS */ +#define CPU_MODEL_NEHALEM_EX 0x2E +#define CPU_MODEL_WESTMERE_EX 0x2F + /* CPU Features */ #define CPU_FEATURE_MMX 0x00000001 // MMX Instruction Set #define CPU_FEATURE_SSE 0x00000002 // SSE Instruction Set @@ -33,11 +45,12 @@ #define CPU_FEATURE_EM64T 0x00000040 // 64Bit Support #define CPU_FEATURE_HTT 0x00000080 // HyperThreading #define CPU_FEATURE_MOBILE 0x00000100 // Mobile CPU +#define CPU_FEATURE_MSR 0x00000200 // MSR Support /* SMBIOS Memory Types */ -#define SMB_MEM_TYPE_UNDEFINED 0 +#define SMB_MEM_TYPE_UNDEFINED 0 #define SMB_MEM_TYPE_OTHER 1 -#define SMB_MEM_TYPE_UNKNOWN 2 +#define SMB_MEM_TYPE_UNKNOWN 2 #define SMB_MEM_TYPE_DRAM 3 #define SMB_MEM_TYPE_EDRAM 4 #define SMB_MEM_TYPE_VRAM 5 @@ -75,16 +88,16 @@ #define UUID_LEN 16 typedef struct _RamSlotInfo_t { - uint32_t ModuleSize; // Size of Module in MB - uint32_t Frequency; // in Mhz + uint32_t ModuleSize; // Size of Module in MB + uint32_t Frequency; // in Mhz const char* Vendor; const char* PartNo; const char* SerialNo; - char* spd; // SPD Dump - bool InUse; - uint8_t Type; - uint8_t BankConnections; // table type 6, see (3.3.7) - uint8_t BankConnCnt; + char* spd; // SPD Dump + bool InUse; + uint8_t Type; + uint8_t BankConnections; // table type 6, see (3.3.7) + uint8_t BankConnCnt; } RamSlotInfo_t; @@ -92,6 +105,8 @@ struct CPU { uint32_t Features; // CPU Features like MMX, SSE2, VT, MobileCPU uint32_t Vendor; // Vendor + uint32_t Signature; // Signature + uint32_t Stepping; // Stepping uint32_t Model; // Model uint32_t ExtModel; // Extended Model uint32_t Family; // Family @@ -105,12 +120,21 @@ uint64_t TSCFrequency; // TSC Frequency Hz uint64_t FSBFrequency; // FSB Frequency Hz uint64_t CPUFrequency; // CPU Frequency Hz - uint32_t BrandString[16]; // 48 Byte Branding String + char BrandString[48]; // 48 Byte Branding String uint32_t CPUID[CPUID_MAX][4]; // CPUID 0..4, 80..81 Raw Values } CPU; struct RAM { - RamSlotInfo_t DIMM[MAX_RAM_SLOTS]; // Information about each slot + uint64_t Frequency; // Ram Frequency + uint32_t Divider; // Memory divider + uint8_t CAS; // CAS 1/2/2.5/3/4/5/6/7 + uint8_t TRC; + uint8_t TRP; + uint8_t RAS; + uint8_t Channels; // Channel Configuration Single,Dual or Triple + uint8_t NoSlots; // Maximum no of slots available + uint8_t Type; // Standard SMBIOS v2.5 Memory Type + RamSlotInfo_t DIMM[MAX_RAM_SLOTS]; // Information about each slot } RAM; struct DMI { Index: branches/meklort/i386/libsaio/disk.c =================================================================== --- branches/meklort/i386/libsaio/disk.c (revision 504) +++ branches/meklort/i386/libsaio/disk.c (revision 505) @@ -67,6 +67,9 @@ #include "msdos.h" #include "ext2fs.h" +#include "xml.h" +#include "disk.h" + #include #include #include @@ -77,7 +80,6 @@ #include "efi.h" #include "efi_tables.h" -#define BPS 512 /* sector size of the device */ #define PROBEFS_SIZE BPS * 4 /* buffer size for filesystem probe */ #define CD_BPS 2048 /* CD-ROM block size */ #define N_CACHE_SECS (BIOS_LEN / BPS) /* Must be a multiple of 4 for CD-ROMs */ @@ -871,7 +873,8 @@ biosdev, partno, part->relsect, part, - 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + NTFSGetUUID, NTFSGetDescription, (BVFree)free, 0, kBIOSDevTypeHardDrive, 0); @@ -1445,12 +1448,11 @@ void rescanBIOSDevice(int biosdev) { - struct DiskBVMap *oldMap = diskResetBootVolumes(biosdev); - CacheReset(); - diskFreeMap(oldMap); - oldMap = NULL; - - scanBootVolumes(biosdev, 0); + struct DiskBVMap *oldMap = diskResetBootVolumes(biosdev); + CacheReset(); + diskFreeMap(oldMap); + oldMap = NULL; + scanBootVolumes(biosdev, 0); } struct DiskBVMap* diskResetBootVolumes(int biosdev) @@ -1554,9 +1556,15 @@ struct DiskBVMap * map = NULL; int bvCount = 0; - const char *val; - char devsw[12]; + const char *raw = 0; + char* val = 0; int len; + + getValueForKey(kHidePartition, &raw, &len, &bootInfo->bootConfig); + if(raw) + { + val = XMLDecode(raw); + } /* * Traverse gDISKBVmap to get references for @@ -1589,18 +1597,21 @@ ) newBVR->visible = true; - /* - * Looking for "Hide Partition" entries in "hd(x,y) hd(n,m)" format + /* Looking for "Hide Partition" entries in 'hd(x,y)|uuid|"label" hd(m,n)|uuid|"label"' format * to be able to hide foreign partitions from the boot menu. */ - if ( (newBVR->flags & kBVFlagForeignBoot) - && getValueForKey(kHidePartition, &val, &len, &bootInfo->bootConfig) - ) - { - sprintf(devsw, "hd(%d,%d)", BIOS_DEV_UNIT(newBVR), newBVR->part_no); - if (strstr(val, devsw) != NULL) - newBVR->visible = false; - } + if ( (newBVR->flags & kBVFlagForeignBoot) ) + { + char *start, *next = val; + long len = 0; + do + { + start = strbreak(next, &next, &len); + if(len && matchVolumeToString(newBVR, start, len) ) + newBVR->visible = false; + } + while ( next && *next ); + } /* * Use the first bvr entry as the starting chain pointer. @@ -1629,6 +1640,8 @@ #endif *count = bvCount; + + free(val); return chain; } @@ -1679,72 +1692,140 @@ //========================================================================== -/* If Rename Partition has defined an alias, then extract it for description purpose */ -static const char * getVolumeLabelAlias( BVRef bvr, const char * str, long strMaxLen) +bool matchVolumeToString( BVRef bvr, const char* match, long matchLen) { - const int MAX_ALIAS_SIZE=31; - static char szAlias[MAX_ALIAS_SIZE+1]; - char *q=szAlias; - const char * szAliases = getStringForKey(kRenamePartition, &bootInfo->bootConfig); + char testStr[128]; - if (!str || !*str || !szAliases) return 0; // no renaming wanted + if ( !bvr || !match || !*match) + return 0; + + if ( bvr->biosdev < 0x80 || bvr->biosdev >= 0x100 ) + return 0; + + // Try to match hd(x,y) first. + sprintf(testStr, "hd(%d,%d)", BIOS_DEV_UNIT(bvr), bvr->part_no); + if ( matchLen ? !strncmp(match, testStr, matchLen) : !strcmp(match, testStr) ) + return true; + + // Try to match volume UUID. + if ( bvr->fs_getuuid && bvr->fs_getuuid(bvr, testStr) == 0) + { + if( matchLen ? !strncmp(match, testStr, matchLen) : !strcmp(match, testStr) ) + return true; + } + + // Try to match volume label (always quoted). + if ( bvr->description ) + { + bvr->description(bvr, testStr, sizeof(testStr)-1); + if( matchLen ? !strncmp(match, testStr, matchLen) : !strcmp(match, testStr) ) + return true; + } + + return false; +} - const char * p = strstr(szAliases, str); - if(!p || !(*p)) return 0; // this volume must not be renamed, or option is malformed +/* If Rename Partition has defined an alias, then extract it for description purpose + * The format for the rename string is the following: + * hd(x,y)|uuid|"label" "alias";hd(m,n)|uuid|"label" etc; ... + */ - p+= strlen(str); // skip the "hd(n,m) " field - // multiple aliases can be found separated by a semi-column - while(*p && *p != ';' && q<(szAlias+MAX_ALIAS_SIZE)) *q++=*p++; - *q='\0'; - - return szAlias; +bool getVolumeLabelAlias(BVRef bvr, char* str, long strMaxLen) +{ + char *aliasList, *entryStart, *entryNext; + + if ( !str || strMaxLen <= 0) + return false; + + aliasList = XMLDecode(getStringForKey(kRenamePartition, &bootInfo->bootConfig)); + if ( !aliasList ) + return false; + + for ( entryStart = entryNext = aliasList; + entryNext && *entryNext; + entryStart = entryNext ) + { + char *volStart, *volEnd, *aliasStart; + long volLen, aliasLen; + + // Delimit current entry + entryNext = strchr(entryStart, ';'); + if ( entryNext ) + { + *entryNext = '\0'; + entryNext++; + } + + volStart = strbreak(entryStart, &volEnd, &volLen); + if(!volLen) + continue; + + aliasStart = strbreak(volEnd, 0, &aliasLen); + if(!aliasLen) + continue; + + if ( matchVolumeToString(bvr, volStart, volLen) ) + { + strncat(str, aliasStart, min(strMaxLen, aliasLen)); + free(aliasList); + + return true; + } + } + + free(aliasList); + return false; } -void getBootVolumeDescription( BVRef bvr, char * str, long strMaxLen, bool verbose ) +void getBootVolumeDescription( BVRef bvr, char * str, long strMaxLen, bool useDeviceDescription ) { - unsigned char type = (unsigned char) bvr->part_type; - char *p; + unsigned char type; + char *p = str; + + if(!bvr || !p || strMaxLen <= 0) + return; + + type = (unsigned char) bvr->part_type; + + if (useDeviceDescription) + { + int len = getDeviceDescription(bvr, str); + if(len >= strMaxLen) + return; + + strcpy(str + len, " "); + len++; + strMaxLen -= len; + p += len; + } - p = str; - if (verbose) { - sprintf( str, "hd(%d,%d) ", BIOS_DEV_UNIT(bvr), bvr->part_no); - for (; strMaxLen > 0 && *p != '\0'; p++, strMaxLen--); + /* See if a partition rename is preferred */ + if(getVolumeLabelAlias(bvr, p, strMaxLen)) { + strncpy(bvr->label, p, strMaxLen); + return; // we're done here no need to seek for real name } - - // See if we should get the renamed alias name for this partion: - const char * szAliasName = getVolumeLabelAlias(bvr, str, strMaxLen); - if (szAliasName && *szAliasName) - { - strncpy(bvr->label, szAliasName, strMaxLen); - return; // we're done here no need to seek for real name - } // // Get the volume label using filesystem specific functions // or use the alternate volume label if available. // - if (*bvr->altlabel == '\0') - { - if (bvr->description) + if (*bvr->altlabel != '\0') + strncpy(p, bvr->altlabel, strMaxLen); + else if (bvr->description) bvr->description(bvr, p, strMaxLen); - } - else - strncpy(p, bvr->altlabel, strMaxLen); if (*p == '\0') { - const char * name = getNameForValue( fdiskTypes, type ); - if (name == NULL) { - name = bvr->type_name; - } - if (name == NULL) { - sprintf(p, "TYPE %02x", type); - } else { - strncpy(p, name, strMaxLen); - } + const char * name = getNameForValue( fdiskTypes, type ); + if (name == NULL) { + name = bvr->type_name; + } + if (name == NULL) { + sprintf(p, "TYPE %02x", type); + } else { + strncpy(p, name, strMaxLen); + } } - - /* See if a partion rename is wanted: */ - + // Set the devices label sprintf(bvr->label, p); } Index: branches/meklort/i386/libsaio/pci_setup.c =================================================================== --- branches/meklort/i386/libsaio/pci_setup.c (revision 504) +++ branches/meklort/i386/libsaio/pci_setup.c (revision 505) @@ -6,11 +6,11 @@ #include "ati.h" extern void set_eth_builtin(pci_dt_t *eth_dev); -//extern int ehci_acquire(pci_dt_t *pci_dev); -//extern int uhci_reset(pci_dt_t *pci_dev); extern void notify_usb_dev(pci_dt_t *pci_dev); extern void force_enable_hpet(pci_dt_t *lpc_dev); +extern pci_dt_t *dram_controller_dev; + void setup_pci_devs(pci_dt_t *pci_dt) { char *devicepath; @@ -29,6 +29,10 @@ switch (current->class_id) { + case PCI_CLASS_BRIDGE_HOST: + dram_controller_dev = current; + break; + case PCI_CLASS_NETWORK_ETHERNET: if (do_eth_devprop) set_eth_builtin(current); @@ -58,22 +62,6 @@ case PCI_CLASS_SERIAL_USB: notify_usb_dev(current); - /* - switch (pci_config_read8(current->dev.addr, PCI_CLASS_PROG)) - { - // EHCI - case 0x20: - if (fix_ehci) - ehci_acquire(current); - break; - - // UHCI - case 0x00: - if (fix_uhci) - uhci_reset(current); - break; - } - */ break; case PCI_CLASS_BRIDGE_ISA: Index: branches/meklort/i386/libsaio/cpu.h =================================================================== --- branches/meklort/i386/libsaio/cpu.h (revision 504) +++ branches/meklort/i386/libsaio/cpu.h (revision 505) @@ -14,12 +14,16 @@ #define bitmask(h,l) ((bit(h)|(bit(h)-1)) & ~(bit(l)-1)) #define bitfield(x,h,l) (((x) & bitmask(h,l)) >> l) -#define IA32_PERF_STATUS 0x198 -#define MSR_FLEX_RATIO 0x194 -#define MSR_PLATFORM_INFO 0xCE -#define K8_FIDVID_STATUS 0xC0010042 -#define K10_COFVID_STATUS 0xC0010071 +#define CPU_STRING_UNKNOWN "Unknown CPU Typ" +#define MSR_IA32_PERF_STATUS 0x198 +#define MSR_IA32_PERF_CONTROL 0x199 +#define MSR_IA32_EXT_CONFIG 0x00EE +#define MSR_FLEX_RATIO 0x194 +#define MSR_PLATFORM_INFO 0xCE +#define K8_FIDVID_STATUS 0xC0010042 +#define K10_COFVID_STATUS 0xC0010071 + #define DEFAULT_FSB 100000 /* for now, hardcoding 100MHz for old CPUs */ // DFE: This constant comes from older xnu: @@ -29,4 +33,111 @@ #define CALIBRATE_TIME_MSEC 30 /* 30 msecs */ #define CALIBRATE_LATCH ((CLKNUM * CALIBRATE_TIME_MSEC + 1000/2)/1000) +static inline uint64_t rdtsc64(void) +{ + uint64_t ret; + __asm__ volatile("rdtsc" : "=A" (ret)); + return ret; +} + +static inline uint64_t rdmsr64(uint32_t msr) +{ + uint64_t ret; + __asm__ volatile("rdmsr" : "=A" (ret) : "c" (msr)); + return ret; +} + +static inline void wrmsr64(uint32_t msr, uint64_t val) +{ + __asm__ volatile("wrmsr" : : "c" (msr), "A" (val)); +} + +static inline void intel_waitforsts(void) { + uint32_t inline_timeout = 100000; + while (rdmsr64(MSR_IA32_PERF_STATUS) & (1 << 21)) { if (!inline_timeout--) break; } +} + +static inline void do_cpuid(uint32_t selector, uint32_t *data) +{ + asm volatile ("cpuid" + : "=a" (data[0]), + "=b" (data[1]), + "=c" (data[2]), + "=d" (data[3]) + : "a" (selector)); +} + +static inline void do_cpuid2(uint32_t selector, uint32_t selector2, uint32_t *data) +{ + asm volatile ("cpuid" + : "=a" (data[0]), + "=b" (data[1]), + "=c" (data[2]), + "=d" (data[3]) + : "a" (selector), "c" (selector2)); +} + +// DFE: enable_PIT2 and disable_PIT2 come from older xnu + +/* + * Enable or disable timer 2. + * Port 0x61 controls timer 2: + * bit 0 gates the clock, + * bit 1 gates output to speaker. + */ +static inline void enable_PIT2(void) +{ + /* Enable gate, disable speaker */ + __asm__ volatile( + " inb $0x61,%%al \n\t" + " and $0xFC,%%al \n\t" /* & ~0x03 */ + " or $1,%%al \n\t" + " outb %%al,$0x61 \n\t" + : : : "%al" ); +} + +static inline void disable_PIT2(void) +{ + /* Disable gate and output to speaker */ + __asm__ volatile( + " inb $0x61,%%al \n\t" + " and $0xFC,%%al \n\t" /* & ~0x03 */ + " outb %%al,$0x61 \n\t" + : : : "%al" ); +} + +// DFE: set_PIT2_mode0, poll_PIT2_gate, and measure_tsc_frequency are +// roughly based on Linux code + +/* Set the 8254 channel 2 to mode 0 with the specified value. + In mode 0, the counter will initially set its gate low when the + timer expires. For this to be useful, you ought to set it high + before calling this function. The enable_PIT2 function does this. + */ +static inline void set_PIT2_mode0(uint16_t value) +{ + __asm__ volatile( + " movb $0xB0,%%al \n\t" + " outb %%al,$0x43 \n\t" + " movb %%dl,%%al \n\t" + " outb %%al,$0x42 \n\t" + " movb %%dh,%%al \n\t" + " outb %%al,$0x42" + : : "d"(value) /*: no clobber */ ); +} + +/* Returns the number of times the loop ran before the PIT2 signaled */ +static inline unsigned long poll_PIT2_gate(void) +{ + unsigned long count = 0; + unsigned char nmi_sc_val; + do { + ++count; + __asm__ volatile( + "inb $0x61,%0" + : "=q"(nmi_sc_val) /*:*/ /* no input */ /*:*/ /* no clobber */); + } while( (nmi_sc_val & 0x20) == 0); + return count; +} + #endif /* !__LIBSAIO_CPU_H */ Index: branches/meklort/i386/libsaio/disk.h =================================================================== --- branches/meklort/i386/libsaio/disk.h (revision 0) +++ branches/meklort/i386/libsaio/disk.h (revision 505) @@ -0,0 +1,14 @@ +/* + * disk.h + * Chameleon + * + * Created by Daniel Miranda on 27/07/10. + * Copyright 2010 __MyCompanyName__. All rights reserved. + * + */ +#ifndef __LIBSAIO_DISK_H +#define __LIBSAIO_DISK_H + +bool matchVolumeToString( BVRef bvr, const char* match, long strMaxLen); + +#endif /* __LIBSAIO_DISK_H */ \ No newline at end of file Property changes on: branches/meklort/i386/libsaio/disk.h ___________________________________________________________________ Added: svn:executable + * Index: branches/meklort/i386/libsaio/cache.c =================================================================== --- branches/meklort/i386/libsaio/cache.c (revision 504) +++ branches/meklort/i386/libsaio/cache.c (revision 505) @@ -39,7 +39,7 @@ #define kCacheSize (0x100000) #define kCacheMinBlockSize (0x200) -#define kCacheMaxBlockSize (0x4000) +#define kCacheMaxBlockSize (0x8000) #define kCacheMaxEntries (kCacheSize / kCacheMinBlockSize) static CICell gCacheIH; @@ -74,7 +74,7 @@ #endif if ((blockSize < kCacheMinBlockSize) || - (blockSize >= kCacheMaxBlockSize)) + (blockSize > kCacheMaxBlockSize)) return; gCacheBlockSize = blockSize; Index: branches/meklort/i386/libsaio/saio_types.h =================================================================== --- branches/meklort/i386/libsaio/saio_types.h (revision 504) +++ branches/meklort/i386/libsaio/saio_types.h (revision 505) @@ -132,10 +132,10 @@ typedef long (*FSLoadFile)(CICell ih, char * filePath); typedef long (*FSReadFile)(CICell ih, char *filePath, void *base, uint64_t offset, uint64_t length); typedef long (*FSGetFileBlock)(CICell ih, char *filePath, unsigned long long *firstBlock); -typedef long (*FSGetDirEntry)(CICell ih, char * dirPath, long * dirIndex, +typedef long (*FSGetDirEntry)(CICell ih, char * dirPath, long long * dirIndex, char ** name, long * flags, long * time, FinderInfo * finderInfo, long * infoValid); -typedef long (* FSGetUUID)(CICell ih, char *uuidStr); +typedef long (*FSGetUUID)(CICell ih, char *uuidStr); typedef void (*BVGetDescription)(CICell ih, char * str, long strMaxLen); // Can be just pointed to free or a special free function typedef void (*BVFree)(CICell ih); @@ -147,6 +147,7 @@ char * i_buf; /* file load address */ }; +#define BPS 512 /* sector size of the device */ #define F_READ 0x1 /* file opened for reading */ #define F_WRITE 0x2 /* file opened for writing */ #define F_ALLOC 0x4 /* buffer allocated */ @@ -157,7 +158,7 @@ struct dirstuff { char * dir_path; /* directory path */ - long dir_index; /* directory entry index */ + long long dir_index; /* directory entry index */ BVRef dir_bvr; /* volume reference */ }; Index: branches/meklort/i386/libsaio/msdos.c =================================================================== --- branches/meklort/i386/libsaio/msdos.c (revision 504) +++ branches/meklort/i386/libsaio/msdos.c (revision 505) @@ -54,7 +54,7 @@ #include "msdos.h" #define LABEL_LENGTH 11 -#define MAX_DOS_BLOCKSIZE 2048 +#define MSDOS_CACHE_BLOCKSIZE BPS #define CLUST_FIRST 2/* reserved cluster range */ #define CLUST_RSRVD32 0x0ffffff8 /* reserved cluster range */ @@ -151,7 +151,7 @@ if (msdoscurrent == ih) { - CacheInit(ih, msdosclustersize); + CacheInit(ih, MSDOS_CACHE_BLOCKSIZE); return 0; } @@ -220,14 +220,38 @@ } msdosclustersize = msdosbps * spc; + msdoscurrent = ih; - msdoscurrent = ih; - CacheInit(ih, msdosclustersize); + CacheInit(ih, MSDOS_CACHE_BLOCKSIZE); free (buf); return 0; } static int +readSector(CICell ih, off_t readOffset, char *buf, int size) +{ + // Caching only FAT entries (4 bytes) by utlizing the cache with sector aligned read requests. + if (size < BPS) + { + long long sectorOffset = (uint64_t)readOffset / BPS * BPS; + long relOffset = readOffset % BPS; + char *cacheBuffer; + + cacheBuffer = malloc(MSDOS_CACHE_BLOCKSIZE); + CacheRead(ih, cacheBuffer, sectorOffset, MSDOS_CACHE_BLOCKSIZE, true); + bcopy(cacheBuffer + relOffset, buf, size); + free(cacheBuffer); + } + else + { + Seek(ih, readOffset); + Read(ih, (long)buf, size); + } + + return 0; +} + +static int msdosreadcluster (CICell ih, uint8_t *buf, int size, off_t *cluster) { off_t readOffset; @@ -266,15 +290,15 @@ Seek(ih, readOffset); Read(ih, (long)buf, size); } - + /* Find first sector of FAT */ - readOffset = msdosressector*msdosbps; + readOffset = msdosressector * msdosbps; + /* Find sector containing "cluster" entry in FAT */ - readOffset += ((uint64_t)*cluster * (uint64_t)msdosfatbits)/8; + readOffset += ((uint64_t)*cluster * (uint64_t)msdosfatbits) / 8; /* Read one sector of the FAT */ - Seek(ih, readOffset); - Read(ih, (long)tmpbuf, 4); + readSector(ih, readOffset, tmpbuf, 4); switch (msdosfatbits) { case 32: @@ -615,7 +639,7 @@ return 0; } -long MSDOSGetDirEntry(CICell ih, char * dirPath, long * dirIndex, +long MSDOSGetDirEntry(CICell ih, char * dirPath, long long * dirIndex, char ** name, long * flags, long * time, FinderInfo * finderInfo, long * infoValid) { @@ -626,7 +650,7 @@ return -1; if (dirPath[0] == '/') dirPath++; - st = (struct msdosdirstate *)*dirIndex; + st = (struct msdosdirstate *)(long) *dirIndex; if (!st) { st=malloc (sizeof (*st)); @@ -651,7 +675,7 @@ } else initRoot (st); - *dirIndex = (long)st; + *dirIndex = (long long) (long) st; } while((dirp = getnextdirent (ih, vfatname, st))&& (dirp->deAttributes & ATTR_VOLUME)); if (!dirp) @@ -720,6 +744,8 @@ char *ptr = (char *)base; struct direntry *dirp; int i; + char devStr[12]; + if (MSDOSInitPartition (ih)<0) return -1; if (filePath[0] == '/') @@ -754,8 +780,10 @@ ptr+=msdosclustersize; toread-=msdosclustersize; } - verbose("Loaded FAT%d file: [%s] %d bytes from %x.\n", - msdosfatbits, filePath, (uint32_t)( toread<0 ) ? wastoread : wastoread-toread, ih); + + getDeviceDescription(ih, devStr); + verbose("Read FAT%d file: [%s/%s] %d bytes.\n", + msdosfatbits, devStr, filePath, (uint32_t)( toread<0 ) ? wastoread : wastoread-toread); free (buf); if (toread<0) return wastoread; Index: branches/meklort/i386/libsaio/fake_efi.c =================================================================== --- branches/meklort/i386/libsaio/fake_efi.c (revision 504) +++ branches/meklort/i386/libsaio/fake_efi.c (revision 505) @@ -1,6 +1,6 @@ /* - * Copyright 2007 David F. Elliott. All rights reserved. + * Copyright 2007 David F. Elliott. All rights reserved. */ #include "libsaio.h" @@ -11,7 +11,7 @@ #include "fake_efi.h" #include "efi_tables.h" #include "platform.h" -#include "dsdt_patcher.h" +#include "acpi_patcher.h" #include "smbios_patcher.h" #include "device_inject.h" #include "convert.h" @@ -22,57 +22,55 @@ extern void setup_pci_devs(pci_dt_t *pci_dt); /* -Modern Darwin kernels require some amount of EFI because Apple machines all -have EFI. Modifying the kernel source to not require EFI is of course -possible but would have to be maintained as a separate patch because it is -unlikely that Apple wishes to add legacy support to their kernel. + * Modern Darwin kernels require some amount of EFI because Apple machines all + * have EFI. Modifying the kernel source to not require EFI is of course + * possible but would have to be maintained as a separate patch because it is + * unlikely that Apple wishes to add legacy support to their kernel. + * + * As you can see from the Apple-supplied code in bootstruct.c, it seems that + * the intention was clearly to modify this booter to provide EFI-like structures + * to the kernel rather than modifying the kernel to handle non-EFI stuff. This + * makes a lot of sense from an engineering point of view as it means the kernel + * for the as yet unreleased EFI-only Macs could still be booted by the non-EFI + * DTK systems so long as the kernel checked to ensure the boot tables were + * filled in appropriately. Modern xnu requires a system table and a runtime + * services table and performs no checks whatsoever to ensure the pointers to + * these tables are non-NULL. Therefore, any modern xnu kernel will page fault + * early on in the boot process if the system table pointer is zero. + * + * Even before that happens, the tsc_init function in modern xnu requires the FSB + * Frequency to be a property in the /efi/platform node of the device tree or else + * it panics the bootstrap process very early on. + * + * As of this writing, the current implementation found here is good enough + * to make the currently available xnu kernel boot without modification on a + * system with an appropriate processor. With a minor source modification to + * the tsc_init function to remove the explicit check for Core or Core 2 + * processors the kernel can be made to boot on other processors so long as + * the code can be executed by the processor and the machine contains the + * necessary hardware. + */ -As you can see from the Apple-supplied code in bootstruct.c, it seems that -the intention was clearly to modify this booter to provide EFI-like structures -to the kernel rather than modifying the kernel to handle non-EFI stuff. This -makes a lot of sense from an engineering point of view as it means the kernel -for the as yet unreleased EFI-only Macs could still be booted by the non-EFI -DTK systems so long as the kernel checked to ensure the boot tables were -filled in appropriately. Modern xnu requires a system table and a runtime -services table and performs no checks whatsoever to ensure the pointers to -these tables are non-NULL. Therefore, any modern xnu kernel will page fault -early on in the boot process if the system table pointer is zero. - -Even before that happens, the tsc_init function in modern xnu requires the FSB -Frequency to be a property in the /efi/platform node of the device tree or else -it panics the bootstrap process very early on. - -As of this writing, the current implementation found here is good enough -to make the currently available xnu kernel boot without modification on a -system with an appropriate processor. With a minor source modification to -the tsc_init function to remove the explicit check for Core or Core 2 -processors the kernel can be made to boot on other processors so long as -the code can be executed by the processor and the machine contains the -necessary hardware. -*/ - - /*========================================================================== * Utility function to make a device tree string from an EFI_GUID */ static inline char * mallocStringForGuid(EFI_GUID const *pGuid) { - char *string = malloc(37); - efi_guid_unparse_upper(pGuid, string); - return string; + char *string = malloc(37); + efi_guid_unparse_upper(pGuid, string); + return string; } - /*========================================================================== * Function to map 32 bit physical address to 64 bit virtual address */ + static uint64_t ptov64(uint32_t addr) { - return ((uint64_t)addr | 0xFFFFFF8000000000ULL); + return ((uint64_t)addr | 0xFFFFFF8000000000ULL); } - /*========================================================================== * Fake EFI implementation */ @@ -82,194 +80,312 @@ static EFI_UINT32 const FIRMWARE_REVISION = 132; /* FIXME: Find a constant for this. */ /* Default platform system_id (fix by IntVar) */ -static EFI_CHAR8 const SYSTEM_ID[] = "0123456789ABCDEF";//random value gen by uuidgen +static EFI_CHAR8 const SYSTEM_ID[] = "0123456789ABCDEF"; //random value gen by uuidgen /* Just a ret instruction */ static uint8_t const VOIDRET_INSTRUCTIONS[] = {0xc3}; + /* movl $0x80000003,%eax; ret */ static uint8_t const UNSUPPORTEDRET_INSTRUCTIONS[] = {0xb8, 0x03, 0x00, 0x00, 0x80, 0xc3}; - -/* We use the fake_efi_pages struct so that we only need to do one kernel - * memory allocation for all needed EFI data. Otherwise, small allocations - * like the FIRMWARE_VENDOR string would take up an entire page. - * NOTE WELL: Do NOT assume this struct has any particular layout within itself. - * It is absolutely not intended to be publicly exposed anywhere - * We say pages (plural) although right now we are well within the 1 page size - * and probably will stay that way. - */ -struct fake_efi_pages -{ - EFI_SYSTEM_TABLE_64 efiSystemTable; - EFI_RUNTIME_SERVICES_64 efiRuntimeServices; - EFI_CONFIGURATION_TABLE_64 efiConfigurationTable[MAX_CONFIGURATION_TABLE_ENTRIES]; - EFI_CHAR16 firmwareVendor[sizeof(FIRMWARE_VENDOR)/sizeof(EFI_CHAR16)]; - uint8_t voidret_instructions[sizeof(VOIDRET_INSTRUCTIONS)/sizeof(uint8_t)]; - uint8_t unsupportedret_instructions[sizeof(UNSUPPORTEDRET_INSTRUCTIONS)/sizeof(uint8_t)]; -}; - -EFI_SYSTEM_TABLE_64 *gST = NULL; +EFI_SYSTEM_TABLE_32 *gST32 = NULL; +EFI_SYSTEM_TABLE_64 *gST64 = NULL; Node *gEfiConfigurationTableNode = NULL; extern EFI_STATUS addConfigurationTable(EFI_GUID const *pGuid, void *table, char const *alias) { - EFI_UINTN i = gST->NumberOfTableEntries; - /* We only do adds, not modifications and deletes like InstallConfigurationTable */ - if(i >= MAX_CONFIGURATION_TABLE_ENTRIES) - stop("Ran out of space for configuration tables. Increase the reserved size in the code.\n"); - - if(pGuid == NULL) - return EFI_INVALID_PARAMETER; - - if(table != NULL) - { - /* FIXME - ((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorGuid = *pGuid; - ((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorTable = (EFI_PTR64)table; - - ++gST->NumberOfTableEntries; - */ - Node *tableNode = DT__AddChild(gEfiConfigurationTableNode, mallocStringForGuid(pGuid)); - - /* Use the pointer to the GUID we just stuffed into the system table */ - DT__AddProperty(tableNode, "guid", sizeof(EFI_GUID), (void*)pGuid); - - /* The "table" property is the 32-bit (in our implementation) physical address of the table */ - DT__AddProperty(tableNode, "table", sizeof(void*) * 2, table); - - /* Assume the alias pointer is a global or static piece of data */ - if(alias != NULL) - DT__AddProperty(tableNode, "alias", strlen(alias)+1, (char*)alias); - - return EFI_SUCCESS; - } - return EFI_UNSUPPORTED; + EFI_UINTN i = 0; + + //Azi: as is, cpu's with em64t will use EFI64 on pre 10.6 systems, + // wich seems to cause no problem. In case it does, force i386 arch. + if (archCpuType == CPU_TYPE_I386) + { + i = gST32->NumberOfTableEntries; + } + else + { + i = gST64->NumberOfTableEntries; + } + + // We only do adds, not modifications and deletes like InstallConfigurationTable + if (i >= MAX_CONFIGURATION_TABLE_ENTRIES) + stop("Ran out of space for configuration tables. Increase the reserved size in the code.\n"); + + if (pGuid == NULL) + return EFI_INVALID_PARAMETER; + + if (table != NULL) + { + // FIXME + //((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorGuid = *pGuid; + //((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorTable = (EFI_PTR64)table; + + //++gST->NumberOfTableEntries; + + Node *tableNode = DT__AddChild(gEfiConfigurationTableNode, mallocStringForGuid(pGuid)); + + // Use the pointer to the GUID we just stuffed into the system table + DT__AddProperty(tableNode, "guid", sizeof(EFI_GUID), (void*)pGuid); + + // The "table" property is the 32-bit (in our implementation) physical address of the table + DT__AddProperty(tableNode, "table", sizeof(void*) * 2, table); + + // Assume the alias pointer is a global or static piece of data + if (alias != NULL) + DT__AddProperty(tableNode, "alias", strlen(alias)+1, (char*)alias); + + return EFI_SUCCESS; + } + return EFI_UNSUPPORTED; } -static inline void fixupEfiSystemTableCRC32(EFI_SYSTEM_TABLE_64 *efiSystemTable) +//Azi: crc32 done in place, on the cases were it wasn't. +/*static inline void fixupEfiSystemTableCRC32(EFI_SYSTEM_TABLE_64 *efiSystemTable) { - efiSystemTable->Hdr.CRC32 = 0; - efiSystemTable->Hdr.CRC32 = crc32(0L, efiSystemTable, efiSystemTable->Hdr.HeaderSize); -} + efiSystemTable->Hdr.CRC32 = 0; + efiSystemTable->Hdr.CRC32 = crc32(0L, efiSystemTable, efiSystemTable->Hdr.HeaderSize); +}*/ /* -What we do here is simply allocate a fake EFI system table and a fake EFI -runtime services table. + * What we do here is simply allocate a fake EFI system table and a fake EFI + * runtime services table. + * + * Because we build against modern headers with kBootArgsRevision 4 we + * also take care to set efiMode = 32. + */ -Because we build against modern headers with kBootArgsRevision 4 we -also take care to set efiMode = 32. -*/ -void -setupEfiTables(void) +void setupEfiTables32(void) { - struct fake_efi_pages *fakeEfiPages= (struct fake_efi_pages*)AllocateKernelMemory(sizeof(struct fake_efi_pages)); + // We use the fake_efi_pages struct so that we only need to do one kernel + // memory allocation for all needed EFI data. Otherwise, small allocations + // like the FIRMWARE_VENDOR string would take up an entire page. + // NOTE WELL: Do NOT assume this struct has any particular layout within itself. + // It is absolutely not intended to be publicly exposed anywhere + // We say pages (plural) although right now we are well within the 1 page size + // and probably will stay that way. + struct fake_efi_pages + { + EFI_SYSTEM_TABLE_32 efiSystemTable; + EFI_RUNTIME_SERVICES_32 efiRuntimeServices; + EFI_CONFIGURATION_TABLE_32 efiConfigurationTable[MAX_CONFIGURATION_TABLE_ENTRIES]; + EFI_CHAR16 firmwareVendor[sizeof(FIRMWARE_VENDOR)/sizeof(EFI_CHAR16)]; + uint8_t voidret_instructions[sizeof(VOIDRET_INSTRUCTIONS)/sizeof(uint8_t)]; + uint8_t unsupportedret_instructions[sizeof(UNSUPPORTEDRET_INSTRUCTIONS)/sizeof(uint8_t)]; + }; + + struct fake_efi_pages *fakeEfiPages = (struct fake_efi_pages*)AllocateKernelMemory(sizeof(struct fake_efi_pages)); + + // Zero out all the tables in case fields are added later + bzero(fakeEfiPages, sizeof(struct fake_efi_pages)); + + // -------------------------------------------------------------------- + // Initialize some machine code that will return EFI_UNSUPPORTED for + // functions returning int and simply return for void functions. + memcpy(fakeEfiPages->voidret_instructions, VOIDRET_INSTRUCTIONS, sizeof(VOIDRET_INSTRUCTIONS)); + memcpy(fakeEfiPages->unsupportedret_instructions, UNSUPPORTEDRET_INSTRUCTIONS, sizeof(UNSUPPORTEDRET_INSTRUCTIONS)); + + // -------------------------------------------------------------------- + // System table + EFI_SYSTEM_TABLE_32 *efiSystemTable = gST32 = &fakeEfiPages->efiSystemTable; + efiSystemTable->Hdr.Signature = EFI_SYSTEM_TABLE_SIGNATURE; + efiSystemTable->Hdr.Revision = EFI_SYSTEM_TABLE_REVISION; + efiSystemTable->Hdr.HeaderSize = sizeof(EFI_SYSTEM_TABLE_32); + efiSystemTable->Hdr.CRC32 = 0; // Initialize to zero and then do CRC32 + efiSystemTable->Hdr.Reserved = 0; + + efiSystemTable->FirmwareVendor = (EFI_PTR32)&fakeEfiPages->firmwareVendor; + memcpy(fakeEfiPages->firmwareVendor, FIRMWARE_VENDOR, sizeof(FIRMWARE_VENDOR)); + efiSystemTable->FirmwareRevision = FIRMWARE_REVISION; + + // XXX: We may need to have basic implementations of ConIn/ConOut/StdErr + // The EFI spec states that all handles are invalid after boot services have been + // exited so we can probably get by with leaving the handles as zero. + efiSystemTable->ConsoleInHandle = 0; + efiSystemTable->ConIn = 0; + + efiSystemTable->ConsoleOutHandle = 0; + efiSystemTable->ConOut = 0; + + efiSystemTable->StandardErrorHandle = 0; + efiSystemTable->StdErr = 0; + + efiSystemTable->RuntimeServices = (EFI_PTR32)&fakeEfiPages->efiRuntimeServices; + + // According to the EFI spec, BootServices aren't valid after the + // boot process is exited so we can probably do without it. + // Apple didn't provide a definition for it in pexpert/i386/efi.h + // so I'm guessing they don't use it. + efiSystemTable->BootServices = 0; + + efiSystemTable->NumberOfTableEntries = 0; + efiSystemTable->ConfigurationTable = (EFI_PTR32)fakeEfiPages->efiConfigurationTable; + + // We're done. Now CRC32 the thing so the kernel will accept it. + // Must be initialized to zero before CRC32, done above. + gST32->Hdr.CRC32 = crc32(0L, gST32, gST32->Hdr.HeaderSize); + + // -------------------------------------------------------------------- + // Runtime services + EFI_RUNTIME_SERVICES_32 *efiRuntimeServices = &fakeEfiPages->efiRuntimeServices; + efiRuntimeServices->Hdr.Signature = EFI_RUNTIME_SERVICES_SIGNATURE; + efiRuntimeServices->Hdr.Revision = EFI_RUNTIME_SERVICES_REVISION; + efiRuntimeServices->Hdr.HeaderSize = sizeof(EFI_RUNTIME_SERVICES_32); + efiRuntimeServices->Hdr.CRC32 = 0; + efiRuntimeServices->Hdr.Reserved = 0; + + // There are a number of function pointers in the efiRuntimeServices table. + // These are the Foundation (e.g. core) services and are expected to be present on + // all EFI-compliant machines. Some kernel extensions (notably AppleEFIRuntime) + // will call these without checking to see if they are null. + // + // We don't really feel like doing an EFI implementation in the bootloader + // but it is nice if we can at least prevent a complete crash by + // at least providing some sort of implementation until one can be provided + // nicely in a kext. + void (*voidret_fp)() = (void*)fakeEfiPages->voidret_instructions; + void (*unsupportedret_fp)() = (void*)fakeEfiPages->unsupportedret_instructions; + efiRuntimeServices->GetTime = (EFI_PTR32)unsupportedret_fp; + efiRuntimeServices->SetTime = (EFI_PTR32)unsupportedret_fp; + efiRuntimeServices->GetWakeupTime = (EFI_PTR32)unsupportedret_fp; + efiRuntimeServices->SetWakeupTime = (EFI_PTR32)unsupportedret_fp; + efiRuntimeServices->SetVirtualAddressMap = (EFI_PTR32)unsupportedret_fp; + efiRuntimeServices->ConvertPointer = (EFI_PTR32)unsupportedret_fp; + efiRuntimeServices->GetVariable = (EFI_PTR32)unsupportedret_fp; + efiRuntimeServices->GetNextVariableName = (EFI_PTR32)unsupportedret_fp; + efiRuntimeServices->SetVariable = (EFI_PTR32)unsupportedret_fp; + efiRuntimeServices->GetNextHighMonotonicCount = (EFI_PTR32)unsupportedret_fp; + efiRuntimeServices->ResetSystem = (EFI_PTR32)voidret_fp; + + // We're done. Now CRC32 the thing so the kernel will accept it + efiRuntimeServices->Hdr.CRC32 = crc32(0L, efiRuntimeServices, efiRuntimeServices->Hdr.HeaderSize); + + // -------------------------------------------------------------------- + // Finish filling in the rest of the boot args that we need. + bootArgs->efiSystemTable = (uint32_t)efiSystemTable; + bootArgs->efiMode = kBootArgsEfiMode32; + + // The bootArgs structure as a whole is bzero'd so we don't need to fill in + // things like efiRuntimeServices* and what not. + // + // In fact, the only code that seems to use that is the hibernate code so it + // knows not to save the pages. It even checks to make sure its nonzero. +} - /* Zero out all the tables in case fields are added later */ - bzero(fakeEfiPages, sizeof(struct fake_efi_pages)); - - /* -------------------------------------------------------------------- - * Initialize some machine code that will return EFI_UNSUPPORTED for - * functions returning int and simply return for void functions. - */ - memcpy(fakeEfiPages->voidret_instructions, VOIDRET_INSTRUCTIONS, sizeof(VOIDRET_INSTRUCTIONS)); - memcpy(fakeEfiPages->unsupportedret_instructions, UNSUPPORTEDRET_INSTRUCTIONS, sizeof(UNSUPPORTEDRET_INSTRUCTIONS)); - - /* -------------------------------------------------------------------- */ - /* System table */ - EFI_SYSTEM_TABLE_64 *efiSystemTable = gST = &fakeEfiPages->efiSystemTable; - efiSystemTable->Hdr.Signature = EFI_SYSTEM_TABLE_SIGNATURE; - efiSystemTable->Hdr.Revision = EFI_SYSTEM_TABLE_REVISION; - efiSystemTable->Hdr.HeaderSize = sizeof(EFI_SYSTEM_TABLE_64); - efiSystemTable->Hdr.CRC32 = 0; /* Initialize to zero and then do CRC32 */ - efiSystemTable->Hdr.Reserved = 0; - - efiSystemTable->FirmwareVendor = (EFI_PTR32)&fakeEfiPages->firmwareVendor; - memcpy(fakeEfiPages->firmwareVendor, FIRMWARE_VENDOR, sizeof(FIRMWARE_VENDOR)); - efiSystemTable->FirmwareRevision = FIRMWARE_REVISION; - - /* XXX: We may need to have basic implementations of ConIn/ConOut/StdErr */ - /* The EFI spec states that all handles are invalid after boot services have been - * exited so we can probably get by with leaving the handles as zero. */ - efiSystemTable->ConsoleInHandle = 0; - efiSystemTable->ConIn = 0; - - efiSystemTable->ConsoleOutHandle = 0; - efiSystemTable->ConOut = 0; - - efiSystemTable->StandardErrorHandle = 0; - efiSystemTable->StdErr = 0; - - efiSystemTable->RuntimeServices = ptov64((EFI_PTR32)&fakeEfiPages->efiRuntimeServices); - /* According to the EFI spec, BootServices aren't valid after the - * boot process is exited so we can probably do without it. - * Apple didn't provide a definition for it in pexpert/i386/efi.h - * so I'm guessing they don't use it. - */ - efiSystemTable->BootServices = 0; - - efiSystemTable->NumberOfTableEntries = 0; - efiSystemTable->ConfigurationTable = (EFI_PTR32)fakeEfiPages->efiConfigurationTable; - - - /* We're done. Now CRC32 the thing so the kernel will accept it */ - fixupEfiSystemTableCRC32(efiSystemTable); - - /* -------------------------------------------------------------------- */ - /* Runtime services */ - EFI_RUNTIME_SERVICES_64 *efiRuntimeServices = &fakeEfiPages->efiRuntimeServices; - efiRuntimeServices->Hdr.Signature = EFI_RUNTIME_SERVICES_SIGNATURE; - efiRuntimeServices->Hdr.Revision = EFI_RUNTIME_SERVICES_REVISION; - efiRuntimeServices->Hdr.HeaderSize = sizeof(EFI_RUNTIME_SERVICES_64); - efiRuntimeServices->Hdr.CRC32 = 0; - efiRuntimeServices->Hdr.Reserved = 0; - - /* There are a number of function pointers in the efiRuntimeServices table. - * These are the Foundation (e.g. core) services and are expected to be present on - * all EFI-compliant machines. Some kernel extensions (notably AppleEFIRuntime) - * will call these without checking to see if they are null. - * - * We don't really feel like doing an EFI implementation in the bootloader - * but it is nice if we can at least prevent a complete crash by - * at least providing some sort of implementation until one can be provided - * nicely in a kext. - */ - void (*voidret_fp)() = (void*)fakeEfiPages->voidret_instructions; - void (*unsupportedret_fp)() = (void*)fakeEfiPages->unsupportedret_instructions; - efiRuntimeServices->GetTime = ptov64((EFI_PTR32)unsupportedret_fp); - efiRuntimeServices->SetTime = ptov64((EFI_PTR32)unsupportedret_fp); - efiRuntimeServices->GetWakeupTime = ptov64((EFI_PTR32)unsupportedret_fp); - efiRuntimeServices->SetWakeupTime = ptov64((EFI_PTR32)unsupportedret_fp); - efiRuntimeServices->SetVirtualAddressMap = ptov64((EFI_PTR32)unsupportedret_fp); - efiRuntimeServices->ConvertPointer = ptov64((EFI_PTR32)unsupportedret_fp); - efiRuntimeServices->GetVariable = ptov64((EFI_PTR32)unsupportedret_fp); - efiRuntimeServices->GetNextVariableName = ptov64((EFI_PTR32)unsupportedret_fp); - efiRuntimeServices->SetVariable = ptov64((EFI_PTR32)unsupportedret_fp); - efiRuntimeServices->GetNextHighMonotonicCount = ptov64((EFI_PTR32)unsupportedret_fp); - efiRuntimeServices->ResetSystem = ptov64((EFI_PTR32)voidret_fp); - - /* We're done. Now CRC32 the thing so the kernel will accept it */ - efiRuntimeServices->Hdr.CRC32 = crc32(0L, efiRuntimeServices, efiRuntimeServices->Hdr.HeaderSize); - - - /* -------------------------------------------------------------------- */ - /* Finish filling in the rest of the boot args that we need. */ - bootArgs->efiSystemTable = (uint32_t)efiSystemTable; - bootArgs->efiMode = kBootArgsEfiMode64; - - /* The bootArgs structure as a whole is bzero'd so we don't need to fill in - * things like efiRuntimeServices* and what not. - * - * In fact, the only code that seems to use that is the hibernate code so it - * knows not to save the pages. It even checks to make sure its nonzero. - */ +void setupEfiTables64(void) +{ + struct fake_efi_pages + { + EFI_SYSTEM_TABLE_64 efiSystemTable; + EFI_RUNTIME_SERVICES_64 efiRuntimeServices; + EFI_CONFIGURATION_TABLE_64 efiConfigurationTable[MAX_CONFIGURATION_TABLE_ENTRIES]; + EFI_CHAR16 firmwareVendor[sizeof(FIRMWARE_VENDOR)/sizeof(EFI_CHAR16)]; + uint8_t voidret_instructions[sizeof(VOIDRET_INSTRUCTIONS)/sizeof(uint8_t)]; + uint8_t unsupportedret_instructions[sizeof(UNSUPPORTEDRET_INSTRUCTIONS)/sizeof(uint8_t)]; + }; + + struct fake_efi_pages *fakeEfiPages = (struct fake_efi_pages*)AllocateKernelMemory(sizeof(struct fake_efi_pages)); + + // Zero out all the tables in case fields are added later + bzero(fakeEfiPages, sizeof(struct fake_efi_pages)); + + // -------------------------------------------------------------------- + // Initialize some machine code that will return EFI_UNSUPPORTED for + // functions returning int and simply return for void functions. + memcpy(fakeEfiPages->voidret_instructions, VOIDRET_INSTRUCTIONS, sizeof(VOIDRET_INSTRUCTIONS)); + memcpy(fakeEfiPages->unsupportedret_instructions, UNSUPPORTEDRET_INSTRUCTIONS, sizeof(UNSUPPORTEDRET_INSTRUCTIONS)); + + // -------------------------------------------------------------------- + // System table + EFI_SYSTEM_TABLE_64 *efiSystemTable = gST64 = &fakeEfiPages->efiSystemTable; + efiSystemTable->Hdr.Signature = EFI_SYSTEM_TABLE_SIGNATURE; + efiSystemTable->Hdr.Revision = EFI_SYSTEM_TABLE_REVISION; + efiSystemTable->Hdr.HeaderSize = sizeof(EFI_SYSTEM_TABLE_64); + efiSystemTable->Hdr.CRC32 = 0; // Initialize to zero and then do CRC32 + efiSystemTable->Hdr.Reserved = 0; + + efiSystemTable->FirmwareVendor = ptov64((EFI_PTR32)&fakeEfiPages->firmwareVendor); + memcpy(fakeEfiPages->firmwareVendor, FIRMWARE_VENDOR, sizeof(FIRMWARE_VENDOR)); + efiSystemTable->FirmwareRevision = FIRMWARE_REVISION; + + // XXX: We may need to have basic implementations of ConIn/ConOut/StdErr + // The EFI spec states that all handles are invalid after boot services have been + // exited so we can probably get by with leaving the handles as zero. + efiSystemTable->ConsoleInHandle = 0; + efiSystemTable->ConIn = 0; + + efiSystemTable->ConsoleOutHandle = 0; + efiSystemTable->ConOut = 0; + + efiSystemTable->StandardErrorHandle = 0; + efiSystemTable->StdErr = 0; + + efiSystemTable->RuntimeServices = ptov64((EFI_PTR32)&fakeEfiPages->efiRuntimeServices); + // According to the EFI spec, BootServices aren't valid after the + // boot process is exited so we can probably do without it. + // Apple didn't provide a definition for it in pexpert/i386/efi.h + // so I'm guessing they don't use it. + efiSystemTable->BootServices = 0; + + efiSystemTable->NumberOfTableEntries = 0; + efiSystemTable->ConfigurationTable = ptov64((EFI_PTR32)fakeEfiPages->efiConfigurationTable); + + // We're done. Now CRC32 the thing so the kernel will accept it + gST64->Hdr.CRC32 = crc32(0L, gST64, gST64->Hdr.HeaderSize); + + // -------------------------------------------------------------------- + // Runtime services + EFI_RUNTIME_SERVICES_64 *efiRuntimeServices = &fakeEfiPages->efiRuntimeServices; + efiRuntimeServices->Hdr.Signature = EFI_RUNTIME_SERVICES_SIGNATURE; + efiRuntimeServices->Hdr.Revision = EFI_RUNTIME_SERVICES_REVISION; + efiRuntimeServices->Hdr.HeaderSize = sizeof(EFI_RUNTIME_SERVICES_64); + efiRuntimeServices->Hdr.CRC32 = 0; + efiRuntimeServices->Hdr.Reserved = 0; + + // There are a number of function pointers in the efiRuntimeServices table. + // These are the Foundation (e.g. core) services and are expected to be present on + // all EFI-compliant machines. Some kernel extensions (notably AppleEFIRuntime) + // will call these without checking to see if they are null. + // + // We don't really feel like doing an EFI implementation in the bootloader + // but it is nice if we can at least prevent a complete crash by + // at least providing some sort of implementation until one can be provided + // nicely in a kext. + + void (*voidret_fp)() = (void*)fakeEfiPages->voidret_instructions; + void (*unsupportedret_fp)() = (void*)fakeEfiPages->unsupportedret_instructions; + efiRuntimeServices->GetTime = ptov64((EFI_PTR32)unsupportedret_fp); + efiRuntimeServices->SetTime = ptov64((EFI_PTR32)unsupportedret_fp); + efiRuntimeServices->GetWakeupTime = ptov64((EFI_PTR32)unsupportedret_fp); + efiRuntimeServices->SetWakeupTime = ptov64((EFI_PTR32)unsupportedret_fp); + efiRuntimeServices->SetVirtualAddressMap = ptov64((EFI_PTR32)unsupportedret_fp); + efiRuntimeServices->ConvertPointer = ptov64((EFI_PTR32)unsupportedret_fp); + efiRuntimeServices->GetVariable = ptov64((EFI_PTR32)unsupportedret_fp); + efiRuntimeServices->GetNextVariableName = ptov64((EFI_PTR32)unsupportedret_fp); + efiRuntimeServices->SetVariable = ptov64((EFI_PTR32)unsupportedret_fp); + efiRuntimeServices->GetNextHighMonotonicCount = ptov64((EFI_PTR32)unsupportedret_fp); + efiRuntimeServices->ResetSystem = ptov64((EFI_PTR32)voidret_fp); + + // We're done. Now CRC32 the thing so the kernel will accept it + efiRuntimeServices->Hdr.CRC32 = crc32(0L, efiRuntimeServices, efiRuntimeServices->Hdr.HeaderSize); + + // -------------------------------------------------------------------- + // Finish filling in the rest of the boot args that we need. + bootArgs->efiSystemTable = (uint32_t)efiSystemTable; + bootArgs->efiMode = kBootArgsEfiMode64; + + // The bootArgs structure as a whole is bzero'd so we don't need to fill in + // things like efiRuntimeServices* and what not. + // + // In fact, the only code that seems to use that is the hibernate code so it + // knows not to save the pages. It even checks to make sure its nonzero. } /* -In addition to the EFI tables there is also the EFI device tree node. -In particular, we need /efi/platform to have an FSBFrequency key. Without it, -the tsc_init function will panic very early on in kernel startup, before -the console is available. -*/ + * In addition to the EFI tables there is also the EFI device tree node. + * In particular, we need /efi/platform to have an FSBFrequency key. Without it, + * the tsc_init function will panic very early on in kernel startup, before + * the console is available. + */ /*========================================================================== * FSB Frequency detection @@ -285,22 +401,22 @@ */ /* From Foundation/Efi/Guid/Smbios/SmBios.c */ -EFI_GUID const gEfiSmbiosTableGuid = EFI_SMBIOS_TABLE_GUID; +EFI_GUID const gEfiSmbiosTableGuid = EFI_SMBIOS_TABLE_GUID; -#define SMBIOS_RANGE_START 0x000F0000 -#define SMBIOS_RANGE_END 0x000FFFFF +#define SMBIOS_RANGE_START 0x000F0000 +#define SMBIOS_RANGE_END 0x000FFFFF /* '_SM_' in little endian: */ #define SMBIOS_ANCHOR_UINT32_LE 0x5f4d535f #define EFI_ACPI_TABLE_GUID \ { \ - 0xeb9d2d30, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + 0xeb9d2d30, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } #define EFI_ACPI_20_TABLE_GUID \ { \ - 0x8868e871, 0xe4f1, 0x11d3, { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \ + 0x8868e871, 0xe4f1, 0x11d3, { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \ } EFI_GUID gEfiAcpiTableGuid = EFI_ACPI_TABLE_GUID; @@ -317,227 +433,287 @@ static const char const FIRMWARE_VENDOR_PROP[] = "firmware-vendor"; static const char const FIRMWARE_ABI_32_PROP_VALUE[] = "EFI32"; static const char const FIRMWARE_ABI_64_PROP_VALUE[] = "EFI64"; - static const char const SYSTEM_ID_PROP[] = "system-id"; static const char const SYSTEM_SERIAL_PROP[] = "SystemSerialNumber"; static const char const SYSTEM_TYPE_PROP[] = "system-type"; static const char const MODEL_PROP[] = "Model"; -/* Get an smbios option string option to convert to EFI_CHAR16 string */ +/* + * Get an smbios option string option to convert to EFI_CHAR16 string + */ + static EFI_CHAR16* getSmbiosChar16(const char * key, size_t* len) { - const char * src= getStringForKey(key, &bootInfo->smbiosConfig); - EFI_CHAR16* dst = 0; - size_t i=0; + const char *src = getStringForKey(key, &bootInfo->smbiosConfig); + EFI_CHAR16* dst = 0; + size_t i = 0; + + if (!key || !(*key) || !len || !src) return 0; + + *len = strlen(src); + dst = (EFI_CHAR16*) malloc( ((*len)+1) * 2 ); + for (; i < (*len); i++) dst[i] = src[i]; + dst[(*len)] = '\0'; + *len = ((*len)+1)*2; // return the CHAR16 bufsize in cluding zero terminated CHAR16 + return dst; +} - if (!key || !(*key) || !len || !src) return 0; +/* + * Get the SystemID from the bios dmi info + */ - *len = strlen(src); - dst = (EFI_CHAR16*) malloc( ((*len)+1) * 2 ); - for (; i < (*len); i++) dst[i] = src[i]; - dst[(*len)] = '\0'; - *len = ((*len)+1)*2; // return the CHAR16 bufsize in cluding zero terminated CHAR16 - return dst; -} - -/* Get the SystemID from the bios dmi info */ -static EFI_CHAR8* getSmbiosUUID() +static EFI_CHAR8* getSmbiosUUID() { + static EFI_CHAR8 uuid[UUID_LEN]; + int i, isZero, isOnes; struct SMBEntryPoint *smbios; - SMBByte *p; - int i, isZero, isOnes; - static EFI_CHAR8 uuid[UUID_LEN]; - - smbios = getSmbios(SMBIOS_PATCHED); /* checks for _SM_ anchor and table header checksum */ + SMBByte *p; + + smbios = getSmbios(SMBIOS_PATCHED); // checks for _SM_ anchor and table header checksum if (smbios==NULL) return 0; // getSmbios() return a non null value if smbios is found - - p = (SMBByte*) FindFirstDmiTableOfType(1, 0x19); /* Type 1: (3.3.2) System Information */ + + p = (SMBByte*) FindFirstDmiTableOfType(1, 0x19); // Type 1: (3.3.2) System Information if (p==NULL) return NULL; - + verbose("Found SMBIOS System Information Table 1\n"); p += 8; - - for (i=0, isZero=1, isOnes=1; ibootConfig); + EFI_CHAR8* ret = getUUIDFromString(sysId); - // Rek: new SMsystemid option conforming to smbios notation standards, this option should - // belong to smbios config only ... - const char * sysId = getStringForKey(kSystemID, &bootInfo->bootConfig); - EFI_CHAR8* ret = getUUIDFromString(sysId); + if (!sysId || !ret) // try bios dmi info UUID extraction + { + ret = getSmbiosUUID(); + sysId = 0; + } + + if (!ret) // no bios dmi UUID available, set a fixed value for system-id + ret=getUUIDFromString((sysId = (const char*) SYSTEM_ID)); + + verbose("Customizing SystemID with : %s\n", getStringFromUUID(ret)); // apply a nice formatting to the displayed output + return ret; +} - if(!sysId || !ret) { // try bios dmi info UUID extraction - ret = getSmbiosUUID(); - sysId = 0; - } - if(!ret) // no bios dmi UUID available, set a fixed value for system-id - ret=getUUIDFromString((sysId = (const char*) SYSTEM_ID)); +/* + * Must be called AFTER setup Acpi because we need to take care of correct + * facp content to reflect in ioregs + */ - verbose("Customizing SystemID with : %s\n", getStringFromUUID(ret)); // apply a nice formatting to the displayed output - return ret; -} - -// must be called AFTER setup Acpi because we need to take care of correct facp content to reflect in ioregs void setupSystemType() { - Node *node = DT__FindNode("/", false); - if (node == 0) stop("Couldn't get root node"); - // we need to write this property after facp parsing - /* Export system-type only if it has been overrriden by the SystemType option */ - DT__AddProperty(node, SYSTEM_TYPE_PROP, sizeof(Platform.Type), &Platform.Type); + Node *node = DT__FindNode("/", false); + if (node == 0) stop("Couldn't get root node"); + // we need to write this property after facp parsing + // Export system-type only if it has been overrriden by the SystemType option + DT__AddProperty(node, SYSTEM_TYPE_PROP, sizeof(Platform.Type), &Platform.Type); } void setupEfiDeviceTree(void) { - EFI_CHAR16* ret16=0; - EFI_CHAR8* ret=0; - size_t len=0; - Node *node; - - node = DT__FindNode("/", false); - - if (node == 0) stop("Couldn't get root node"); - - /* We could also just do DT__FindNode("/efi/platform", true) - * But I think eventually we want to fill stuff in the efi node - * too so we might as well create it so we have a pointer for it too. - */ - node = DT__AddChild(node, "efi"); - - DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION); + EFI_CHAR8* ret = 0; + EFI_CHAR16* ret16 = 0; + size_t len = 0; + Node *node; - if(platformCPUFeature(CPU_FEATURE_EM64T)) + node = DT__FindNode("/", false); + + if (node == 0) stop("Couldn't get root node"); + + // We could also just do DT__FindNode("/efi/platform", true) + // But I think eventually we want to fill stuff in the efi node + // too so we might as well create it so we have a pointer for it too. + node = DT__AddChild(node, "efi"); + + if (archCpuType == CPU_TYPE_I386) { + DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_32_PROP_VALUE), (char*)FIRMWARE_ABI_32_PROP_VALUE); + } + else + { DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_64_PROP_VALUE), (char*)FIRMWARE_ABI_64_PROP_VALUE); } + + DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION); + DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR); + + // TODO: Fill in other efi properties if necessary + + // Set up the /efi/runtime-services table node similar to the way a child node of configuration-table + // is set up. That is, name and table properties + Node *runtimeServicesNode = DT__AddChild(node, "runtime-services"); + + if (archCpuType == CPU_TYPE_I386) + { + // The value of the table property is the 32-bit physical address for the RuntimeServices table. + // Since the EFI system table already has a pointer to it, we simply use the address of that pointer + // for the pointer to the property data. Warning.. DT finalization calls free on that but we're not + // the only thing to use a non-malloc'd pointer for something in the DT + + DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST32->RuntimeServices); + } else { - DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_32_PROP_VALUE), (char*)FIRMWARE_ABI_32_PROP_VALUE); + DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST64->RuntimeServices); } - DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR); + // Set up the /efi/configuration-table node which will eventually have several child nodes for + // all of the configuration tables needed by various kernel extensions. + gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table"); + + // Now fill in the /efi/platform Node + Node *efiPlatformNode = DT__AddChild(node, "platform"); + + // NOTE WELL: If you do add FSB Frequency detection, make sure to store + // the value in the fsbFrequency global and not an malloc'd pointer + // because the DT_AddProperty function does not copy its args. + + if (Platform.CPU.FSBFrequency != 0) + DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform.CPU.FSBFrequency); + + // Export TSC and CPU frequencies for use by the kernel or KEXTs + if (Platform.CPU.TSCFrequency != 0) + DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &Platform.CPU.TSCFrequency); + + if (Platform.CPU.CPUFrequency != 0) + DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &Platform.CPU.CPUFrequency); + + // Export system-id. Can be disabled with SystemId=No in com.apple.Boot.plist + if ((ret=getSystemID())) + DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, UUID_LEN, (EFI_UINT32*) ret); - /* TODO: Fill in other efi properties if necessary */ + // Export SystemSerialNumber if present + if ((ret16=getSmbiosChar16("SMserial", &len))) + DT__AddProperty(efiPlatformNode, SYSTEM_SERIAL_PROP, len, ret16); + + // Export Model if present + if ((ret16=getSmbiosChar16("SMproductname", &len))) + DT__AddProperty(efiPlatformNode, MODEL_PROP, len, ret16); + + // Fill /efi/device-properties node. + setupDeviceProperties(node); +} - /* Set up the /efi/runtime-services table node similar to the way a child node of configuration-table - * is set up. That is, name and table properties */ - Node *runtimeServicesNode = DT__AddChild(node, "runtime-services"); +/* + * Load the smbios.plist override config file if any + */ - /* The value of the table property is the 32-bit physical address for the RuntimeServices table. - * Since the EFI system table already has a pointer to it, we simply use the address of that pointer - * for the pointer to the property data. Warning.. DT finalization calls free on that but we're not - * the only thing to use a non-malloc'd pointer for something in the DT - */ - DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST->RuntimeServices); +static void setupSmbiosConfigFile(const char *filename) +{ + char dirSpecSMBIOS[128] = ""; + const char *override_pathname = NULL; + int len = 0, err = 0; + extern void scan_mem(); + + // Take in account user overriding + if (getValueForKey(kSMBIOSKey, &override_pathname, &len, &bootInfo->bootConfig) && len > 0) + { + // Specify a path to a file, e.g. SMBIOS=/Extra/macProXY.plist + sprintf(dirSpecSMBIOS, override_pathname); + err = loadConfigFile(dirSpecSMBIOS, &bootInfo->smbiosConfig); + } + else + { + // Check selected volume's Extra. + sprintf(dirSpecSMBIOS, "/Extra/%s", filename); + if (err = loadConfigFile(dirSpecSMBIOS, &bootInfo->smbiosConfig)) + { + // Check booter volume/rdbt Extra. + sprintf(dirSpecSMBIOS, "bt(0,0)/Extra/%s", filename); + err = loadConfigFile(dirSpecSMBIOS, &bootInfo->smbiosConfig); + } + } - /* Set up the /efi/configuration-table node which will eventually have several child nodes for - * all of the configuration tables needed by various kernel extensions. - */ - gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table"); + if (err) + { + verbose("No SMBIOS replacement found.\n"); + } - /* Now fill in the /efi/platform Node */ - Node *efiPlatformNode = DT__AddChild(node, "platform"); - - /* NOTE WELL: If you do add FSB Frequency detection, make sure to store - * the value in the fsbFrequency global and not an malloc'd pointer - * because the DT_AddProperty function does not copy its args. - */ - if(Platform.CPU.FSBFrequency != 0) - DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform.CPU.FSBFrequency); - - /* Export TSC and CPU frequencies for use by the kernel or KEXTs */ - if(Platform.CPU.TSCFrequency != 0) - DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &Platform.CPU.TSCFrequency); - - if(Platform.CPU.CPUFrequency != 0) - DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &Platform.CPU.CPUFrequency); - - /* Export system-id. Can be disabled with system-id=No in com.apple.Boot.plist */ - if((ret=getSystemID())) - DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, UUID_LEN, (EFI_UINT32*) ret); - - /* Export SystemSerialNumber if present */ - if ((ret16=getSmbiosChar16("SMserial", &len))) - DT__AddProperty(efiPlatformNode, SYSTEM_SERIAL_PROP, len, ret16); - - /* Export Model if present */ - if ((ret16=getSmbiosChar16("SMproductname", &len))) - DT__AddProperty(efiPlatformNode, MODEL_PROP, len, ret16); - - /* Fill /efi/device-properties node. - */ - setupDeviceProperties(node); + // get a chance to scan mem dynamically if user asks for it while having the config options loaded as well, + // as opposed to when it was in scan_platform(); also load the orig. smbios so that we can access dmi info without + // patching the smbios yet + getSmbios(SMBIOS_ORIGINAL); + scan_mem(); + smbios_p = (EFI_PTR32)getSmbios(SMBIOS_PATCHED); // process smbios asap } -/* Load the smbios.plist override config file if any */ -static void setupSmbiosConfigFile() -{ - const char * value = getStringForKey(kSMBIOS, &bootInfo->bootConfig); - extern void scan_mem(); +/* + * Installs all the needed configuration table entries + */ - if (!value) value = "/Extra/smbios.plist"; - if (loadConfigFile(value, &bootInfo->smbiosConfig) == -1) { - verbose("No SMBIOS replacement found\n"); - } - - // get a chance to scan mem dynamically if user asks for it while having the config options loaded as well - // as opposed to when it was in scan_platform(), also load the orig. smbios so that we can access dmi info without - // patching the smbios yet - getSmbios(SMBIOS_ORIGINAL); - scan_mem(); - smbios_p = (EFI_PTR32) getSmbios(SMBIOS_PATCHED); // process smbios asap -} - -/* Installs all the needed configuration table entries */ static void setupEfiConfigurationTable() { - smbios_p = (EFI_PTR32)getSmbios(SMBIOS_PATCHED); - addConfigurationTable(&gEfiSmbiosTableGuid, &smbios_p, NULL); - - // Setup ACPI with DSDT overrides (mackerintel's patch) - setupAcpi(); - - // We've obviously changed the count.. so fix up the CRC32 - fixupEfiSystemTableCRC32(gST); + smbios_p = (EFI_PTR32)getSmbios(SMBIOS_PATCHED); + addConfigurationTable(&gEfiSmbiosTableGuid, &smbios_p, NULL); + + // Setup ACPI with DSDT overrides (mackerintel's patch) + setupAcpi(); + + // We've obviously changed the count.. so fix up the CRC32 + if (archCpuType == CPU_TYPE_I386) + { + gST32->Hdr.CRC32 = 0; + gST32->Hdr.CRC32 = crc32(0L, gST32, gST32->Hdr.HeaderSize); + } + else + { + gST64->Hdr.CRC32 = 0; + gST64->Hdr.CRC32 = crc32(0L, gST64, gST64->Hdr.HeaderSize); + } } -static void setupEfiDevices(setup) +/* + * Entrypoint from boot.c + */ + +void setupFakeEfi(void) { + // Generate efi device strings setup_pci_devs(root_pci_dev); -} -/* Entrypoint from boot.c */ -void setupFakeEfi(void) -{ - // load smbios.plist file if any - setupSmbiosConfigFile(); + // load smbios.plist file if any + setupSmbiosConfigFile("SMBIOS.plist"); - // Generate efi device strings - setupEfiDevices(); + // Initialize the base table + if (archCpuType == CPU_TYPE_I386) + { + setupEfiTables32(); + } + else + { + setupEfiTables64(); + } - // Initialize the base table - setupEfiTables(); + // Initialize the device tree + setupEfiDeviceTree(); - // Initialize the device tree - setupEfiDeviceTree(); - - // Add configuration table entries to both the services table and the device tree - setupEfiConfigurationTable(); + // Add configuration table entries to both the services table and the device tree + setupEfiConfigurationTable(); } Index: branches/meklort/i386/libsaio/msdos.h =================================================================== --- branches/meklort/i386/libsaio/msdos.h (revision 504) +++ branches/meklort/i386/libsaio/msdos.h (revision 505) @@ -24,10 +24,10 @@ extern long MSDOSInitPartition(CICell ih); extern long MSDOSLoadFile(CICell ih, char * filePath); extern long MSDOSReadFile(CICell ih, char * filePath, void *base, uint64_t offset, uint64_t length); -extern long MSDOSGetDirEntry(CICell ih, char * dirPath, long * dirIndex, +extern long MSDOSGetDirEntry(CICell ih, char * dirPath, long long * dirIndex, char ** name, long * flags, long * time, FinderInfo * finderInfo, long * infoValid); extern long MSDOSGetFileBlock(CICell ih, char *str, unsigned long long *firstBlock); extern long MSDOSGetUUID(CICell ih, char *uuidStr); extern void MSDOSFree(CICell ih); -extern int MSDOSProbe (const void *buf); \ No newline at end of file +extern int MSDOSProbe (const void *buf); Index: branches/meklort/i386/libsaio/saio_internal.h =================================================================== --- branches/meklort/i386/libsaio/saio_internal.h (revision 504) +++ branches/meklort/i386/libsaio/saio_internal.h (revision 505) @@ -89,8 +89,11 @@ /* console.c */ extern bool gVerboseMode; extern bool gErrors; +extern void initBooterLog(void); +extern void setupBooterLog(void); extern void putchar(int ch); extern int getchar(void); +extern void msglog(const char * format, ...); extern int printf(const char *format, ...); extern int error(const char *format, ...); extern int verbose(const char *format, ...); @@ -170,7 +173,7 @@ extern long LoadFile(const char *fileSpec); extern long ReadFileAtOffset(const char * fileSpec, void *buffer, uint64_t offset, uint64_t length); extern long LoadThinFatFile(const char *fileSpec, void **binary); -extern long GetDirEntry(const char *dirSpec, long *dirIndex, const char **name, +extern long GetDirEntry(const char *dirSpec, long long *dirIndex, const char **name, long *flags, long *time); extern long GetFileInfo(const char *dirSpec, const char *name, long *flags, long *time); @@ -183,6 +186,9 @@ extern int close(int fdesc); extern int file_size(int fdesc); extern int read(int fdesc, char *buf, int count); +extern int write(int fdesc, const char *buf, int count); +extern int writebyte(int fdesc, char value); +extern int writeint(int fdesc, int value); extern int b_lseek(int fdesc, int addr, int ptr); extern int tell(int fdesc); extern const char * systemConfigDir(void); @@ -199,6 +205,7 @@ extern void getBootVolumeDescription(BVRef bvr, char *str, long strMaxLen, bool verbose); extern void setRootVolume(BVRef volume); extern void setBootGlobals(BVRef chain); +extern int getDeviceDescription(BVRef volume, char *str); extern int gBIOSDev; extern int gBootFileType; Index: branches/meklort/i386/boot0/boot0.s =================================================================== --- branches/meklort/i386/boot0/boot0.s (revision 504) +++ branches/meklort/i386/boot0/boot0.s (revision 505) @@ -55,7 +55,7 @@ ; ; Set to 1 to enable verbose mode ; -VERBOSE EQU 0 +VERBOSE EQU 1 ; ; Various constants. Index: branches/meklort/i386/boot1/boot1.asm =================================================================== --- branches/meklort/i386/boot1/boot1.asm (revision 504) +++ branches/meklort/i386/boot1/boot1.asm (revision 505) @@ -1,390 +0,0 @@ -; boot1.asm - boot1 written for turbo assembler, since gas only -; generates 32 bit code and this must run in real mode. -; To compile as hard disk boot1: -; tasm /m3 /dBOOTDEV=HDISK boot1 -; tlink boot1 -; exe2bin boot1 -; ren boot1.bin boot1 -; To compile as floppy boot1f: -; tasm /m3 /dBOOTDEV=FLOPPY boot1 ,boot1f -; tlink boot1f -; exe2bin boot1f -; ren boot1f.bin boot1f - -;*********************************************************************** -; This is the code for the NeXT boot1 bootsector. -;*********************************************************************** - - P486 ;enable i386 instructions - IDEAL - SEGMENT CSEG - ASSUME CS:CSEG,DS:CSEG - - SDEBUG = 0 - -;BOOTSEG = 100h ; boot will be loaded at 4k -;BOOTOFF = 0000h -BOOTSEG = 00h -BOOTOFF = 1000h -BUFSZ = 2000h ; 8K disk transfer buffer - -; FDISK partition table in sector 0 -PARTSTART = 1beh ; starting address of partition table -NUMPART = 4 ; number of partitions in partition table -PARTSZ = 16 ; each partition table entry is 16 bytes -BOOT_IND = 0 ; offset of boot indicator in partition table -BEG_HEAD = 1 ; offset of beginning head -BEG_SEC = 2 ; offset of beginning sector -BEG_CYL = 3 ; offset of beginning cylinder -NAME_OFFSET = 4 ; offset of partition name -PARTSEC = 8 ; offset of partition sector specifier -NEXTNAME = 0A7h ; value of boot_ind, means bootable partition - -LOADSZ = 88 ; maxiumum possible size of unix boot -- 44k - -FLOPPY = 0 -HDISK = 80h - -;BOOTDEV = ? ; set to 00h for floppy, 80h for hard disk - ; (use a command line switch to set) - -; NeXT disk label -DISKLABEL = 15 ; sector num of 2nd disk label, 1st is trashed by bootsec -DL_DISKTAB = 44 - -; We support disk label version 3 "3Vld" in our little endian world -DL_V3 = 33566c64h - -; NeXT disktab -DT_SECSIZE = 48 -DT_BOOT0_BLKNO = 80 - - -; This code is a replacement for boot1. It is loaded at 0x0:0x7c00 - -start: - mov ax,BOOTSEG - cli ; interrupts off - mov ss,ax ; set up stack seg - mov sp,0fff0h - sti ; reenable interrupts - - xor ax,ax - mov es,ax - mov ds,ax - mov si,7C00h - cld ; so pointers will get updated - mov di,0E000h ; relocate boot program to 0xE000 - mov cx,100h ; copy 256x2 bytes - repnz movsw ; move it - off1 = 0E000h + (a1 - start) - jmp FAR 0000:off1 ; jump to a1 in relocated place - -a1: - mov ax,0E00h - mov ds,ax - mov ax,BOOTSEG - mov es,ax - - ; load the boot loader (boot2) into BOOTSEG:BUFSZ - call loadboot - - ; ljmp to the second stage boot loader (boot2). - ; After ljmp, cs is BOOTSEG and boot1 (BUFSZ bytes) will be used - ; as an internal buffer "intbuf". - - xor edx,edx ; bootdev = 0 for hard disk -IF ( BOOTDEV EQ FLOPPY ) - inc edx ; bootdev = 1 for floppy disk -ENDIF - - ;boot2 immediately follows disk buffer; 4K + BUFSZ - jmp FAR BOOTSEG:(BOOTOFF + BUFSZ) - ; jump to boot2 in loaded location - - - -loadboot: - mov si, OFFSET intro - call message ; display intro message - - ; load second stage boot from fixed disk - ; get boot drive parameters - ; Note: I believe that the bootsector read may not be necessary; - ; at least some blk0 bootsectors leave a pointer to the active - ; partition entry in si (assuming there was another blk0 bootsec) - - call getinfo - - -IF ( BOOTDEV EQ HDISK ) - - ; read sector 0 into BOOTSEG:0 by using BIOS call (INT 13H 02H) - ; this gets info on the disk's actual partition table - ; However, in the case of multiple partitions, this may not - ; be the same as the sector with the code here. - - mov di,5 ; try 5 times to read bootsector - -retry_disk: - xor bx, bx ; buffer is BOOTSEG:0 - mov ax,201h - mov cx,bx - mov dx,bx - mov bx,BOOTOFF ; actually, it's 0:BOOTOFF - inc cx ; cyl 0, sector 1 - mov dl,BOOTDEV ; target 0, head 0 - - push di - int 13h ; read the bootsector - pop di - - jnb read_success1 - - ; woops, bios failed to read sector - xor ax,ax - int 13h ; reset disk - dec di - jne retry_disk - - jmp read_error ; disk failed - - -read_success1: ; find the NeXT partition - mov bx,PARTSTART - mov cx,NUMPART - -again: - mov al, [es:(bx+BOOTOFF)+NAME_OFFSET] - ; get partition name - cmp al, NEXTNAME ; is it NeXT partition? - jne cont ; nope, keep looking - -foundNextPart: ; found it, get label location - - mov eax, [es:(bx+BOOTOFF)+PARTSEC] - ; offset to NeXT partition - add eax, DISKLABEL ; add offset to the label - jmp getLabl ; fetch that label - -cont: - add bx, PARTSZ - loop again ; if more part table entries, - ; keep looking - - ; fall through, didn't find NeXT disk partition entry - -no_fdisk: -ENDIF - ; Read NeXT disk label - mov eax, DISKLABEL ; Get block number of label -getLabl: - mov bx,BOOTOFF ; read into load area - mov cx,1 - call readSectors - - ; we used to think about testing the disk label version here... - - mov bx,BOOTOFF ; point to beginning of label - - ; Use values from label to read entire boot program - ; Get block number of boot - ; Get dl_secsize and dl_boot0_blkno[0] - mov edx, [es:(bx + DL_DISKTAB+DT_SECSIZE)] - bswap edx ; edx -> sector size - - mov eax, [es:(bx + DL_DISKTAB+DT_BOOT0_BLKNO)] - bswap eax ; eax -> block # - - ; Compute dl_secsize * dt_boot0_blkno[0] / 512 - shr edx, 9 ; divide dl_secsize by 512 - mul edx ; multiply boot block loc - ; by dl_secsize/512 - ; eax has secno - mov bx, (BUFSZ + BOOTOFF) ; read boot2 into BOOTSEG:BUFSZ - mov edi, LOADSZ ; read this many sectors -nexsec: - push eax ; push sector # - push bx ; push buffer address - mov ecx, edi ; max number of sectors to read - - call readSectors - pop bx - pop eax - add eax, ecx ; add number of sectors read - sub di, cx - shl cx, 9 ; multiply by 512 bytes per sector - add bx, cx - - cmp di, 0 - jne nexsec - - ret - -spt: DW 0 ; sectors;track (one-based) -spc: DW 0 ; tracks;cylinder (zero-based) -nsec: DW 0 ; number of sectors to read - -readSectors: ; eax has starting block #, bx has offset from BOOTSEG - ; cx has maximum number of sectors to read - ; Trashes ax, bx, cx, dx - - ; BIOS call "INT 0x13 Function 0x2" to read sectors - ; ah = 0x2 al = number of sectors - ; ch = cylinder cl = sector - ; dh = head dl = drive (0x80=hard disk, 0=floppy disk) - ; es:bx = segment:offset of buffer - -IF ( BOOTDEV EQ FLOPPY ) - push eax - mov al,'.' - call putchr - pop eax -ENDIF - - push bx ; save offset - mov [WORD nsec], cx - - mov ebx, eax ; bx -> block # - xor ecx, ecx - mov cx, [WORD spc] ; cx -> sectors/cyl - - xor edx,edx ; prepare for division - div ecx ; eax = cyl, edx=remainder - push ax ; save cylinder #, sec/spc - - mov eax, edx - mov cx, [WORD spt] ; ecx -> sectors/track - xor edx,edx ; prepare for division - div ecx ; eax = head - push ax ; save head, (secspc)/spt - - mov eax, ebx ; reload block # - xor edx, edx ; prepare for division - div ecx ; edx has sector # - - sub cx, dx ;cx now has number of sectors to read - cmp cx, [WORD nsec] - jge last ; use the minimum of bx and cx - mov [WORD nsec], cx -last: - - mov cx, dx ; cl -> sector - inc cl ; starts @ 1 - pop ax ; get head - mov dh, al ; dh -> head - - pop ax ; get cyl - mov ch, al ; ch -> cyl - mov dl, BOOTDEV ; floppy disk - - xor al,al - shr ax,2 - or cl,al ; retain pesky big cyl bits - -; mov al, 1 ; get # of sectors -;pop ax ; number of sectors to read -mov ax, [WORD nsec] - pop bx ; get buffer - mov ah, 2 ; bios read function - - int 13h - - jb read_error -mov cx, [WORD nsec] ; return number of sectors read - ret - - -getinfo: ; get some drive parameters - mov dl, BOOTDEV ; boot drive is drive C - mov ah, 8h - push es - int 13h - pop es - - mov al, dh ; max head # - inc al ; al -> tracks/cyl - and cx, 3fh ; cl -> secs/track - mul cl ; ax -> secs/cyl - mov [WORD spc], ax - mov [WORD spt], cx - - ret - - -message: ; write the error message in ds:esi - ; to console - push es - mov ax,ds - mov es,ax - - mov bx, 1 ; bh=0, bl=1 (blue) - cld - -nextb: - lodsb ; load a byte into al - cmp al, 0 - je done - mov ah, 0eh ; bios int 10, function 0xe - int 10h ; bios display a byte in tty mode - jmp nextb -done: pop es - ret - -putchr: - push bx - mov bx, 1 ; bh=0, bl=1 (blue) - mov ah, 0eh ; bios int 10, function 0xe - int 10h ; bios display a byte in tty mode - pop bx - ret - -IF SDEBUG -hexout: - ; print ebx as hex number - push cx - push ax - mov cx,8 ;output 8 nibbles - -htop: - rol ebx,4 - mov al,bl - and al,0fh - cmp al,0ah - jb o_digit - add al,'A'-10 - jmp o_print -o_digit: add al,'0' -o_print: call putchr - dec cx - jne htop -; mov al,10 -; call putchr -; mov al,13 -; call putchr - mov al,' ' - call putchr - pop ax - pop cx - ret -ENDIF - - -read_error: - mov si, OFFSET eread -boot_exit: ; boot_exit: write error message and halt - call message ; display error message -halt: jmp halt - - -intro: db 10,'NEXTSTEP boot1 vXX.XX.XX.XX.XX',10,13,0 -eread: db 'Read error',10,13,0 - -; the last 2 bytes in the sector contain the signature -d1: - a2 = 510 - (d1 - start) - DB a2 dup (0) - DW 0AA55h - ENDS - END Index: branches/meklort/i386/boot1/boot1f32.s =================================================================== --- branches/meklort/i386/boot1/boot1f32.s (revision 504) +++ branches/meklort/i386/boot1/boot1f32.s (revision 505) @@ -75,7 +75,7 @@ kBoot1LoadAddr EQU 0x7C00 ; boot1 load address kBoot1RelocAddr EQU 0xE000 ; boot1 relocated address -kBoot2Sectors EQU (384 * 1024 - 512) / kSectorBytes ; max size of 'boot' file in sectors +kBoot2Sectors EQU (448 * 1024 - 512) / kSectorBytes ; max size of 'boot' file in sectors kBoot2Segment EQU 0x2000 ; boot2 load segment kBoot2Address EQU kSectorBytes ; boot2 load address Index: branches/meklort/i386/boot1/boot1he.s =================================================================== --- branches/meklort/i386/boot1/boot1he.s (revision 504) +++ branches/meklort/i386/boot1/boot1he.s (revision 505) @@ -79,7 +79,7 @@ kBoot1ExtAddr EQU kBoot1RelocAddr + kSectorBytes ; boot1 load address for sector 41-47 kHFSPlusBuffer EQU kBoot1RelocAddr + kBoot1ExtSize ; HFS+ Volume Header address -kBoot2Sectors EQU (384 * 1024 - 512) / kSectorBytes ; max size of 'boot' file in sectors +kBoot2Sectors EQU (448 * 1024 - 512) / kSectorBytes ; max size of 'boot' file in sectors kBoot2Segment EQU 0x2000 ; boot2 load segment kBoot2Address EQU kSectorBytes ; boot2 load address Index: branches/meklort/i386/boot1/boot1.s =================================================================== --- branches/meklort/i386/boot1/boot1.s (revision 504) +++ branches/meklort/i386/boot1/boot1.s (revision 505) @@ -52,7 +52,7 @@ ; ; Set to 1 to enable verbose mode. ; -VERBOSE EQU 0 +VERBOSE EQU 1 ; ; Various constants. @@ -74,7 +74,7 @@ kBoot1Sector1Addr EQU kBoot1RelocAddr + kSectorBytes ; boot1 load address for sector 1 kHFSPlusBuffer EQU kBoot1Sector1Addr + kSectorBytes ; HFS+ Volume Header address -kBoot2Sectors EQU (384 * 1024 - 512) / kSectorBytes ; max size of 'boot' file in sectors +kBoot2Sectors EQU (448 * 1024 - 512) / kSectorBytes ; max size of 'boot' file in sectors kBoot2Segment EQU 0x2000 ; boot2 load segment kBoot2Address EQU kSectorBytes ; boot2 load address Index: branches/meklort/i386/boot1/boot1f32-install.sh =================================================================== --- branches/meklort/i386/boot1/boot1f32-install.sh (revision 0) +++ branches/meklort/i386/boot1/boot1f32-install.sh (revision 505) @@ -0,0 +1,26 @@ +#!/bin/sh + +# boot1f32-install.sh +# +# Created by mackerintel on 2/2/09. +# Copyright 2009 mackerintel. All rights reserved. + +if [[ x$1 == x ]]; then + echo Usage: $0 disknumber; + exit 0; +fi + +if [[ `dd if=/dev/disk${1}s1 count=8 bs=1 skip=82 | uuencode -m -|head -n 2|tail -n 1` != "RkFUMzIgICA=" ]]; then + echo "/dev/disk${1}s1" "isn't" a FAT32 partition; + exit 1; +fi + +if [ ! -f boot1f32 ]; then + echo "boot1f32 not found"; + exit 1; +fi + +dd if=/dev/disk${1}s1 count=1 bs=512 of=/tmp/origbs +cp boot1f32 /tmp/newbs +dd if=/tmp/origbs of=/tmp/newbs skip=3 seek=3 bs=1 count=87 conv=notrunc +dd of=/dev/disk${1}s1 count=1 bs=512 if=/tmp/newbs Index: branches/meklort/i386/boot2/graphics.c =================================================================== --- branches/meklort/i386/boot2/graphics.c (revision 504) +++ branches/meklort/i386/boot2/graphics.c (revision 505) @@ -1127,7 +1127,7 @@ params[1] = 25; } - setVESATextMode( params[0], params[1], 4 ); + setVESATextMode( params[0], params[1], 4 ); bootArgs->Video.v_display = VGA_TEXT_MODE; } @@ -1193,21 +1193,25 @@ return; } - if (gVerboseMode) { - currentTickTime = time18(); // late binding - if (currentTickTime < lastTickTime + MIN_TICKS) { - return; - } else { - lastTickTime = currentTickTime; - } - - if (getVideoMode() == VGA_TEXT_MODE) { - if (currentIndicator >= sizeof(indicator)) { - currentIndicator = 0; - } - printf("%c\b", indicator[currentIndicator++]); - } - } + currentTickTime = time18(); // late binding + if (currentTickTime < lastTickTime + MIN_TICKS) + { + return; + } + else + { + lastTickTime = currentTickTime; + } + + if (getVideoMode() == VGA_TEXT_MODE) + { + if (currentIndicator >= sizeof(indicator)) + { + currentIndicator = 0; + } + putc(indicator[currentIndicator++]); + putc('\b'); + } } void @@ -1215,7 +1219,8 @@ { if ( getVideoMode() == VGA_TEXT_MODE ) { - printf(" \b"); + putc(' '); + putc('\b'); } } Index: branches/meklort/i386/boot2/boot.c =================================================================== --- branches/meklort/i386/boot2/boot.c (revision 504) +++ branches/meklort/i386/boot2/boot.c (revision 505) @@ -85,8 +85,8 @@ //static void selectBiosDevice(void); static unsigned long Adler32(unsigned char *buffer, long length); +static bool getOSVersion(char *str); - static bool gUnloadPXEOnExit = false; /* @@ -168,6 +168,8 @@ setupFakeEfi(); + md0Ramdisk(); + verbose("Starting Darwin %s\n",( archCpuType == CPU_TYPE_I386 ) ? "x86" : "x86_64"); // Cleanup the PXE base code. @@ -181,11 +183,13 @@ } bool dummyVal; - if (getBoolForKey(kWaitForKeypressKey, &dummyVal, &bootInfo->bootConfig) && dummyVal) { - printf("Press any key to continue..."); - getc(); - } + if (getBoolForKey(kWaitForKeypressKey, &dummyVal, &bootInfo->bootConfig) && dummyVal) { + printf("Press any key to continue..."); + getc(); + } + usb_loop(); + // If we were in text mode, switch to graphics mode. // This will draw the boot graphics unless we are in // verbose mode. @@ -195,6 +199,8 @@ else drawBootGraphics(); + setupBooterLog(); + finalizeBootStruct(); usb_loop(); @@ -254,6 +260,8 @@ // Initialize boot info structure. initKernBootStruct(); + initBooterLog(); + // Setup VGA text mode. // Not sure if it is safe to call setVideoMode() before the // config table has been loaded. Call video_mode() instead. @@ -333,14 +341,14 @@ getc(); #endif - useGUI = true; - // Override useGUI default - getBoolForKey(kGUIKey, &useGUI, &bootInfo->bootConfig); - if (useGUI) { - patchVideoBios(); - /* XXX AsereBLN handle error */ - initGUI(); - } + useGUI = true; + // Override useGUI default + getBoolForKey(kGUIKey, &useGUI, &bootInfo->bootConfig); + if (useGUI && initGUI()) + { + // initGUI() returned with an error, disabling GUI. + useGUI = false; + } setBootGlobals(bvChain); @@ -356,8 +364,6 @@ bool tryresumedefault; bool forceresume; - config_file_t systemVersion; // system.plist of booting partition - // additional variable for testing alternate kernel image locations on boot helper partitions. char bootFileSpec[512]; @@ -386,17 +392,13 @@ bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount); setBootGlobals(bvChain); + setupDeviceList(&bootInfo->themeConfig); } continue; } // Other status (e.g. 0) means that we should proceed with boot. - if( bootArgs->Video.v_display == GRAPHICS_MODE ) - drawBackground(); - - // Found and loaded a config file. Proceed with boot. - // Turn off any GUI elements if( bootArgs->Video.v_display == GRAPHICS_MODE ) { @@ -404,19 +406,13 @@ gui.bootprompt.draw = false; gui.menu.draw = false; gui.infobox.draw = false; + gui.logo.draw = false; drawBackground(); updateVRAM(); } // Find out which version mac os we're booting. - if (!loadConfigFile("System/Library/CoreServices/SystemVersion.plist", &systemVersion)) { - if (getValueForKey(kProductVersion, &val, &len, &systemVersion)) { - // getValueForKey uses const char for val - // so copy it and trim - strncpy(gMacOSVersion, val, MIN(len, 4)); - gMacOSVersion[MIN(len, 4)] = '\0'; - } - } + getOSVersion(gMacOSVersion); if (platformCPUFeature(CPU_FEATURE_EM64T)) { archCpuType = CPU_TYPE_X86_64; @@ -428,10 +424,7 @@ archCpuType = CPU_TYPE_I386; } } - if (getValueForKey(k32BitModeFlag, &val, &len, &bootInfo->bootConfig)) { - archCpuType = CPU_TYPE_I386; - } - + if (!getBoolForKey (kWake, &tryresume, &bootInfo->bootConfig)) { tryresume = true; tryresumedefault = true; @@ -577,12 +570,8 @@ if (ret <= 0) { printf("Can't find %s\n", bootFile); - if(gui.initialised) { - sleep(1); - drawBackground(); - gui.devicelist.draw = true; - gui.redraw = true; - } + sleep(1); + if (gBootFileType == kNetworkDeviceType) { // Return control back to PXE. Don't unload PXE base code. gUnloadPXEOnExit = false; @@ -629,6 +618,38 @@ } */ +static bool getOSVersion(char *str) +{ + bool valid = false; + config_file_t systemVersion; + const char *val; + int len; + + if (!loadConfigFile("System/Library/CoreServices/SystemVersion.plist", &systemVersion)) + { + valid = true; + } + else if (!loadConfigFile("System/Library/CoreServices/ServerVersion.plist", &systemVersion)) + { + valid = true; + } + + if (valid) + { + if (getValueForKey(kProductVersion, &val, &len, &systemVersion)) + { + // getValueForKey uses const char for val + // so copy it and trim + *str = '\0'; + strncat(str, val, MIN(len, 4)); + } + else + valid = false; + } + + return valid; +} + #define BASE 65521L /* largest prime smaller than 65536 */ #define NMAX 5000 // NMAX (was 5521) the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 Index: branches/meklort/i386/boot2/boot.h =================================================================== --- branches/meklort/i386/boot2/boot.h (revision 504) +++ branches/meklort/i386/boot2/boot.h (revision 505) @@ -42,53 +42,57 @@ #define kKernelNameKey "Kernel" #define kKernelCacheKey "Kernel Cache" #define kBootDeviceKey "Boot Device" -#define kTimeoutKey "Timeout" +#define kTimeoutKey "Timeout" #define kRootDeviceKey "rd" #define kBootUUIDKey "boot-uuid" #define kHelperRootUUIDKey "Root UUID" #define kPlatformKey "platform" -#define kACPIKey "acpi" +#define kACPIKey "acpi" #define kCDROMPromptKey "CD-ROM Prompt" #define kCDROMOptionKey "CD-ROM Option Key" #define kRescanPromptKey "Rescan Prompt" -#define kRescanKey "Rescan" +#define kRescanKey "Rescan" #define kScanSingleDriveKey "Scan Single Drive" #define kInsantMenuKey "Instant Menu" #define kDefaultKernel "mach_kernel" -#define kGUIKey "GUI" +#define kGUIKey "GUI" #define kBootBannerKey "Boot Banner" #define kWaitForKeypressKey "Wait" /* AsereBLN: added the other keys */ -#define kUseAtiROM "UseAtiROM" /* ati.c */ -#define kWake "Wake" /* boot.c */ -#define kForceWake "ForceWake" /* boot.c */ -#define kWakeImage "WakeImage" /* boot.c */ +#define kUseAtiROM "UseAtiROM" /* ati.c */ +#define kWake "Wake" /* boot.c */ +#define kForceWake "ForceWake" /* boot.c */ +#define kWakeImage "WakeImage" /* boot.c */ #define kProductVersion "ProductVersion" /* boot.c */ -#define karch "arch" /* boot.c */ -#define kDSDT "DSDT" /* dsdt_patcher.c */ -#define kDropSSDT "DropSSDT" /* dsdt_patcher.c */ -#define kRestartFix "RestartFix" /* dsdt_patcher.c */ -#define kSMBIOS "SMBIOS" /* fake_efi.c */ -#define kSystemID "SystemId" /* fake_efi.c */ -#define kSystemType "SystemType" /* fake_efi.c */ +#define karch "arch" /* boot.c */ +#define kDSDT "DSDT" /* acpi_patcher.c */ +#define kDropSSDT "DropSSDT" /* acpi_patcher.c */ +#define kRestartFix "RestartFix" /* acpi_patcher.c */ +#define kRestartFix "RestartFix" /* acpi_patcher.c */ +#define kGeneratePStates "GeneratePStates" /* acpi_patcher.c */ +#define kGenerateCStates "GenerateCStates" /* acpi_patcher.c */ +#define kEnableC4States "EnableC4State" /* acpi_patcher.c */ +#define kDeviceProperties "device-properties" /* device_inject.c */ +#define kHidePartition "Hide Partition" /* disk.c */ +#define kRenamePartition "Rename Partition" /* disk.c */ +#define kSMBIOSKey "SMBIOS" /* fake_efi.c */ +#define kSystemID "SystemId" /* fake_efi.c */ +#define kSystemType "SystemType" /* fake_efi.c */ #define kUseNvidiaROM "UseNvidiaROM" /* nvidia.c */ -#define kVBIOS "VBIOS" /* nvidia.c */ -#define kPCIRootUID "PCIRootUID" /* pci_root.c */ +#define kVBIOS "VBIOS" /* nvidia.c */ +#define kPCIRootUID "PCIRootUID" /* pci_root.c */ #define kEthernetBuiltIn "EthernetBuiltIn" /* pci_setup.c */ #define kGraphicsEnabler "GraphicsEnabler" /* pci_setup.c */ -#define kUSBBusFix "USBBusFix" /* pci_setup.c */ -#define kEHCIacquire "EHCIacquire" /* pci_setup.c */ -#define kUHCIreset "UHCIreset" /* usb.c */ -#define kForceHPET "ForceHPET" /* usb.c */ -#define kLegacyOff "USBLegacyOff" /* usb.c */ +#define kForceHPET "ForceHPET" /* pci_setup.c */ +#define kUseMemDetect "UseMemDetect" /* platform.c */ #define kSMBIOSdefaults "SMBIOSdefaults" /* smbios_patcher.c */ -#define kEHCIhard "EHCIhard" /* usb.c */ +#define kUSBBusFix "USBBusFix" /* usb.c */ +#define kEHCIacquire "EHCIacquire" /* usb.c */ +#define kUHCIreset "UHCIreset" /* usb.c */ +#define kLegacyOff "USBLegacyOff" /* usb.c */ +#define kEHCIhard "EHCIhard" /* usb.c */ #define kDefaultPartition "Default Partition" /* sys.c */ -#define kDeviceProperties "device-properties" /* device_inject.c */ -#define kHidePartition "Hide Partition" /* disk.c */ -#define kRenamePartition "Rename Partition" /* disk.c */ -#define kUseMemDetect "UseMemDetect" /* platform.c */ -#define kRestartFix "RestartFix" /* dsdt_patcher.c */ +#define kMD0Image "md0" /* ramdisk.h */ #define kScreenWidth "ScreenWidth" /* edid.h */ #define kScreenHeight "ScreenHeight" /* edid.h */ @@ -101,10 +105,9 @@ */ #define kVerboseModeFlag "-v" #define kSafeModeFlag "-x" -#define kOldSafeModeFlag "-f" +#define kIgnoreCachesFlag "-f" #define kIgnoreBootFileFlag "-F" #define kSingleUserModeFlag "-s" -#define k32BitModeFlag "-x32" /* * Booter behavior control @@ -147,7 +150,6 @@ */ extern int usb_loop(); - /* * graphics.c */ @@ -176,6 +178,7 @@ extern void drawPreview(void *src, uint8_t * saveunder); extern int getVideoMode(void); extern void loadImageScale (void *input, int iw, int ih, int ip, void *output, int ow, int oh, int op, int or); + /* * drivers.c */ Index: branches/meklort/i386/boot2/drivers.c =================================================================== --- branches/meklort/i386/boot2/drivers.c (revision 504) +++ branches/meklort/i386/boot2/drivers.c (revision 505) @@ -191,19 +191,25 @@ { verbose("Loading recovery extensions\n"); - const char* recoveryFolder; - int len; - if (getValueForKey(kWakeImage, &recoveryFolder, &len, &bootInfo->bootConfig)) - { - sprintf(dirSpecExtra, "/Extra/%s/", &recoveryFolder); - if(FileLoadDrivers(dirSpecExtra, 0) != 0) - { - verbose("Unable to locate recovery extensions\n"); - } - } - else { - verbose("Unable to locate recovery extensions\n"); - } + // Next try to load Extra extensions from the selected root partition. + strcpy(dirSpecExtra, "/Extra/"); + if (FileLoadDrivers(dirSpecExtra, 0) != 0) + { + // If failed, then try to load Extra extensions from the boot partition + // in case we have a separate booter partition or a bt(0,0) aliased ramdisk. + if ( !(gBIOSBootVolume->biosdev == gBootVolume->biosdev && gBIOSBootVolume->part_no == gBootVolume->part_no) + || (gRAMDiskVolume && gRAMDiskBTAliased) ) + { + // Next try a specfic OS version folder ie 10.5 + sprintf(dirSpecExtra, "bt(0,0)/Extra/%s/", &gMacOSVersion); + if (FileLoadDrivers(dirSpecExtra, 0) != 0) + { + // Next we'll try the base + strcpy(dirSpecExtra, "bt(0,0)/Extra/"); + FileLoadDrivers(dirSpecExtra, 0); + } + } + } } else @@ -237,14 +243,17 @@ } // Also try to load Extensions from boot helper partitions. - strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/"); - if (FileLoadDrivers(dirSpecExtra, 0) != 0) + if (gBootVolume->flags & kBVFlagBooter) { - strcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/"); + strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/"); if (FileLoadDrivers(dirSpecExtra, 0) != 0) { - strcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/"); - FileLoadDrivers(dirSpecExtra, 0); + strcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/"); + if (FileLoadDrivers(dirSpecExtra, 0) != 0) + { + strcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/"); + FileLoadDrivers(dirSpecExtra, 0); + } } } @@ -279,49 +288,51 @@ } //========================================================================== +// FileLoadMKext + +static long +FileLoadMKext( const char * dirSpec, const char * extDirSpec ) +{ + long ret, flags, time, time2; + char altDirSpec[512]; + + sprintf (altDirSpec, "%s%s", dirSpec, extDirSpec); + ret = GetFileInfo(altDirSpec, "Extensions.mkext", &flags, &time); + if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat)) + { + ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2); + if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) || + (((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1)))) + { + sprintf(gDriverSpec, "%sExtensions.mkext", altDirSpec); + verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec); + if (LoadDriverMKext(gDriverSpec) == 0) return 0; + } + } + return -1; +} + +//========================================================================== // FileLoadDrivers static long FileLoadDrivers( char * dirSpec, long plugin ) { - long ret, length, index, flags, time, bundleType; + long ret, length, flags, time, bundleType; + long long index; long result = -1; const char * name; if ( !plugin ) { - long time2; + // First try 10.6's path for loading Extensions.mkext. + if (FileLoadMKext(dirSpec, "Caches/com.apple.kext.caches/Startup/") == 0) + return 0; - // TODO: refactor this part of code. - char altDirSpec[4500]; - sprintf (altDirSpec,"%sCaches/com.apple.kext.caches/Startup/",dirSpec); - ret = GetFileInfo(altDirSpec, "Extensions.mkext", &flags, &time); - if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat)) - { - ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2); - if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) || - (((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1)))) - { - sprintf(gDriverSpec, "%sExtensions.mkext", altDirSpec); - verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec); - if (LoadDriverMKext(gDriverSpec) == 0) return 0; - } - } - // + // Next try the legacy path. + else if (FileLoadMKext(dirSpec, "") == 0) + return 0; - ret = GetFileInfo(dirSpec, "Extensions.mkext", &flags, &time); - if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat)) - { - ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2); - if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) || - (((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1)))) - { - sprintf(gDriverSpec, "%sExtensions.mkext", dirSpec); - verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec); - if (LoadDriverMKext(gDriverSpec) == 0) return 0; - } - } - strcat(dirSpec, "Extensions"); } @@ -356,7 +367,7 @@ result = ret; if (!plugin) - result = FileLoadDrivers(gDriverSpec, 1); + FileLoadDrivers(gDriverSpec, 1); } return result; Index: branches/meklort/i386/boot2/gui.c =================================================================== --- branches/meklort/i386/boot2/gui.c (revision 504) +++ branches/meklort/i386/boot2/gui.c (revision 505) @@ -13,19 +13,16 @@ #include "vers.h" #include "edid.h" +#define IMG_REQUIRED -1 #define THEME_NAME_DEFAULT "Default" static const char *theme_name = THEME_NAME_DEFAULT; #ifdef EMBED_THEME #include "art.h" -#define LOADPNG(img) \ -if (loadThemeImage(#img) != 0) \ - if (loadEmbeddedThemeImage(#img, __## img ##_png, __## img ##_png_len) != 0) \ - return 1; -#else -#define LOADPNG(img) if (loadThemeImage(#img) != 0) { return 1; } #endif +#define LOADPNG(img, alt_img) if (loadThemeImage(#img, alt_img) != 0) { return 1; } + #define MIN(x, y) ((x) < (y) ? (x) : (y)) #define MAX(x, y) ((x) > (y) ? (x) : (y)) @@ -33,7 +30,7 @@ #define vram VIDEO(baseAddr) -int lasttime=0; // we need this for animating maybe +int lasttime = 0; // we need this for animating maybe extern int gDeviceCount; @@ -42,77 +39,101 @@ * ATTENTION: the enum and the following array images[] MUST match !!! */ enum { - iBackground = 0, - iLogo, + iBackground = 0, + iLogo, - iDeviceGeneric, - iDeviceHFS, - iDeviceEXT3, - iDeviceFAT16, - iDeviceFAT32, - iDeviceNTFS, - iDeviceCDROM, - iSelection, - iDeviceScrollPrev, - iDeviceScrollNext, + iDeviceGeneric, + iDeviceGeneric_o, + iDeviceHFS, + iDeviceHFS_o, + iDeviceHFSRAID, + iDeviceHFSRAID_o, + iDeviceEXT3, + iDeviceEXT3_o, + iDeviceFAT, + iDeviceFAT_o, + iDeviceFAT16, + iDeviceFAT16_o, + iDeviceFAT32, + iDeviceFAT32_o, + iDeviceNTFS, + iDeviceNTFS_o, + iDeviceCDROM, + iDeviceCDROM_o, - iMenuBoot, - iMenuVerbose, - iMenuIgnoreCaches, - iMenuSingleUser, - iMenuMemoryInfo, - iMenuVideoInfo, - iMenuHelp, - iMenuVerboseDisabled, - iMenuIgnoreCachesDisabled, - iMenuSingleUserDisabled, - iMenuSelection, + iSelection, + iDeviceScrollPrev, + iDeviceScrollNext, - iProgressBar, - iProgressBarBackground, + iMenuBoot, + iMenuVerbose, + iMenuIgnoreCaches, + iMenuSingleUser, + iMenuMemoryInfo, + iMenuVideoInfo, + iMenuHelp, + iMenuVerboseDisabled, + iMenuIgnoreCachesDisabled, + iMenuSingleUserDisabled, + iMenuSelection, - iTextScrollPrev, - iTextScrollNext, + iProgressBar, + iProgressBarBackground, - iFontConsole, - iFontSmall, + iTextScrollPrev, + iTextScrollNext, + + iFontConsole, + iFontSmall, }; image_t images[] = { - {.name = "background", .image = NULL}, - {.name = "logo", .image = NULL}, + {.name = "background", .image = NULL}, + {.name = "logo", .image = NULL}, + + {.name = "device_generic", .image = NULL}, + {.name = "device_generic_o", .image = NULL}, + {.name = "device_hfsplus", .image = NULL}, + {.name = "device_hfsplus_o", .image = NULL}, + {.name = "device_hfsraid", .image = NULL}, + {.name = "device_hfsraid_o", .image = NULL}, + {.name = "device_ext3", .image = NULL}, + {.name = "device_ext3_o", .image = NULL}, + {.name = "device_fat", .image = NULL}, + {.name = "device_fat_o", .image = NULL}, + {.name = "device_fat16", .image = NULL}, + {.name = "device_fat16_o", .image = NULL}, + {.name = "device_fat32", .image = NULL}, + {.name = "device_fat32_o", .image = NULL}, + {.name = "device_ntfs", .image = NULL}, + {.name = "device_ntfs_o", .image = NULL}, + {.name = "device_cdrom", .image = NULL}, + {.name = "device_cdrom_o", .image = NULL}, - {.name = "device_generic", .image = NULL}, - {.name = "device_hfsplus", .image = NULL}, - {.name = "device_ext3", .image = NULL}, - {.name = "device_fat16", .image = NULL}, - {.name = "device_fat32", .image = NULL}, - {.name = "device_ntfs", .image = NULL}, - {.name = "device_cdrom", .image = NULL}, - {.name = "device_selection", .image = NULL}, - {.name = "device_scroll_prev", .image = NULL}, - {.name = "device_scroll_next", .image = NULL}, - - {.name = "menu_boot", .image = NULL}, - {.name = "menu_verbose", .image = NULL}, - {.name = "menu_ignore_caches", .image = NULL}, - {.name = "menu_single_user", .image = NULL}, - {.name = "menu_memory_info", .image = NULL}, - {.name = "menu_video_info", .image = NULL}, - {.name = "menu_help", .image = NULL}, - {.name = "menu_verbose_disabled", .image = NULL}, - {.name = "menu_ignore_caches_disabled", .image = NULL}, - {.name = "menu_single_user_disabled", .image = NULL}, - {.name = "menu_selection", .image = NULL}, - - {.name = "progress_bar", .image = NULL}, - {.name = "progress_bar_background", .image = NULL}, - - {.name = "text_scroll_prev", .image = NULL}, - {.name = "text_scroll_next", .image = NULL}, - - {.name = "font_console", .image = NULL}, - {.name = "font_small", .image = NULL}, + {.name = "device_selection", .image = NULL}, + {.name = "device_scroll_prev", .image = NULL}, + {.name = "device_scroll_next", .image = NULL}, + + {.name = "menu_boot", .image = NULL}, + {.name = "menu_verbose", .image = NULL}, + {.name = "menu_ignore_caches", .image = NULL}, + {.name = "menu_single_user", .image = NULL}, + {.name = "menu_memory_info", .image = NULL}, + {.name = "menu_video_info", .image = NULL}, + {.name = "menu_help", .image = NULL}, + {.name = "menu_verbose_disabled", .image = NULL}, + {.name = "menu_ignore_caches_disabled", .image = NULL}, + {.name = "menu_single_user_disabled", .image = NULL}, + {.name = "menu_selection", .image = NULL}, + + {.name = "progress_bar", .image = NULL}, + {.name = "progress_bar_background", .image = NULL}, + + {.name = "text_scroll_prev", .image = NULL}, + {.name = "text_scroll_next", .image = NULL}, + + {.name = "font_console", .image = NULL}, + {.name = "font_small", .image = NULL}, }; int imageCnt = 0; @@ -148,41 +169,68 @@ static bool infoMenuNativeBoot = false; -static unsigned long screen_params[4] = {0, 0, 0, 0}; // here we store the used screen resolution +static unsigned long screen_params[4] = {DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT, 32, 0}; // here we store the used screen resolution +static int getImageIndexByName(const char *name) +{ + int i; + for (i = 0; i < sizeof(images) / sizeof(images[0]); i++) + { + if (strcmp(name, images[i].name) == 0) + return i; // found the name + } + return -1; +} + #ifdef EMBED_THEME -static int loadEmbeddedThemeImage(const char *image, unsigned char *image_data, unsigned int image_size) +static int getEmbeddedImageIndexByName(const char *name) { - int i; - uint16_t width; - uint16_t height; - uint8_t *imagedata; - - for (i=0; i < sizeof(images) / sizeof(images[0]); i++) { - if (strcmp(image, images[i].name) == 0) { - if (images[i].image == NULL) { - images[i].image = malloc(sizeof(pixmap_t)); + int upperLimit = sizeof(embeddedImages) / sizeof(embeddedImages[0]) - 1; + int lowerLimit = 0; + int compareIndex = (upperLimit - lowerLimit) >> 1; // Midpoint + int result; + + // NOTE: This algorithm assumes that the embeddedImages is sorted. + // This is currently done using the make file. If the array is every + // manualy generated, this *will* fail to work properly. + while((result = strcmp(name, embeddedImages[compareIndex].name)) != 0) + { + if(result > 0) // We need to search a HIGHER index + { + if(compareIndex != lowerLimit) + { + lowerLimit = compareIndex; } - width = 0; - height = 0; - imagedata = NULL; - if ((loadEmbeddedPngImage(image_data, image_size, &width, &height, &imagedata)) != 0) { - return 1; + else + { + return -1; } - images[i].image->width = width; - images[i].image->height = height; - images[i].image->pixels = (pixel_t *)imagedata; - flipRB(images[i].image); - return 0; + compareIndex = (upperLimit + lowerLimit + 1) >> 1; // Midpoint, round up } + else // We Need to search a LOWER index + { + if(compareIndex != upperLimit) + { + upperLimit = compareIndex; + } + else + { + return -1; + } + compareIndex = (upperLimit + lowerLimit) >> 1; // Midpoint, round down + } } - return 1; + return compareIndex; } #endif -static int loadThemeImage(const char *image) + +static int loadThemeImage(const char *image, int alt_image) { char dirspec[256]; - int i; + int i; +#ifdef EMBED_THEME + int e; +#endif uint16_t width; uint16_t height; uint8_t *imagedata; @@ -190,70 +238,114 @@ if ((strlen(image) + strlen(theme_name) + 20 ) > sizeof(dirspec)) { return 1; } - for (i=0; i < sizeof(images) / sizeof(images[0]); i++) { - if (strcmp(image, images[i].name) == 0) { - if (images[i].image == NULL) { - images[i].image = malloc(sizeof(pixmap_t)); - } - sprintf(dirspec,"/Extra/Themes/%s/%s.png", theme_name, image); - width = 0; - height = 0; - imagedata = NULL; - if ((loadPngImage(dirspec, &width, &height, &imagedata)) != 0) { + + if ((i = getImageIndexByName(image)) >= 0) + { + if (images[i].image == NULL) { + images[i].image = malloc(sizeof(pixmap_t)); + } + sprintf(dirspec, "/Extra/Themes/%s/%s.png", theme_name, image); + width = 0; + height = 0; + imagedata = NULL; + if ((loadPngImage(dirspec, &width, &height, &imagedata)) == 0) + { + images[i].image->width = width; + images[i].image->height = height; + images[i].image->pixels = (pixel_t *)imagedata; + flipRB(images[i].image); + return 0; + } +#ifdef EMBED_THEME + else if ((e = getEmbeddedImageIndexByName(image)) >= 0) + { + unsigned char *embed_data; + unsigned int embed_size; + embed_data = embeddedImages[e].pngdata; + embed_size = *embeddedImages[e].length; + + if (loadEmbeddedPngImage(embed_data, embed_size, &width, &height, &imagedata) == 0) + { + images[i].image->width = width; + images[i].image->height = height; + images[i].image->pixels = (pixel_t *)imagedata; + flipRB(images[i].image); + return 0; + } + + return 0; + } +#endif + else if (alt_image != IMG_REQUIRED && images[alt_image].image->pixels != NULL) + { + // Using the passed alternate image for non-mandatory images. + // We don't clone the already existing pixmap, but using its properties instead! + images[i].image->width = images[alt_image].image->width; + images[i].image->height = images[alt_image].image->height; + images[i].image->pixels = images[alt_image].image->pixels; + return 0; + } + else + { #ifndef EMBED_THEME - printf("ERROR: GUI: could not open '%s/%s.png'!\n", theme_name, image); - sleep(2); + printf("ERROR: GUI: could not open '%s/%s.png'!\n", theme_name, image); + sleep(2); #endif - return 1; - } - images[i].image->width = width; - images[i].image->height = height; - images[i].image->pixels = (pixel_t *)imagedata; - flipRB(images[i].image); - return 0; - } - } + return 1; + } + } return 1; } - static int loadGraphics(void) { - LOADPNG(background); - LOADPNG(logo); + LOADPNG(background, IMG_REQUIRED); + LOADPNG(logo, IMG_REQUIRED); - LOADPNG(device_generic); - LOADPNG(device_hfsplus); - LOADPNG(device_ext3); - LOADPNG(device_fat16); - LOADPNG(device_fat32); - LOADPNG(device_ntfs); - LOADPNG(device_cdrom); - LOADPNG(device_selection); - LOADPNG(device_scroll_prev); - LOADPNG(device_scroll_next); + LOADPNG(device_generic, IMG_REQUIRED); + LOADPNG(device_generic_o, iDeviceGeneric); + LOADPNG(device_hfsplus, iDeviceGeneric); + LOADPNG(device_hfsplus_o, iDeviceHFS); + LOADPNG(device_hfsraid, iDeviceGeneric); + LOADPNG(device_hfsraid_o, iDeviceHFSRAID); + LOADPNG(device_ext3, iDeviceGeneric); + LOADPNG(device_ext3_o, iDeviceEXT3); + LOADPNG(device_fat, iDeviceGeneric); + LOADPNG(device_fat_o, iDeviceFAT); + LOADPNG(device_fat16, iDeviceFAT); + LOADPNG(device_fat16_o, iDeviceFAT_o); + LOADPNG(device_fat32, iDeviceFAT); + LOADPNG(device_fat32_o, iDeviceFAT_o); + LOADPNG(device_ntfs, iDeviceGeneric); + LOADPNG(device_ntfs_o, iDeviceNTFS); + LOADPNG(device_cdrom, iDeviceGeneric); + LOADPNG(device_cdrom_o, iDeviceCDROM); - LOADPNG(menu_boot); - LOADPNG(menu_verbose); - LOADPNG(menu_ignore_caches); - LOADPNG(menu_single_user); - LOADPNG(menu_memory_info); - LOADPNG(menu_video_info); - LOADPNG(menu_help); - LOADPNG(menu_verbose_disabled); - LOADPNG(menu_ignore_caches_disabled); - LOADPNG(menu_single_user_disabled); - LOADPNG(menu_selection); + LOADPNG(device_selection, IMG_REQUIRED); + LOADPNG(device_scroll_prev, IMG_REQUIRED); + LOADPNG(device_scroll_next, IMG_REQUIRED); - LOADPNG(progress_bar); - LOADPNG(progress_bar_background); + LOADPNG(menu_boot, IMG_REQUIRED); + LOADPNG(menu_verbose, IMG_REQUIRED); + LOADPNG(menu_ignore_caches, IMG_REQUIRED); + LOADPNG(menu_single_user, IMG_REQUIRED); + LOADPNG(menu_memory_info, IMG_REQUIRED); + LOADPNG(menu_video_info, IMG_REQUIRED); + LOADPNG(menu_help, IMG_REQUIRED); + LOADPNG(menu_verbose_disabled, IMG_REQUIRED); + LOADPNG(menu_ignore_caches_disabled, IMG_REQUIRED); + LOADPNG(menu_single_user_disabled, IMG_REQUIRED); + LOADPNG(menu_selection, IMG_REQUIRED); - LOADPNG(text_scroll_prev); - LOADPNG(text_scroll_next); + LOADPNG(progress_bar, IMG_REQUIRED); + LOADPNG(progress_bar_background, IMG_REQUIRED); - LOADPNG(font_console); - LOADPNG(font_small); + LOADPNG(text_scroll_prev, IMG_REQUIRED); + LOADPNG(text_scroll_next, IMG_REQUIRED); + LOADPNG(font_console, IMG_REQUIRED); + LOADPNG(font_small, IMG_REQUIRED); + initFont( &font_console, &images[iFontConsole]); initFont( &font_small, &images[iFontSmall]); @@ -326,6 +418,18 @@ return 0; } +int freeWindowBuffer( window_t *window ) +{ + if (window->pixmap && window->pixmap->pixels) + { + free(window->pixmap->pixels); + free(window->pixmap); + return 0; + } + + return 1; +} + void fillPixmapWithColor(pixmap_t *pm, uint32_t color) { int x,y; @@ -348,21 +452,87 @@ blend( images[iBackground].image, gui.screen.pixmap, gui.background.pos ); // draw logo.png into background buffer - blend( images[iLogo].image, gui.screen.pixmap, gui.logo.pos); + if (gui.logo.draw) + { + blend( images[iLogo].image, gui.screen.pixmap, gui.logo.pos); + } memcpy( gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4 ); } -void loadThemeValues(config_file_t *theme, bool overide) +void setupDeviceList(config_file_t *theme) { - unsigned int screen_width = gui.screen.width; - unsigned int screen_height = gui.screen.height; unsigned int pixel; int alpha; // transparency level 0 (obligue) - 255 (transparent) uint32_t color; // color value formatted RRGGBB int val, len; const char *string; + if(getIntForKey("devices_max_visible", &val, theme )) + gui.maxdevices = MIN( val, gDeviceCount ); + + if(getIntForKey("devices_iconspacing", &val, theme )) + gui.devicelist.iconspacing = val; + + // check layout for horizontal or vertical + gui.layout = HorizontalLayout; + if(getValueForKey( "devices_layout", &string, &len, theme)) { + if (!strcmp (string, "vertical")) { + gui.layout = VerticalLayout; + } + } + + switch (gui.layout) { + case VerticalLayout: + gui.devicelist.height = ((images[iSelection].image->height + font_console.chars[0]->height + gui.devicelist.iconspacing) * MIN(gui.maxdevices, gDeviceCount) + (images[iDeviceScrollPrev].image->height + images[iDeviceScrollNext].image->height) + gui.devicelist.iconspacing); + gui.devicelist.width = (images[iSelection].image->width + gui.devicelist.iconspacing); + + if(getDimensionForKey("devices_pos_x", &pixel, theme, gui.screen.width , images[iSelection].image->width ) ) + gui.devicelist.pos.x = pixel; + + if(getDimensionForKey("devices_pos_y", &pixel, theme, gui.screen.height , gui.devicelist.height ) ) + gui.devicelist.pos.y = pixel; + break; + + case HorizontalLayout: + default: + gui.devicelist.width = ((images[iSelection].image->width + gui.devicelist.iconspacing) * MIN(gui.maxdevices, gDeviceCount) + (images[iDeviceScrollPrev].image->width + images[iDeviceScrollNext].image->width) + gui.devicelist.iconspacing); + gui.devicelist.height = (images[iSelection].image->height + font_console.chars[0]->height + gui.devicelist.iconspacing); + + if(getDimensionForKey("devices_pos_x", &pixel, theme, gui.screen.width , gui.devicelist.width ) ) + gui.devicelist.pos.x = pixel; + else + gui.devicelist.pos.x = ( gui.screen.width - gui.devicelist.width ) / 2; + + if(getDimensionForKey("devices_pos_y", &pixel, theme, gui.screen.height , images[iSelection].image->height ) ) + gui.devicelist.pos.y = pixel; + else + gui.devicelist.pos.y = ( gui.screen.height - gui.devicelist.height ) / 2; + break; + } + + if(getColorForKey("devices_bgcolor", &color, theme)) + gui.devicelist.bgcolor = (color & 0x00FFFFFF); + + if(getIntForKey("devices_transparency", &alpha, theme)) + gui.devicelist.bgcolor = gui.devicelist.bgcolor | (( 255 - ( alpha & 0xFF) ) << 24); + + if (gui.devicelist.pixmap) + { + freeWindowBuffer(&gui.devicelist); + createWindowBuffer(&gui.devicelist); + } +} + +void loadThemeValues(config_file_t *theme) +{ + unsigned int screen_width = gui.screen.width; + unsigned int screen_height = gui.screen.height; + unsigned int pixel; + int alpha; // transparency level 0 (obligue) - 255 (transparent) + uint32_t color; // color value formatted RRGGBB + int val; + /* * Parse screen parameters */ @@ -411,58 +581,11 @@ if(getDimensionForKey("countdown_pos_y", &pixel, theme, screen_height , 0 ) ) gui.countdown.pos.y = pixel; - /* + /* * Parse devicelist parameters */ - if(getIntForKey("devices_max_visible", &val, theme )) - gui.maxdevices = MIN( val, gDeviceCount ); + setupDeviceList(theme); - if(getIntForKey("devices_iconspacing", &val, theme )) - gui.devicelist.iconspacing = val; - - // check layout for horizontal or vertical - gui.layout = HorizontalLayout; - if(getValueForKey( "devices_layout", &string, &len, theme)) { - if (!strcmp (string, "vertical")) { - gui.layout = VerticalLayout; - } - } - - switch (gui.layout) { - case VerticalLayout: - gui.devicelist.height = ((images[iSelection].image->height + font_console.chars[0]->height + gui.devicelist.iconspacing) * MIN(gui.maxdevices, gDeviceCount) + (images[iDeviceScrollPrev].image->height + images[iDeviceScrollNext].image->height) + gui.devicelist.iconspacing); - gui.devicelist.width = (images[iSelection].image->width + gui.devicelist.iconspacing); - - if(getDimensionForKey("devices_pos_x", &pixel, theme, gui.screen.width , images[iSelection].image->width ) ) - gui.devicelist.pos.x = pixel; - - if(getDimensionForKey("devices_pos_y", &pixel, theme, gui.screen.height , gui.devicelist.height ) ) - gui.devicelist.pos.y = pixel; - break; - - case HorizontalLayout: - default: - gui.devicelist.width = ((images[iSelection].image->width + gui.devicelist.iconspacing) * MIN(gui.maxdevices, gDeviceCount) + (images[iDeviceScrollPrev].image->width + images[iDeviceScrollNext].image->width) + gui.devicelist.iconspacing); - gui.devicelist.height = (images[iSelection].image->height + font_console.chars[0]->height + gui.devicelist.iconspacing); - - if(getDimensionForKey("devices_pos_x", &pixel, theme, gui.screen.width , gui.devicelist.width ) ) - gui.devicelist.pos.x = pixel; - else - gui.devicelist.pos.x = ( gui.screen.width - gui.devicelist.width ) / 2; - - if(getDimensionForKey("devices_pos_y", &pixel, theme, gui.screen.height , images[iSelection].image->height ) ) - gui.devicelist.pos.y = pixel; - else - gui.devicelist.pos.y = ( gui.screen.height - gui.devicelist.height ) / 2; - break; - } - - if(getColorForKey("devices_bgcolor", &color, theme)) - gui.devicelist.bgcolor = (color & 0x00FFFFFF); - - if(getIntForKey("devices_transparency", &alpha, theme)) - gui.devicelist.bgcolor = gui.devicelist.bgcolor | (( 255 - ( alpha & 0xFF) ) << 24); - /* * Parse infobox parameters */ @@ -558,14 +681,6 @@ int initGUI(void) { //int val; -#ifdef EMBED_THEME - config_file_t *config; - - config = &bootInfo->themeConfig; - if (ParseXMLFile((char *)__theme_plist, &config->dictionary) != 0) { - return 1; - } -#else int len; char dirspec[256]; @@ -575,18 +690,25 @@ } sprintf(dirspec, "/Extra/Themes/%s/theme.plist", theme_name); if (loadConfigFile(dirspec, &bootInfo->themeConfig) != 0) { +#ifdef EMBED_THEME + config_file_t *config; + + config = &bootInfo->themeConfig; + if (ParseXMLFile((char *)__theme_plist, &config->dictionary) != 0) { + return 1; + } +#else return 1; +#endif } -#endif /* // parse display size parameters - if (getIntForKey("screen_width", &val, &bootInfo->themeConfig)) { + if (getIntForKey("screen_width", &val, &bootInfo->themeConfig) && val > 0) { screen_params[0] = val; } - if (getIntForKey("screen_height", &val, &bootInfo->themeConfig)) { + if (getIntForKey("screen_height", &val, &bootInfo->themeConfig) && val > 0) { screen_params[1] = val; } - screen_params[2] = 32; */ getResolution(&screen_params[0], &screen_params[1], &screen_params[2]); @@ -603,7 +725,7 @@ // load graphics otherwise fail and return if (loadGraphics() == 0) { - loadThemeValues(&bootInfo->themeConfig, true); + loadThemeValues(&bootInfo->themeConfig); colorFont(&font_small, gui.screen.font_small_color); colorFont(&font_console, gui.screen.font_console_color); @@ -613,7 +735,8 @@ if (createWindowBuffer(&gui.devicelist) == 0) { if (createWindowBuffer(&gui.bootprompt) == 0) { if (createWindowBuffer(&gui.infobox) == 0) { - if (createWindowBuffer(&gui.menu) == 0) { + if (createWindowBuffer(&gui.menu) == 0) { + gui.logo.draw = true; drawBackground(); // lets copy the screen into the back buffer memcpy( gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4 ); @@ -630,10 +753,10 @@ return 1; } -void drawDeviceIcon(BVRef device, pixmap_t *buffer, position_t p) +void drawDeviceIcon(BVRef device, pixmap_t *buffer, position_t p, bool isSelected) { int devicetype; - + if( diskIsCDROM(device) ) devicetype = iDeviceCDROM; // Use CDROM icon else @@ -642,33 +765,39 @@ { case kPartitionTypeHFS: - // TODO: add apple raid icon choices - - devicetype = iDeviceHFS; // Use HFS icon + // Use HFS or HFSRAID icon depending on bvr flags. + devicetype = (device->flags & kBVFlagBooter) ? iDeviceHFSRAID : iDeviceHFS; break; - + case kPartitionTypeHPFS: devicetype = iDeviceNTFS; // Use HPFS / NTFS icon break; - + case kPartitionTypeFAT16: devicetype = iDeviceFAT16; // Use FAT16 icon break; - + case kPartitionTypeFAT32: devicetype = iDeviceFAT32; // Use FAT32 icon break; - + case kPartitionTypeEXT3: devicetype = iDeviceEXT3; // Use EXT2/3 icon break; - + default: devicetype = iDeviceGeneric; // Use Generic icon break; } } + // Draw the selection image and use the next (device_*_o) image for the selected item. + if (isSelected) + { + blend(images[iSelection].image, buffer, centeredAt(images[iSelection].image, p)); + devicetype++; + } + // draw icon blend( images[devicetype].image, buffer, centeredAt( images[devicetype].image, p )); @@ -718,45 +847,46 @@ } // draw visible device icons - for ( i=0; i < gui.maxdevices; i++ ) + for (i = 0; i < gui.maxdevices; i++) { - BVRef param = menuItems[start+i].param; + BVRef param = menuItems[start + i].param; - if((start+i) == selection) + bool isSelected = ((start + i) == selection) ? true : false; + if (isSelected) { - if(param->flags & kBVFlagNativeBoot) - infoMenuNativeBoot = true; - else - { - infoMenuNativeBoot = false; - if(infoMenuSelection >= INFOMENU_NATIVEBOOT_START && infoMenuSelection <= INFOMENU_NATIVEBOOT_END) - infoMenuSelection = 0; - } + if (param->flags & kBVFlagNativeBoot) + { + infoMenuNativeBoot = true; + } + else + { + infoMenuNativeBoot = false; + if(infoMenuSelection >= INFOMENU_NATIVEBOOT_START && infoMenuSelection <= INFOMENU_NATIVEBOOT_END) + infoMenuSelection = 0; + } if(gui.menu.draw) drawInfoMenuItems(); - blend( images[iSelection].image, gui.devicelist.pixmap, centeredAt( images[iSelection].image, p ) ); - #if DEBUG - gui.debug.cursor = pos( 10, 100); - dprintf( &gui.screen, "label %s\n", param->label ); - dprintf( &gui.screen, "biosdev 0x%x\n", param->biosdev ); - dprintf(&gui.screen, "width %d\n", gui.screen.width); - dprintf(&gui.screen, "height %d\n", gui.screen.height); - dprintf( &gui.screen, "type 0x%x\n", param->type ); - dprintf( &gui.screen, "flags 0x%x\n", param->flags ); - dprintf( &gui.screen, "part_no %d\n", param->part_no ); - dprintf( &gui.screen, "part_boff 0x%x\n", param->part_boff ); - dprintf( &gui.screen, "part_type 0x%x\n", param->part_type ); - dprintf( &gui.screen, "bps 0x%x\n", param->bps ); - dprintf( &gui.screen, "name %s\n", param->name ); - dprintf( &gui.screen, "type_name %s\n", param->type_name ); - dprintf( &gui.screen, "modtime %d\n", param->modTime ); + gui.debug.cursor = pos( 10, 100); + dprintf( &gui.screen, "label %s\n", param->label ); + dprintf( &gui.screen, "biosdev 0x%x\n", param->biosdev ); + dprintf(&gui.screen, "width %d\n", gui.screen.width); + dprintf(&gui.screen, "height %d\n", gui.screen.height); + dprintf( &gui.screen, "type 0x%x\n", param->type ); + dprintf( &gui.screen, "flags 0x%x\n", param->flags ); + dprintf( &gui.screen, "part_no %d\n", param->part_no ); + dprintf( &gui.screen, "part_boff 0x%x\n", param->part_boff ); + dprintf( &gui.screen, "part_type 0x%x\n", param->part_type ); + dprintf( &gui.screen, "bps 0x%x\n", param->bps ); + dprintf( &gui.screen, "name %s\n", param->name ); + dprintf( &gui.screen, "type_name %s\n", param->type_name ); + dprintf( &gui.screen, "modtime %d\n", param->modTime ); #endif } - drawDeviceIcon( param, gui.devicelist.pixmap, p ); + drawDeviceIcon( param, gui.devicelist.pixmap, p, isSelected); if (gui.layout == HorizontalLayout) { @@ -1693,6 +1823,7 @@ //int pos; int length; const char *dummyVal; + int oldScreenWidth, oldScreenHeight; bool legacy_logo; uint16_t x, y; @@ -1704,21 +1835,23 @@ /* // parse screen size parameters - if (getIntForKey("boot_width", &pos, &bootInfo->themeConfig)) { + if (getIntForKey("boot_width", &pos, &bootInfo->themeConfig) && pos > 0) { screen_params[0] = pos; } else { screen_params[0] = DEFAULT_SCREEN_WIDTH; } - if (getIntForKey("boot_height", &pos, &bootInfo->themeConfig)) { + if (getIntForKey("boot_height", &pos, &bootInfo->themeConfig) && pos > 0) { screen_params[1] = pos; } else { screen_params[1] = DEFAULT_SCREEN_HEIGHT; } - screen_params[2] = 32; */ getResolution(&screen_params[0], &screen_params[1], &screen_params[2]); + // Save current screen resolution. + oldScreenWidth = gui.screen.width; + oldScreenHeight = gui.screen.height; gui.screen.width = screen_params[0]; gui.screen.height = screen_params[1]; @@ -1726,10 +1859,13 @@ // find best matching vesa mode for our requested width & height getGraphicModeParams(screen_params); - if (bootArgs->Video.v_display == VGA_TEXT_MODE) { + // Set graphics mode if the booter was in text mode or the screen resolution has changed. + if (bootArgs->Video.v_display == VGA_TEXT_MODE + || (screen_params[0] != oldScreenWidth && screen_params[1] != oldScreenHeight) ) + { setVideoMode(GRAPHICS_MODE, 0); } - + if (getValueForKey("-checkers", &dummyVal, &length, &bootInfo->bootConfig)) { drawCheckerBoard(); } else { Index: branches/meklort/i386/boot2/gui.h =================================================================== --- branches/meklort/i386/boot2/gui.h (revision 504) +++ branches/meklort/i386/boot2/gui.h (revision 505) @@ -134,7 +134,8 @@ int initGUI(); void drawBackground(); -void drawDeviceIcon(BVRef device, pixmap_t *buffer, position_t p); +void setupDeviceList(config_file_t *theme); +void drawDeviceIcon(BVRef device, pixmap_t *buffer, position_t p, bool isSelected); void drawDeviceList(int start, int end, int selection); void drawProgressBar(pixmap_t *blendInto, uint16_t width, position_t p, uint8_t progress); Index: branches/meklort/i386/boot2/ramdisk.c =================================================================== --- branches/meklort/i386/boot2/ramdisk.c (revision 504) +++ branches/meklort/i386/boot2/ramdisk.c (revision 505) @@ -16,7 +16,6 @@ bool gRAMDiskBTAliased = false; char gRAMDiskFile[512]; - // Notify OS X that a ramdisk has been setup. XNU with attach this to /dev/md0 void md0Ramdisk() { @@ -36,36 +35,35 @@ if(fh < 0) { sprintf(filename, "rd(0,0)/Extra/%s", override_filename); - if((fh = open(filename, 0)) < 0) + fh = open(filename, 0); + + if(fh < 0) { sprintf(filename, "/Extra/%s", override_filename); fh = open(filename, 0); - } } } - - + if(fh < 0) { - // Fallback to Postboot.img sprintf(filename, "rd(0,0)/Extra/Postboot.img"); fh = open(filename, 0); + if(fh < 0) { sprintf(filename, "/Extra/Postboot.img"); // Check /Extra if not in rd(0,0) fh = open(filename, 0); - } } - + if (fh >= 0) { verbose("Enabling ramdisk %s\n", filename); ramdiskPtr.size = file_size(fh); ramdiskPtr.base = AllocateKernelMemory(ramdiskPtr.size); - + if(ramdiskPtr.size && ramdiskPtr.base) { // Read new ramdisk image contents in kernel memory. @@ -76,232 +74,236 @@ if(node != NULL) { DT__AddProperty(node, "RAMDisk", sizeof(RAMDiskParam), (void*)&ramdiskPtr); - } else { verbose("Unable to notify Mac OS X of the ramdisk %s.\n", filename); } - } - else { + else + { verbose("Unable to read md0 image %s.\n", filename); - } - - } else { + } + } + else + { verbose("md0 image %s is empty.\n", filename); } - - + close(fh); - + } } - void umountRAMDisk() { - if (gRAMDiskMI != NULL) - { - // Release ramdisk BVRef and DiskBVMap. - struct DiskBVMap *oldMap = diskResetBootVolumes(0x100); - CacheReset(); - diskFreeMap(oldMap); - - // Free multiboot info and module structures. - if ((void *)gRAMDiskMI->mi_mods_addr != NULL) free((void *)gRAMDiskMI->mi_mods_addr); - if (gRAMDiskMI != NULL) free(gRAMDiskMI); - - // Reset multiboot structures. - gMI = gRAMDiskMI = NULL; - *gRAMDiskFile = '\0'; + if (gRAMDiskMI != NULL) + { + // Release ramdisk BVRef and DiskBVMap. + struct DiskBVMap *oldMap = diskResetBootVolumes(0x100); + CacheReset(); + diskFreeMap(oldMap); - // Release ramdisk driver hooks. - p_get_ramdisk_info = NULL; - p_ramdiskReadBytes = NULL; - - printf("\nunmounting: done"); - } + // Free multiboot info and module structures. + if ((void *)gRAMDiskMI->mi_mods_addr != NULL) free((void *)gRAMDiskMI->mi_mods_addr); + if (gRAMDiskMI != NULL) free(gRAMDiskMI); + + // Reset multiboot structures. + gMI = gRAMDiskMI = NULL; + *gRAMDiskFile = '\0'; + + // Release ramdisk driver hooks. + p_get_ramdisk_info = NULL; + p_ramdiskReadBytes = NULL; + + // Reset ramdisk bvr + gRAMDiskVolume = NULL; + printf("\nunmounting: done"); + } } int mountRAMDisk(const char * param) { - int fh = 0, ramDiskSize; - int error = 0; + int fh = 0, ramDiskSize; + int error = 0; - // Get file handle for ramdisk file. - fh = open(param, 0); - if (fh != -1) - { - printf("\nreading ramdisk image: %s", param); + // Get file handle for ramdisk file. + fh = open(param, 0); + if (fh != -1) + { + printf("\nreading ramdisk image: %s", param); - ramDiskSize = file_size(fh); - if (ramDiskSize > 0) - { - // Unmount previously mounted image if exists. - umountRAMDisk(); - - // Read new ramdisk image contents into PREBOOT_DATA area. - if (read(fh, (char *)PREBOOT_DATA, ramDiskSize) != ramDiskSize) error = -1; - } - else error = -1; + ramDiskSize = file_size(fh); + if (ramDiskSize > 0) + { + // Unmount previously mounted image if exists. + umountRAMDisk(); - close(fh); - } - else error = -1; - - if (error == 0) - { - // Save filename in gRAMDiskFile to display information. - strcpy(gRAMDiskFile, param); + // Read new ramdisk image contents into PREBOOT_DATA area. + if (read(fh, (char *)PREBOOT_DATA, ramDiskSize) != ramDiskSize) error = -1; + } + else error = -1; - // Set gMI as well for the multiboot ramdisk driver hook. - gMI = gRAMDiskMI = malloc(sizeof(multiboot_info)); - struct multiboot_module * ramdisk_module = malloc(sizeof(multiboot_module)); - - // Fill in multiboot info and module structures. - if (gRAMDiskMI != NULL && ramdisk_module != NULL) - { - gRAMDiskMI->mi_mods_count = 1; - gRAMDiskMI->mi_mods_addr = (uint32_t)ramdisk_module; - ramdisk_module->mm_mod_start = PREBOOT_DATA; - ramdisk_module->mm_mod_end = PREBOOT_DATA + ramDiskSize; - - // Set ramdisk driver hooks. - p_get_ramdisk_info = &multiboot_get_ramdisk_info; - p_ramdiskReadBytes = &multibootRamdiskReadBytes; - - int partCount; // unused - // Save bvr of the mounted image. - gRAMDiskVolume = diskScanBootVolumes(0x100, &partCount); - if(gRAMDiskVolume == NULL) - { - umountRAMDisk(); - printf("\nRamdisk contains no partitions."); - } - else - { - char dirSpec[128]; + close(fh); + } + else error = -1; - // Reading ramdisk configuration. - strcpy(dirSpec, RAMDISKCONFIG_FILENAME); - - if (loadConfigFile(dirSpec, &bootInfo->ramdiskConfig) == 0) - { - getBoolForKey("BTAlias", &gRAMDiskBTAliased, &bootInfo->ramdiskConfig); - } - else - { - printf("\nno ramdisk config...\n"); - } - - printf("\nmounting: done"); - } - } + if (error == 0) + { + // Save filename in gRAMDiskFile to display information. + strcpy(gRAMDiskFile, param); - } - - return error; + // Set gMI as well for the multiboot ramdisk driver hook. + gMI = gRAMDiskMI = malloc(sizeof(multiboot_info)); + struct multiboot_module * ramdisk_module = malloc(sizeof(multiboot_module)); + + // Fill in multiboot info and module structures. + if (gRAMDiskMI != NULL && ramdisk_module != NULL) + { + gRAMDiskMI->mi_mods_count = 1; + gRAMDiskMI->mi_mods_addr = (uint32_t)ramdisk_module; + ramdisk_module->mm_mod_start = PREBOOT_DATA; + ramdisk_module->mm_mod_end = PREBOOT_DATA + ramDiskSize; + + // Set ramdisk driver hooks. + p_get_ramdisk_info = &multiboot_get_ramdisk_info; + p_ramdiskReadBytes = &multibootRamdiskReadBytes; + + int partCount; // unused + // Save bvr of the mounted image. + gRAMDiskVolume = diskScanBootVolumes(0x100, &partCount); + if(gRAMDiskVolume == NULL) + { + umountRAMDisk(); + printf("\nRamdisk contains no partitions."); + } + else + { + char dirSpec[128]; + + // Reading ramdisk configuration. + strcpy(dirSpec, RAMDISKCONFIG_FILENAME); + + if (loadConfigFile(dirSpec, &bootInfo->ramdiskConfig) == 0) + { + getBoolForKey("BTAlias", &gRAMDiskBTAliased, &bootInfo->ramdiskConfig); + } + else + { + printf("\nno ramdisk config...\n"); + } + + printf("\nmounting: done"); + } + } + } + + return error; } void setRAMDiskBTHook(bool mode) { - gRAMDiskBTAliased = mode; - if (mode) { - printf("\nEnabled bt(0,0) alias."); - } else { - printf("\nDisabled bt(0,0) alias."); - } + gRAMDiskBTAliased = mode; + if (mode) + { + printf("\nEnabled bt(0,0) alias."); + } + else + { + printf("\nDisabled bt(0,0) alias."); + } } void showInfoRAMDisk(void) { - int len; - const char *val; + int len; + const char *val; - if (gRAMDiskMI != NULL) - { - struct multiboot_module * ramdisk_module = (void *)gRAMDiskMI->mi_mods_addr; + if (gRAMDiskMI != NULL) + { + struct multiboot_module * ramdisk_module = (void *)gRAMDiskMI->mi_mods_addr; - printf("\nfile: %s %d", gRAMDiskFile, - ramdisk_module->mm_mod_end - ramdisk_module->mm_mod_start); - printf("\nalias: %s", gRAMDiskBTAliased ? "enabled" : "disabled"); + printf("\nfile: %s %d", gRAMDiskFile, + ramdisk_module->mm_mod_end - ramdisk_module->mm_mod_start); + printf("\nalias: %s", gRAMDiskBTAliased ? "enabled" : "disabled"); - // Display ramdisk information if available. - - if (getValueForKey("Info", &val, &len, &bootInfo->ramdiskConfig)) - printf("\ninfo: %s", val); - else - printf("\nramdisk info not available."); - - } - else - { - printf("\nNo ramdisk mounted."); - } + // Display ramdisk information if available. + if (getValueForKey("Info", &val, &len, &bootInfo->ramdiskConfig)) + { + printf("\ninfo: %s", val); + } + else + { + printf("\nramdisk info not available."); + } + } + else + { + printf("\nNo ramdisk mounted."); + } } int loadPrebootRAMDisk() { - mountRAMDisk("bt(0,0)/Extra/Preboot.dmg"); - if (gRAMDiskMI != NULL) - { - printf("\n"); - return 0; - } - else - { - return -1; - } + mountRAMDisk("bt(0,0)/Extra/Preboot.dmg"); + if (gRAMDiskMI != NULL) + { + printf("\n"); + return 0; + } + else + { + return -1; + } } void processRAMDiskCommand(char ** argPtr, const char * cmd) { - char * ptr = *argPtr; - char param[1024]; - getNextArg(&ptr, param); - - if (strcmp(cmd, "m") == 0) - { - mountRAMDisk(param); - sleep(2); - } - else if (strcmp(cmd, "u") == 0) - { - umountRAMDisk(); - sleep(2); - } - else if (strcmp(cmd, "e") == 0) - { - setRAMDiskBTHook(1); - sleep(2); - } - else if (strcmp(cmd, "d") == 0) - { - setRAMDiskBTHook(0); - sleep(2); - } - else if (strcmp(cmd, "i") == 0) - { - setActiveDisplayPage(1); - clearScreenRows(0, 24); - setCursorPosition(0, 0, 1); - showInfoRAMDisk(); - printf("\n\nPress any key to continue.\n"); - getc(); - setActiveDisplayPage(0); - } - else - { - setActiveDisplayPage(1); - clearScreenRows(0, 24); - setCursorPosition(0, 0, 1); - printf("\nusage:\n"); - printf("\n?rd i - display ramdisk information"); - printf("\n?rd m - mount ramdisk image\n?rd u - unmount ramdisk image"); - printf("\n?rd e - enable bt(0,0) alias\n?rd d - disable bt(0,0) alias"); - printf("\n\nPress any key to continue.\n"); - getc(); - setActiveDisplayPage(0); - } + char * ptr = *argPtr; + char param[1024]; + getNextArg(&ptr, param); + + if (strcmp(cmd, "m") == 0) + { + mountRAMDisk(param); + sleep(2); + } + else if (strcmp(cmd, "u") == 0) + { + umountRAMDisk(); + sleep(2); + } + else if (strcmp(cmd, "e") == 0) + { + setRAMDiskBTHook(true); + sleep(2); + } + else if (strcmp(cmd, "d") == 0) + { + setRAMDiskBTHook(false); + sleep(2); + } + else if (strcmp(cmd, "i") == 0) + { + setActiveDisplayPage(1); + clearScreenRows(0, 24); + setCursorPosition(0, 0, 1); + showInfoRAMDisk(); + printf("\n\nPress any key to continue.\n"); + getc(); + setActiveDisplayPage(0); + } + else + { + setActiveDisplayPage(1); + clearScreenRows(0, 24); + setCursorPosition(0, 0, 1); + printf("\nusage:\n"); + printf("\n?rd i - display ramdisk information"); + printf("\n?rd m - mount ramdisk image\n?rd u - unmount ramdisk image"); + printf("\n?rd e - enable bt(0,0) alias\n?rd d - disable bt(0,0) alias"); + printf("\n\nPress any key to continue.\n"); + getc(); + setActiveDisplayPage(0); + } } Index: branches/meklort/i386/boot2/options.c =================================================================== --- branches/meklort/i386/boot2/options.c (revision 504) +++ branches/meklort/i386/boot2/options.c (revision 505) @@ -111,8 +111,8 @@ position_t p = pos( gui.screen.width / 2 + 1 , ( gui.devicelist.pos.y + 3 ) + ( ( gui.devicelist.height - gui.devicelist.iconspacing ) / 2 ) ); char dummy[80]; - getBootVolumeDescription( gBootVolume, dummy, 80, true ); - drawDeviceIcon( gBootVolume, gui.screen.pixmap, p ); + getBootVolumeDescription( gBootVolume, dummy, sizeof(dummy) - 1, true ); + drawDeviceIcon( gBootVolume, gui.screen.pixmap, p, true ); drawStrCenteredAt( (char *) msg, &font_small, gui.screen.pixmap, gui.countdown.pos ); // make this screen the new background @@ -182,12 +182,22 @@ { gBootArgsPtr = gBootArgs; memset(gBootArgs, '\0', BOOT_STRING_LEN); - + if (bootArgs->Video.v_display == GRAPHICS_MODE) { clearGraphicBootPrompt(); } } +static void addBootArg(const char * argStr) +{ + if ( (gBootArgsPtr + strlen(argStr) + 1) < gBootArgsEnd) + { + *gBootArgsPtr++ = ' '; + strcat(gBootArgs, argStr); + gBootArgsPtr += strlen(argStr); + } +} + //========================================================================== static void showBootPrompt(int row, bool visible) @@ -434,22 +444,19 @@ case BOOT_VERBOSE: gVerboseMode = true; gBootMode = kBootModeNormal; - *gBootArgsPtr++ = '-'; - *gBootArgsPtr++ = 'v'; + addBootArg(kVerboseModeFlag); break; case BOOT_IGNORECACHE: gVerboseMode = false; gBootMode = kBootModeNormal; - *gBootArgsPtr++ = '-'; - *gBootArgsPtr++ = 'f'; + addBootArg(kIgnoreCachesFlag); break; case BOOT_SINGLEUSER: gVerboseMode = true; gBootMode = kBootModeNormal; - *gBootArgsPtr++ = '-'; - *gBootArgsPtr++ = 's'; + addBootArg(kSingleUserModeFlag); break; } @@ -689,12 +696,14 @@ } // ensure we're in graphics mode if gui is setup - if (gui.initialised) { - if (bootArgs->Video.v_display == VGA_TEXT_MODE) { - setVideoMode(GRAPHICS_MODE, 0); - } + if (gui.initialised && bootArgs->Video.v_display == VGA_TEXT_MODE) + { + setVideoMode(GRAPHICS_MODE, 0); } + // Clear command line boot arguments + clearBootArgs(); + // Allow user to override default timeout. if (multiboot_timeout_set) { timeout = multiboot_timeout; @@ -725,32 +734,27 @@ //gBootMode |= kBootModeSafe; } + // Checking user pressed keys + bool f8press = false, spress = false, vpress = false; + while (readKeyboardStatus()) { + key = bgetc (); + if (key == 0x4200) f8press = true; + if ((key & 0xff) == 's' || (key & 0xff) == 'S') spress = true; + if ((key & 0xff) == 'v' || (key & 0xff) == 'V') vpress = true; + } // If user typed F8, abort quiet mode, and display the menu. - { - bool f8press = false, spress = false, vpress = false; - int key; - while (readKeyboardStatus()) { - key = bgetc (); - if (key == 0x4200) f8press = true; - if ((key & 0xff) == 's' || (key & 0xff) == 'S') spress = true; - if ((key & 0xff) == 'v' || (key & 0xff) == 'V') vpress = true; - } - if (f8press) { - gBootMode &= ~kBootModeQuiet; - timeout = 0; - } - if ((gBootMode & kBootModeQuiet) && firstRun && vpress && (gBootArgsPtr + 3 < gBootArgsEnd)) { - *(gBootArgsPtr++) = ' '; - *(gBootArgsPtr++) = '-'; - *(gBootArgsPtr++) = 'v'; - } - if ((gBootMode & kBootModeQuiet) && firstRun && spress && (gBootArgsPtr + 3 < gBootArgsEnd)) { - *(gBootArgsPtr++) = ' '; - *(gBootArgsPtr++) = '-'; - *(gBootArgsPtr++) = 's'; - } + if (f8press) { + gBootMode &= ~kBootModeQuiet; + timeout = 0; } - clearBootArgs(); + // If user typed 'v' or 'V', boot in verbose mode. + if ((gBootMode & kBootModeQuiet) && firstRun && vpress) { + addBootArg(kVerboseModeFlag); + } + // If user typed 's' or 'S', boot in single user mode. + if ((gBootMode & kBootModeQuiet) && firstRun && spress) { + addBootArg(kSingleUserModeFlag); + } if (bootArgs->Video.v_display == VGA_TEXT_MODE) { setCursorPosition(0, 0, 0); @@ -767,28 +771,24 @@ // When booting from CD, default to hard drive boot when possible. if (isCDROM && firstRun) { const char *val; - char *prompt; - char *name; + char *prompt = NULL; + char *name = NULL; int cnt; int optionKey; if (getValueForKey(kCDROMPromptKey, &val, &cnt, &bootInfo->bootConfig)) { - cnt += 1; - prompt = malloc(cnt); - strlcpy(prompt, val, cnt); + prompt = malloc(cnt + 1); + strncat(prompt, val, cnt); } else { name = malloc(80); - getBootVolumeDescription(gBootVolume, name, 80, false); + getBootVolumeDescription(gBootVolume, name, 79, false); prompt = malloc(256); sprintf(prompt, "Press any key to start up from %s, or press F8 to enter startup options.", name); free(name); - cnt = 0; } if (getIntForKey( kCDROMOptionKey, &optionKey, &bootInfo->bootConfig )) { // The key specified is a special key. - } else if (getValueForKey( kCDROMOptionKey, &val, &cnt, &bootInfo->bootConfig ) && cnt >= 1) { - optionKey = val[0]; } else { // Default to F8. optionKey = 0x4200; @@ -803,7 +803,7 @@ key = optionKey; } - if (cnt) { + if (prompt != NULL) { free(prompt); } @@ -855,7 +855,7 @@ // Associate a menu item for each BVRef. for (bvr=bvChain, i=gDeviceCount-1, selectIndex=0; bvr; bvr=bvr->next) { if (bvr->visible) { - getBootVolumeDescription(bvr, menuItems[i].name, 80, true); + getBootVolumeDescription(bvr, menuItems[i].name, sizeof(menuItems[i].name) - 1, true); menuItems[i].param = (void *) bvr; if (bvr == menuBVR) { selectIndex = i; @@ -867,6 +867,7 @@ if (bootArgs->Video.v_display == GRAPHICS_MODE) { // redraw the background buffer + gui.logo.draw = true; drawBackground(); gui.devicelist.draw = true; gui.redraw = true; @@ -1305,24 +1306,24 @@ strncpy(&argP[cnt], cp, userCnt); argP[cnt+userCnt] = '\0'; - if(!shouldboot) - { - gVerboseMode = getValueForKey( kVerboseModeFlag, &val, &cnt, &bootInfo->bootConfig ) || - getValueForKey( kSingleUserModeFlag, &val, &cnt, &bootInfo->bootConfig ); + if(!shouldboot) + { + gVerboseMode = getValueForKey( kVerboseModeFlag, &val, &cnt, &bootInfo->bootConfig ) || + getValueForKey( kSingleUserModeFlag, &val, &cnt, &bootInfo->bootConfig ); + + gBootMode = ( getValueForKey( kSafeModeFlag, &val, &cnt, &bootInfo->bootConfig ) ) ? + kBootModeSafe : kBootModeNormal; - gBootMode = ( getValueForKey( kSafeModeFlag, &val, &cnt, &bootInfo->bootConfig ) ) ? - kBootModeSafe : kBootModeNormal; + if ( getValueForKey( kIgnoreCachesFlag, &val, &cnt, &bootInfo->bootConfig ) ) { + gBootMode = kBootModeSafe; + } + } - if ( getValueForKey( kOldSafeModeFlag, &val, &cnt, &bootInfo->bootConfig ) ) { - gBootMode = kBootModeSafe; - } + if ( getValueForKey( kMKextCacheKey, &val, &cnt, &bootInfo->bootConfig ) ) + { + strlcpy(gMKextName, val, cnt + 1); + } - if ( getValueForKey( kMKextCacheKey, &val, &cnt, &bootInfo->bootConfig ) ) { - strlcpy(gMKextName, val, cnt + 1); - } - - } - free(configKernelFlags); free(valueBuffer); Index: branches/meklort/i386/boot2/Makefile =================================================================== --- branches/meklort/i386/boot2/Makefile (revision 504) +++ branches/meklort/i386/boot2/Makefile (revision 505) @@ -20,7 +20,7 @@ LIBSADIR = ../libsa LIBSAIODIR = ../libsaio UTILDIR = ../util -THEME = default +THEME = embed THEMEDIR = ../../artwork/themes/$(THEME) INC = -I. -I.. -I$(SYMDIR) -I$(LIBSADIR) -I$(LIBSAIODIR) -I$(UTILDIR) ifneq "" "$(wildcard /bin/mkdirs)" @@ -54,7 +54,7 @@ $(HFILES) $(OTHERFILES) DIRS_NEEDED = $(OBJROOT) $(SYMROOT) BOOT2ADDR = 20200 -MAXBOOTSIZE = 392704 +MAXBOOTSIZE = 458240 all: $(DIRS_NEEDED) boot @@ -95,8 +95,19 @@ @echo "#define __BOOT2_ART_H" >> $(SYMROOT)/art.h @cd $(SYMROOT)/embed && find . -name 'theme.plist' -exec xxd -i >> $(SYMROOT)/art.h {} \; @cd $(SYMROOT)/embed && find . -name '*.png' -exec xxd -i >> $(SYMROOT)/art.h {} \; + + @echo "typedef struct {" >> $(SYMROOT)/art.h + @echo " char name[32];" >> $(SYMROOT)/art.h + @echo " unsigned char *pngdata;" >> $(SYMROOT)/art.h + @echo " unsigned int *length;" >> $(SYMROOT)/art.h + @echo "} embeddedpng_t;" >> $(SYMROOT)/art.h + @echo "" >> $(SYMROOT)/art.h + @echo "embeddedpng_t embeddedImages[] = {" >> $(SYMROOT)/art.h + @cd $(SYMROOT)/embed && find . -name '*.png' | sort | cut -f 2 -d '/' | cut -f 1 -d '.' | \ + awk '{ printf "\t{.name = \"%s\", .pngdata = __%s_png, .length = &__%s_png_len},\n", $$1, $$1, $$1 }' >> $(SYMROOT)/art.h + @echo "};" >> $(SYMROOT)/art.h + @echo "#endif /* !__BOOT2_ART_H */" >> $(SYMROOT)/art.h ;\ - rm -rf $(SYMROOT)/embed ;\ embedded.h: @cd $(SYMROOT)/../../doc && xxd -i BootHelp.txt > $(SYMROOT)/embedded.h Index: branches/meklort/i386/cdboot/cdboot.s =================================================================== --- branches/meklort/i386/cdboot/cdboot.s (revision 504) +++ branches/meklort/i386/cdboot/cdboot.s (revision 505) @@ -114,7 +114,7 @@ ; at build time. kSectorBytes EQU 2048 ; sector size in bytes kBoot2Size EQU 65024 ; default load size for boot2 -kBoot2MaxSize EQU 392704 ; max size for boot2 +kBoot2MaxSize EQU 458240 ; max size for boot2 kBoot2Address EQU 0x0200 ; boot2 load address kBoot2Segment EQU 0x2000 ; boot2 load segment Index: branches/meklort/i386/libsa/libsa.h =================================================================== --- branches/meklort/i386/libsa/libsa.h (revision 504) +++ branches/meklort/i386/libsa/libsa.h (revision 505) @@ -70,6 +70,11 @@ return ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')); } +//Azi: TODO - add more ponctuation characters as needed; at least these two, i need for PartNo. +static inline int ispunct(char c) +{ + return (c == '.' || c == '-'); +} /* * string.c @@ -102,6 +107,9 @@ extern int strncasecmp(const char * s1, const char * s2, size_t n); #endif +extern char * strchr(const char *str, int c); +extern char * strbreak(const char *str, char **next, long *len); + extern uint8_t checksum8( void * start, unsigned int length ); /* Index: branches/meklort/i386/libsa/string.c =================================================================== --- branches/meklort/i386/libsa/string.c (revision 504) +++ branches/meklort/i386/libsa/string.c (revision 505) @@ -257,6 +257,55 @@ } #endif +char* strchr(const char *str, int c) +{ + do + { + if(*str == c) + return (char*)str; + } + while(*(str++)); + + return 0; +} + +char* strbreak(const char *str, char **next, long *len) +{ + char *start = (char*)str, *end; + bool quoted = false; + + if ( !start || !len ) + return 0; + + *len = 0; + + while ( isspace(*start) ) + start++; + + if (*start == '"') + { + start++; + + end = strchr(start, '"'); + if(end) + quoted = true; + else + end = strchr(start, '\0'); + } + else + { + for ( end = start; *end && !isspace(*end); end++ ) + {} + } + + *len = end - start; + + if(next) + *next = quoted ? end+1 : end; + + return start; +} + /* COPYRIGHT NOTICE: checksum8 from AppleSMBIOS */ uint8_t checksum8( void * start, unsigned int length ) { Index: branches/meklort/i386/libsa/memory.h =================================================================== --- branches/meklort/i386/libsa/memory.h (revision 504) +++ branches/meklort/i386/libsa/memory.h (revision 505) @@ -48,7 +48,7 @@ # define BASE_SEG BOOT2_SEG #endif -#define STACK_SEG 0x8000 // zef: old STACK_SEG 0x5000 +#define STACK_SEG 0x1000 // zef: old STACK_SEG 0x5000 #define STACK_OFS 0xFFF0 // stack pointer #define BOOT1U_SEG 0x1000 @@ -78,24 +78,24 @@ #define BOOT2_ADDR ADDR32(BOOT2_SEG, BOOT2_OFS) // TODO: BOOT_ADDR ? -#define HIB_ADDR 0x00040000 // special hibernation area +#define HIB_ADDR 0x00040000 // special hibernation area #define HIB_LEN 0x00060000 -#define VIDEO_ADDR 0x000A0000 // unusable space +#define VIDEO_ADDR 0x000A0000 // unusable space #define VIDEO_LEN 0x00060000 -#define KERNEL_ADDR 0x00100000 // 128M kernel + drivers // Was 64 +#define KERNEL_ADDR 0x00100000 // 128M kernel + drivers #define KERNEL_LEN 0x08000000 -#define ZALLOC_ADDR 0x08100000 // 192M zalloc area // Was 256 +#define ZALLOC_ADDR 0x08100000 // 256M zalloc area #define ZALLOC_LEN 0x10000000 -#define LOAD_ADDR 0x14100000 // 95M File load buffer -#define LOAD_LEN 0x05F80000 +#define LOAD_ADDR 0x18100000 // 64M File load buffer +#define LOAD_LEN 0x04000000 // Location of data fed to boot2 by the prebooter -#define PREBOOT_DATA 0x1A080000 // Still have enough room for a 95M ramdisk image - // in case of 512MB system memory. +#define PREBOOT_DATA 0x1C100000 // Still have enough room for a 63M ramdisk image + // in case of 512MB system memory. #define TFTP_ADDR LOAD_ADDR // tftp download buffer #define TFTP_LEN LOAD_LEN Index: branches/meklort/i386/util/bdmesg.c =================================================================== --- branches/meklort/i386/util/bdmesg.c (revision 0) +++ branches/meklort/i386/util/bdmesg.c (revision 505) @@ -0,0 +1,38 @@ +/* + * BooterLog Dump Tool, part of the Chameleon Boot Loader Project + * + * Copyright 2010 by Islam M. Ahmed Zaid. All rights reserved. + * + */ + +#include +#include +#include +#include + +#include "IOKit/IOKitLib.h" + + +int main(int argc, char *argv[]) +{ + io_registry_entry_t root = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/"); + if (!root) + { + printf("IORegistryEntry \"IOIOService:/\" not found.\n"); + return 0; + } + + CFTypeRef bootLog = IORegistryEntryCreateCFProperty(root, CFSTR("boot-log"), kCFAllocatorDefault, 0); + if (!bootLog) + { + printf("\"boot-log\" property not found.\n"); + return 0; + } + //CFShow(bootLog); + const UInt8 *msglog = CFDataGetBytePtr((CFDataRef)bootLog); + if (msglog) + printf("%s\n", msglog); + + return 0; +} + Index: branches/meklort/i386/util/Makefile =================================================================== --- branches/meklort/i386/util/Makefile (revision 504) +++ branches/meklort/i386/util/Makefile (revision 505) @@ -18,7 +18,7 @@ CFILES = machOconv.c ALLSRC = $(CFILES) $(MFILES) $(HFILES) $(EXPORT_HFILES) -PROGRAMS = machOconv +PROGRAMS = machOconv bdmesg OUTFILES = $(PROGRAMS) @@ -29,6 +29,9 @@ machOconv: machOconv.o $(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $(SYMROOT)/$(@F) machOconv.o +bdmesg: bdmesg.o + $(CC) $(CFLAGS) $(LDFLAGS) -framework IOKit -framework CoreFoundation -mmacosx-version-min=10.5 -o $(SYMROOT)/$(@F) bdmesg.o + include ../MakeInc.dir #dependencies Index: branches/meklort/GPL_V2_LICENSE =================================================================== --- branches/meklort/GPL_V2_LICENSE (revision 0) +++ branches/meklort/GPL_V2_LICENSE (revision 505) @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. \ No newline at end of file Index: branches/meklort/CREDITS =================================================================== --- branches/meklort/CREDITS (revision 504) +++ branches/meklort/CREDITS (revision 505) @@ -3,33 +3,35 @@ Developers: ---------- - Crazor - Dense - fassl - iNDi - JrCs - Kabyl - kaitek - mackerintel - mercurysquad - munky - rekursor - Turbo - zef + Crazor + Dense + fassl + iNDi + JrCs + Kabyl + kaitek + mackerintel + mercurysquad + munky + meklort + mozodojo + rekursor + Turbo + valv + zef Thanks to: --------- - asereBLN - bumby - cosmo1t - dfe - Galaxy - kalyway - Krazubu - MasterChief - netkas - sckevyn - smith@@ - THeKiNG - XyZ - \ No newline at end of file + asereBLN + Azimutz + bumby + cosmo1t + dfe + Galaxy + kalyway + Krazubu + MasterChief + netkas + sckevyn + smith@@ + THeKiNG Index: branches/meklort/Makefile =================================================================== --- branches/meklort/Makefile (revision 504) +++ branches/meklort/Makefile (revision 505) @@ -46,7 +46,7 @@ # Currently builds for i386 # -all embedtheme tags debug install installhdrs: $(SYMROOT) $(OBJROOT) +all embedtheme tags debug install installhdrs modules: $(SYMROOT) $(OBJROOT) @if [ -e ".svn" ]; then svnversion -n | tr -d [:alpha:] > revision; fi @if [ -z "$(RC_ARCHS)" ]; then \ RC_ARCHS="i386"; \ @@ -115,6 +115,7 @@ @tar -czf $(SYMROOT)/$(PRODUCT)-src.tar.gz ${EXCLUDE} . @tar -cjf $(SYMROOT)/$(PRODUCT)-src.tar.bz2 ${EXCLUDE} . + clean: rm -rf sym obj dst Index: branches/meklort/README =================================================================== --- branches/meklort/README (revision 0) +++ branches/meklort/README (revision 505) @@ -0,0 +1,7 @@ +Chameleon is a Darwin/XNU boot loader based on Apple's boot-132. + +Because Chameleon now uses part of GPL V2 licensed code in 2 files, +it *must* conform to the most restrictive license that it uses that is the: +GPL Version 2 LICENSE + +Chameleon can thus be (and has to be) freely distributed under the term of the GPL V2 license which prevails, as it is the most restrictive license. Index: branches/meklort/MEMTEST86_LICENSE =================================================================== --- branches/meklort/MEMTEST86_LICENSE (revision 0) +++ branches/meklort/MEMTEST86_LICENSE (revision 505) @@ -0,0 +1,32 @@ +dram_controllers.c/h that scans from the pci host controller USES +an adaptation for chameleon 2.0 RC5 from original : + +======================== +memtest86 license notice +======================== + + Released under version 2 of the Gnu Public License. + By Chris Brady, cbrady@sgi.com + ---------------------------------------------------- + MemTest86+ V4.00 Specific code (GPL V2.0) + By Samuel DEMEULEMEESTER, sdemeule@memtest.org + http://www.canardpc.com - http://www.memtest.org + + +============================ +GPL version 2 license notice +============================ + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Property changes on: branches/meklort ___________________________________________________________________ Modified: svn:mergeinfo Merged /trunk:r138-502