Index: branches/slice/trunkM/bdmesg.txt =================================================================== --- branches/slice/trunkM/bdmesg.txt (revision 0) +++ branches/slice/trunkM/bdmesg.txt (revision 1171) @@ -0,0 +1,244 @@ +Chameleon 2.0-RC5 (svn-r1093) [2011-06-30 11:39:59] +msr(295): ia32_perf_stat 0x06000815 +max: 8 current: 8 +CPU: Brand String: Genuine Intel(R) CPU U1300 @ 1.06GHz +CPU: Vendor/Family/ExtFamily: 0x756e6547/0x6/0x0 +CPU: Model/ExtModel/Stepping: 0xe/0x0/0x8 +CPU: MaxCoef/CurrCoef: 0x8/0x8 +CPU: MaxDiv/CurrDiv: 0x0/0x0 +CPU: TSCFreq: 1064MHz +CPU: FSBFreq: 133MHz +CPU: CPUFreq: 1064MHz +CPU: NoCores/NoThreads: 1/1 +CPU: Features: 0x0000030f +Read HFS+ file: [hd(0,3)/Extra/com.apple.Boot.plist] 501 bytes. +Attempting to read GPT +Read GPT +Reading GPT partition 1, type C12A7328-F81F-11D2-BA4B-00A0C93EC93B +Reading GPT partition 2, type 48465300-0000-11AA-AA11-00306543ECAC +Reading GPT partition 3, type 48465300-0000-11AA-AA11-00306543ECAC +Module 'Symbols.dylib' by 'Chameleon' Loaded. + Description: Chameleon symbols for linking + Version: 0 + Compat: 0 +Read HFS+ file: [hd(0,3)/Extra/modules/Resolution.dylib] 22376 bytes. +Module 'Resolution.dylib' by 'Unknown' Loaded. + Description: + Version: 0 + Compat: 0 +Buffer location: 0x1000EB0E status: 0 +0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x30 0x64 0xE2 0x58 0x31 0x32 0x39 0x35 +0xFF 0xFF 0xFF 0x00 0x64 0x58 0x32 0x35 0x11 0x03 0x1A 0x78 0x87 0x99 0x4F 0x26 +0xFF 0xFF 0x30 0x58 0x39 0x11 0x80 0x78 0xAE 0x4F 0x22 0x00 0x01 0x01 0x01 0x01 +0xFF 0x00 0x58 0x35 0x03 0x78 0x99 0x26 0x00 0x01 0x01 0x01 0x01 0x1C 0x20 0x30 +0xFF 0x64 0x39 0x03 0x0A 0x4F 0x54 0x01 0x01 0x01 0x2A 0x20 0x22 0x00 0x00 0x00 +0xFF 0x58 0x11 0x78 0x4F 0x00 0x01 0x01 0x01 0x20 0x00 0x18 0x00 0x00 0x00 0x47 +0xFF 0x32 0x80 0x99 0x54 0x01 0x01 0x1C 0x10 0x00 0x00 0x00 0x00 0x39 0x45 0xFE +0x00 0x35 0x78 0x26 0x01 0x01 0x1C 0x30 0x18 0x00 0x00 0x47 0x31 0xFE 0xA9 0xE9 +getResolution: 1280x800x32 +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/theme.plist] 2787 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/background.png] 966 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/logo.png] 37244 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_generic.png] 22700 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_generic_o.png] 22748 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_hfsplus.png] 25968 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_hfsplus_o.png] 25971 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_hfsraid.png] 26603 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_hfsraid_o.png] 26565 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_ext3.png] 25554 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_ext3_o.png] 25561 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_fat.png] 24399 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_fat_o.png] 24429 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_fat16.png] 13605 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_fat32.png] 12713 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_ntfs.png] 27227 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_ntfs_o.png] 27197 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_cdrom.png] 23564 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_cdrom_o.png] 22930 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_selection.png] 454 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_scroll_prev.png] 4566 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/device_scroll_next.png] 4381 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/menu_boot.png] 182 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/menu_verbose.png] 182 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/menu_ignore_caches.png] 182 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/menu_single_user.png] 182 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/menu_memory_info.png] 180 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/menu_video_info.png] 180 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/menu_help.png] 180 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/menu_verbose_disabled.png] 187 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/menu_ignore_caches_disabled.png] 187 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/menu_single_user_disabled.png] 187 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/menu_selection.png] 236 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/progress_bar.png] 349 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/progress_bar_background.png] 179 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/text_scroll_prev.png] 632 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/text_scroll_next.png] 650 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/font_console.png] 3499 bytes. +Read HFS+ file: [hd(0,3)/Extra/Themes/Default/font_small.png] 5525 bytes. +Read HFS+ file: [hd(1,2)/Extra/com.apple.Boot.plist] 430 bytes. +Setting boot-uuid to: C9572FBE-7EC5-3A39-AAFE-FE70FA7E936C +Read HFS+ file: [hd(1,2)/System/Library/CoreServices/SystemVersion.plist] 479 bytes. +Hibernate image is too old by 12581828 seconds. Use ForceWake=y to override +Loading Darwin 10.6 +Loading kernel mach_kernel +Read HFS+ file: [hd(1,2)/mach_kernel] 4096 bytes. +Read HFS+ file: [hd(1,2)/mach_kernel] 7454537 bytes. +LoadDrivers: Loading from [/System/Library/Caches/com.apple.kext.caches/Startup/Extensions.mkext] +Read HFS+ file: [hd(1,2)/System/Library/Caches/com.apple.kext.caches/Startup/Extensions.mkext] 4096 bytes. +Read HFS+ file: [hd(1,2)/System/Library/Caches/com.apple.kext.caches/Startup/Extensions.mkext] 4378724 bytes. +Read HFS+ file: [hd(1,2)/DSDT.aml] 19823 bytes. +Using PCI-Root-UID value: 0 +Read HFS+ file: [hd(1,2)/Extra/smbios.plist] 894 bytes. +SMBus CmdReg: 0x101 +Scanning SMBus [8086:27da], mmio: 0x0, ioport: 0x10c0, hostc: 0x3 +SPD[0] (size): 255 @0x50 +SPD[0] (size): 128 @0x51 +Slot: 1 Type 19 2048MB (DDR2 SDRAM) 800MHz Vendor=Hynix Semiconductor + PartNo=HYMP125S64CP8-S6AA SerialNo=00007290 +SPD[0] (size): 255 @0x52 +SPD[0] (size): 255 @0x53 +SPD[0] (size): 255 @0x54 +SPD[0] (size): 255 @0x55 +SPD[0] (size): 255 @0x56 +SPD[0] (size): 255 @0x57 +CPU is Genuine Intel(R) CPU U1300 @ 1.06GHz, family 0x6, model 0xe + +Type: 218, Length: 251, Handle: 0xda00 +Type: 218, Length: 251, Handle: 0xda01 +Type: 218, Length: 251, Handle: 0xda02 +Type: 0, Length: 24, Handle: 0x0 +BIOSInformation: + vendor: Apple Inc. + version: MB11.88Z.006C.B05.0802291410 + releaseDate: 2/29/2008 + +Type: 1, Length: 27, Handle: 0x100 +SystemInformation: + manufacturer: Apple Inc. + productName: MacBook1,1 + version: 1.1 + serialNumber: W88033AKY51 + uuid: 44454C4C-3800-1057-8036-C7C04F4E324A + wakeupReason: 0x6 + skuNumber: b + family: MacBook + +Type: 2, Length: 9, Handle: 0x200 +BaseBoard: + manufacturer: Apple Computer, Inc. + product: Mac-F42C88C8 + version: b + serialNumber: .G8W6N2J.CN129616B63703. + assetTagNumber: b + locationInChassis: + boardType: 0x65 + +Type: 3, Length: 13, Handle: 0x300 +SystemEnclosure: + manufacturer: Dell Inc. + type: 8 + version: b + serialNumber: G8W6N2J + assetTagNumber: b + +Type: 126, Length: 13, Handle: 0x301 +Type: 4, Length: 40, Handle: 0x400 +ProcessorInformation: + socketDesignation: Microprocessor + processorType: 3 + processorFamily: 0xB9 + manufacturer: Intel + processorID: 0x6E8 + processorVersion: b + externalClock: 133MHz + maximumClock: 1064MHz + currentClock: 1066MHz + serialNumber: b + assetTag: b + partNumber: b + +Type: 7, Length: 19, Handle: 0x700 +Type: 7, Length: 19, Handle: 0x701 +Type: 126, Length: 9, Handle: 0x800 +Type: 126, Length: 9, Handle: 0x801 +Type: 126, Length: 9, Handle: 0x803 +Type: 8, Length: 9, Handle: 0x804 +Type: 126, Length: 9, Handle: 0x805 +Type: 8, Length: 9, Handle: 0x806 +Type: 126, Length: 9, Handle: 0x808 +Type: 8, Length: 9, Handle: 0x809 +Type: 126, Length: 9, Handle: 0x80a +Type: 8, Length: 9, Handle: 0x80b +Type: 8, Length: 9, Handle: 0x80c +Type: 8, Length: 9, Handle: 0x80d +Type: 9, Length: 13, Handle: 0x900 +Type: 126, Length: 13, Handle: 0x902 +Type: 10, Length: 6, Handle: 0xa00 +Type: 10, Length: 6, Handle: 0xa01 +Type: 11, Length: 5, Handle: 0xb00 +Type: 13, Length: 22, Handle: 0xd00 +Type: 16, Length: 15, Handle: 0x1000 +Type: 17, Length: 27, Handle: 0x1100 +MemoryDevice: + deviceLocator: System Board Memory + bankLocator: b + memoryType: DDR SDRAM + memorySpeed: 533MHz + manufacturer: N/A + serialNumber: N/A + assetTag: b + partNumber: N/A + +Type: 17, Length: 27, Handle: 0x1101 +MemoryDevice: + deviceLocator: DIMM_B + bankLocator: b + memoryType: DDR2 SDRAM + memorySpeed: 800MHz + manufacturer: Hynix Semiconductor + serialNumber: 00007290 + assetTag: 410833 + partNumber: HYMP125S64CP8-S6AA + +Type: 19, Length: 15, Handle: 0x1300 +Type: 19, Length: 15, Handle: 0x1301 +Type: 20, Length: 19, Handle: 0x1400 +Type: 20, Length: 19, Handle: 0x1401 +Type: 20, Length: 19, Handle: 0x1402 +Type: 21, Length: 7, Handle: 0x1500 +Type: 22, Length: 26, Handle: 0x1600 +Type: 126, Length: 26, Handle: 0x1602 +Type: 27, Length: 12, Handle: 0x1b00 +Type: 28, Length: 20, Handle: 0x1c00 +Type: 32, Length: 11, Handle: 0x2000 +Type: 176, Length: 5, Handle: 0xb000 +Type: 177, Length: 12, Handle: 0xb100 +Type: 178, Length: 6, Handle: 0xb200 +Type: 208, Length: 10, Handle: 0xd000 +Type: 126, Length: 12, Handle: 0xd100 +Type: 126, Length: 12, Handle: 0xd200 +Type: 211, Length: 13, Handle: 0xd300 +Type: 216, Length: 9, Handle: 0xd800 +Type: 217, Length: 8, Handle: 0xd900 +Type: 219, Length: 9, Handle: 0xdb01 +Type: 126, Length: 9, Handle: 0xdb80 +Type: 126, Length: 9, Handle: 0xdb81 +Type: 129, Length: 8, Handle: 0x8100 +Type: 220, Length: 22, Handle: 0xdc00 +Type: 221, Length: 19, Handle: 0xdd00 +Type: 212, Length: 47, Handle: 0xd400 +Type: 222, Length: 13, Handle: 0xde00 +Type: 131, Length: 6, Handle: 0xde00 +AppleProcessorType: + ProcessorType: 0x201 + +Type: 127, Length: 4, Handle: 0xde01 + +Customizing SystemID with : 44454c4c-3800-1057-8036-c7c04f4e324a +efi_inject_get_devprop_string NULL trying stringdata +Read HFS+ file: [hd(1,2)/DSDT.aml] 19823 bytes. +ACPI table not found: SSDT.aml +FADT: Restart Fix applied! +FADT: Using custom DSDT! +Starting Darwin x86 + Index: branches/slice/trunkM/coding_standards.txt =================================================================== --- branches/slice/trunkM/coding_standards.txt (revision 0) +++ branches/slice/trunkM/coding_standards.txt (revision 1171) @@ -0,0 +1,83 @@ +Coding Standard rev. 0 (First Draft) + +1. Indentation + having seen most indentation styles going from 2 to 8 spaces, I would suggest a indentation of 4 spaces. + +2. Comments +I see here two main differents cases: +function description comments and one-line code quite comments + +For functions documentation, I suggest to use this syntax +/** + * + */ +Note the use of /** that will make future html auto-documentation easier (i.e: Doxygen at least recognize this marker) + +for punctual, short code comment, let's use: +// +3) #define at top of document +4) Global vars right below #include / #define (notation: gLobal) +Note that global vars and static vars should be avoided as much as possible in favor of local variables use, get/set functions (properties). + +5) No curly brackets for single lines + +6) else +{ + .... +} + +instead of: + +else { + .... +} + +7) if +{ + .... +} +instead of: + +if { + .... +} + +8) fall through code (using indention) or bail out early (using returns)? +Using early bail out for preconditions early in the function code, +use common sense to avoid as an example more than 4 imbricated if() constructions. +In the later case, consider decomposing your function in more manageable primitives. + +9) Spaces/readability i.e. not: if (fd<0) +but: if (fd < 0) + +10. types, variables, functions, naming +non const variables should follow the (currently mostly used) CamelCase convention: +int myVariableIsFine; +instead of : +int my_variable_is_ok; + +Functions should follow the same conventions except for standard c lib related functions. +Types should share the same convention but start with a Captial letter instead of lower case. + +11. Please make sure you extensively initialize variables: +avoid as much as possible: +int myVar +... +myVar = 10; + +but use instead: +int myVar = 10; + +12. const values: +const int MY_CONST_VARIABLE=42; is also ok for me, depending on the context of use. +or +const int MyConstVariable = 42; (with a Capital first letter) + +13. macro definitions should follow this convention: +#define MY_HANDY_MACROS_PSEUDO_FUNC() ... + +14. Macros use should be limited to really special cases where they bring real value (like special optimization cases) +Most of the time inlining a function is much better than the use of macros + +15. Don't optimize your code blindly, always favor readability when in doubt. +Very often, optimization is not necessary where you think it is, think about the bubble sort algorithm, where people would code it in assembly, where a heap or quick sort algorithm would be much more efficient (n log(n) instead of quadratic complexity), as an example when values count to be sorted get high. Index: branches/slice/trunkM/version =================================================================== --- branches/slice/trunkM/version (revision 0) +++ branches/slice/trunkM/version (revision 1171) @@ -0,0 +1 @@ +2.0-RC5m \ No newline at end of file Index: branches/slice/trunkM/Chameleon.xcodeproj/slice.pbxuser =================================================================== --- branches/slice/trunkM/Chameleon.xcodeproj/slice.pbxuser (revision 0) +++ branches/slice/trunkM/Chameleon.xcodeproj/slice.pbxuser (revision 1171) @@ -0,0 +1,469 @@ +// !$*UTF8*$! +{ + 012E60F8137AC68F00E35218 /* smbios_decode.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {877, 3068}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{7003, 1349}"; + }; + }; + 012E60F9137AC68F00E35218 /* smbios_getters.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {782, 7124}}"; + sepNavSelRange = "{11939, 0}"; + sepNavVisRange = "{10719, 891}"; + }; + }; + 012E60FA137AC68F00E35218 /* smbios_getters.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {877, 637}}"; + sepNavSelRange = "{1382, 0}"; + sepNavVisRange = "{481, 946}"; + }; + }; + 012E60FB137AC68F00E35218 /* smbios.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {782, 11648}}"; + sepNavSelRange = "{28103, 0}"; + sepNavVisRange = "{26399, 959}"; + }; + }; + 0172D0DD11FB66820030222E /* dram_controllers.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {782, 7592}}"; + sepNavSelRange = "{15488, 0}"; + sepNavVisRange = "{0, 730}"; + }; + }; + 08FB7793FE84155DC02AAC07 /* Project object */ = { + activeBuildConfigurationName = Debug; + activeTarget = D28A88AD04BDD90700651E21 /* Chameleon */; + codeSenseManager = 122A5BB61375B61C00795FF0 /* Code sense */; + perUserDictionary = { + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 699, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 332620677; + PBXWorkspaceStateSaveDate = 332620677; + }; + perUserProjectItems = { + 122A5BCA1375C49300795FF0 /* PBXTextBookmark */ = 122A5BCA1375C49300795FF0 /* PBXTextBookmark */; + 122A5BCB1375C49300795FF0 /* PBXTextBookmark */ = 122A5BCB1375C49300795FF0 /* PBXTextBookmark */; + 128EB70A13D31D3900E0DA4B /* PBXTextBookmark */ = 128EB70A13D31D3900E0DA4B /* PBXTextBookmark */; + 128EB70B13D31D3900E0DA4B /* PBXTextBookmark */ = 128EB70B13D31D3900E0DA4B /* PBXTextBookmark */; + 128EC26913D3427400E0DA4B /* PBXTextBookmark */ = 128EC26913D3427400E0DA4B /* PBXTextBookmark */; + 128EC27313D3442900E0DA4B /* PBXTextBookmark */ = 128EC27313D3442900E0DA4B /* PBXTextBookmark */; + 128EC27413D3442900E0DA4B /* PBXTextBookmark */ = 128EC27413D3442900E0DA4B /* PBXTextBookmark */; + 128EC2C313D34A8300E0DA4B /* PBXTextBookmark */ = 128EC2C313D34A8300E0DA4B /* PBXTextBookmark */; + 128EC2D813D34BE800E0DA4B /* PBXTextBookmark */ = 128EC2D813D34BE800E0DA4B /* PBXTextBookmark */; + 128EC36A13D35A4A00E0DA4B /* PBXTextBookmark */ = 128EC36A13D35A4A00E0DA4B /* PBXTextBookmark */; + 128EC36B13D35A4A00E0DA4B /* PBXTextBookmark */ = 128EC36B13D35A4A00E0DA4B /* PBXTextBookmark */; + 12B5D34713C064DF003DE4EE /* PBXTextBookmark */ = 12B5D34713C064DF003DE4EE /* PBXTextBookmark */; + 12D15FC013D35DFB00ABAAF4 /* PBXTextBookmark */ = 12D15FC013D35DFB00ABAAF4 /* PBXTextBookmark */; + 12D15FC113D35DFB00ABAAF4 /* PBXTextBookmark */ = 12D15FC113D35DFB00ABAAF4 /* PBXTextBookmark */; + 12D15FC213D35DFB00ABAAF4 /* PBXTextBookmark */ = 12D15FC213D35DFB00ABAAF4 /* PBXTextBookmark */; + 12D15FE813D3634F00ABAAF4 /* PBXTextBookmark */ = 12D15FE813D3634F00ABAAF4 /* PBXTextBookmark */; + 12D15FF213D3652300ABAAF4 /* PBXTextBookmark */ = 12D15FF213D3652300ABAAF4 /* PBXTextBookmark */; + 12D15FF313D3652300ABAAF4 /* PBXTextBookmark */ = 12D15FF313D3652300ABAAF4 /* PBXTextBookmark */; + 12D15FF413D3652300ABAAF4 /* PBXTextBookmark */ = 12D15FF413D3652300ABAAF4 /* PBXTextBookmark */; + 12D15FF513D3652300ABAAF4 /* PBXTextBookmark */ = 12D15FF513D3652300ABAAF4 /* PBXTextBookmark */; + 12EDC2D91376FCB300937D70 /* PBXTextBookmark */ = 12EDC2D91376FCB300937D70 /* PBXTextBookmark */; + }; + sourceControlManager = 122A5BB51375B61C00795FF0 /* Source Control */; + userBuildSettings = { + }; + }; + 122A5BB51375B61C00795FF0 /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + scmConfiguration = { + repositoryNamesForRoots = { + "" = ""; + }; + }; + }; + 122A5BB61375B61C00795FF0 /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + 122A5BCA1375C49300795FF0 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D3A11F3868000754B65 /* device_tree.h */; + name = "device_tree.h: 1"; + rLen = 72; + rLoc = 0; + rType = 0; + vrLen = 498; + vrLoc = 0; + }; + 122A5BCB1375C49300795FF0 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D3711F3868000754B65 /* device_inject.c */; + name = "device_inject.c: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 604; + vrLoc = 1448; + }; + 128EB70A13D31D3900E0DA4B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D6A11F3868000754B65 /* stringTable.c */; + name = "stringTable.c: 600"; + rLen = 20; + rLoc = 12150; + rType = 0; + vrLen = 456; + vrLoc = 12099; + }; + 128EB70B13D31D3900E0DA4B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D7F11F3868000754B65 /* CREDITS */; + name = "CREDITS: 11"; + rLen = 0; + rLoc = 294; + rType = 0; + vrLen = 295; + vrLoc = 0; + }; + 128EC26913D3427400E0DA4B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D2A11F3868000754B65 /* ati.c */; + name = "ati.c: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 507; + vrLoc = 29881; + }; + 128EC27313D3442900E0DA4B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D3611F3868000754B65 /* cpu.h */; + name = "cpu.h: 28"; + rLen = 0; + rLoc = 662; + rType = 0; + vrLen = 1382; + vrLoc = 997; + }; + 128EC27413D3442900E0DA4B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 012E60F8137AC68F00E35218 /* smbios_decode.c */; + name = "smbios_decode.c: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1349; + vrLoc = 7003; + }; + 128EC2C313D34A8300E0DA4B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D3511F3868000754B65 /* cpu.c */; + name = "cpu.c: 405"; + rLen = 0; + rLoc = 14327; + rType = 0; + vrLen = 829; + vrLoc = 11685; + }; + 128EC2D813D34BE800E0DA4B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D6011F3868000754B65 /* platform.c */; + name = "platform.c: 52"; + rLen = 8; + rLoc = 1222; + rType = 0; + vrLen = 826; + vrLoc = 917; + }; + 128EC36A13D35A4A00E0DA4B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D2611F3868000754B65 /* acpi_patcher.c */; + name = "acpi_patcher.c: 39"; + rLen = 17; + rLoc = 657; + rType = 0; + vrLen = 368; + vrLoc = 517; + }; + 128EC36B13D35A4A00E0DA4B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 012E60FB137AC68F00E35218 /* smbios.c */; + name = "smbios.c: 115"; + rLen = 0; + rLoc = 4506; + rType = 0; + vrLen = 802; + vrLoc = 237; + }; + 12B5D34713C064DF003DE4EE /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D2F11F3868000754B65 /* bootstruct.c */; + name = "bootstruct.c: 215"; + rLen = 0; + rLoc = 6756; + rType = 0; + vrLen = 1093; + vrLoc = 5663; + }; + 12D15FC013D35DFB00ABAAF4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D4011F3868000754B65 /* fake_efi.h */; + name = "fake_efi.h: 19"; + rLen = 12; + rLoc = 550; + rType = 0; + vrLen = 571; + vrLoc = 66; + }; + 12D15FC113D35DFB00ABAAF4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 012E60FA137AC68F00E35218 /* smbios_getters.h */; + name = "smbios_getters.h: 46"; + rLen = 0; + rLoc = 1382; + rType = 0; + vrLen = 946; + vrLoc = 481; + }; + 12D15FC213D35DFB00ABAAF4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 012E60F9137AC68F00E35218 /* smbios_getters.c */; + name = "smbios_getters.c: 493"; + rLen = 7; + rLoc = 13543; + rType = 0; + vrLen = 587; + vrLoc = 13520; + }; + 12D15FE813D3634F00ABAAF4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D6511F3868000754B65 /* SMBIOS.h */; + name = "SMBIOS.h: 72"; + rLen = 15; + rLoc = 2060; + rType = 0; + vrLen = 453; + vrLoc = 1863; + }; + 12D15FF213D3652300ABAAF4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D3F11F3868000754B65 /* fake_efi.c */; + name = "fake_efi.c: 770"; + rLen = 20; + rLoc = 29194; + rType = 0; + vrLen = 368; + vrLoc = 0; + }; + 12D15FF313D3652300ABAAF4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D6111F3868000754B65 /* platform.h */; + name = "platform.h: 101"; + rLen = 13; + rLoc = 3346; + rType = 0; + vrLen = 551; + vrLoc = 3115; + }; + 12D15FF413D3652300ABAAF4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D6811F3868000754B65 /* spd.c */; + name = "spd.c: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 722; + vrLoc = 7943; + }; + 12D15FF513D3652300ABAAF4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D6811F3868000754B65 /* spd.c */; + name = "spd.c: 279"; + rLen = 0; + rLoc = 8418; + rType = 0; + vrLen = 642; + vrLoc = 8297; + }; + 12EDC2D91376FCB300937D70 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B0056D3911F3868000754B65 /* device_tree.c */; + name = "device_tree.c: 311"; + rLen = 12; + rLoc = 7927; + rType = 0; + vrLen = 553; + vrLoc = 7917; + }; + B0056CF711F3868000754B65 /* boot.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {877, 3653}}"; + sepNavSelRange = "{5659, 0}"; + sepNavVisRange = "{5084, 630}"; + }; + }; + B0056D0711F3868000754B65 /* picopng.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {782, 14872}}"; + sepNavSelRange = "{59, 6}"; + sepNavVisRange = "{0, 1312}"; + }; + }; + B0056D2611F3868000754B65 /* acpi_patcher.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {782, 17355}}"; + sepNavSelRange = "{651, 24}"; + sepNavVisRange = "{125, 593}"; + }; + }; + B0056D2A11F3868000754B65 /* ati.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {877, 17433}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{29881, 507}"; + }; + }; + B0056D2F11F3868000754B65 /* bootstruct.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {713, 2795}}"; + sepNavSelRange = "{6756, 0}"; + sepNavVisRange = "{5663, 1093}"; + }; + }; + B0056D3511F3868000754B65 /* cpu.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {877, 5525}}"; + sepNavSelRange = "{14327, 0}"; + sepNavVisRange = "{11685, 829}"; + }; + }; + B0056D3611F3868000754B65 /* cpu.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {877, 2054}}"; + sepNavSelRange = "{662, 0}"; + sepNavVisRange = "{997, 1382}"; + }; + }; + B0056D3711F3868000754B65 /* device_inject.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {713, 4706}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{1448, 604}"; + }; + }; + B0056D3911F3868000754B65 /* device_tree.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {713, 7111}}"; + sepNavSelRange = "{7927, 12}"; + sepNavVisRange = "{7917, 553}"; + }; + }; + B0056D3A11F3868000754B65 /* device_tree.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {713, 806}}"; + sepNavSelRange = "{0, 72}"; + sepNavVisRange = "{0, 498}"; + }; + }; + B0056D3F11F3868000754B65 /* fake_efi.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {877, 10491}}"; + sepNavSelRange = "{29194, 20}"; + sepNavVisRange = "{0, 368}"; + }; + }; + B0056D4011F3868000754B65 /* fake_efi.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {782, 414}}"; + sepNavSelRange = "{538, 0}"; + sepNavVisRange = "{0, 637}"; + }; + }; + B0056D5B11F3868000754B65 /* pci.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {782, 2756}}"; + sepNavSelRange = "{136, 0}"; + sepNavVisRange = "{0, 482}"; + }; + }; + B0056D5C11F3868000754B65 /* pci.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {782, 12519}}"; + sepNavSelRange = "{2084, 4}"; + sepNavVisRange = "{1847, 805}"; + }; + }; + B0056D6011F3868000754B65 /* platform.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {877, 962}}"; + sepNavSelRange = "{1222, 8}"; + sepNavVisRange = "{917, 826}"; + }; + }; + B0056D6111F3868000754B65 /* platform.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {782, 2158}}"; + sepNavSelRange = "{3346, 13}"; + sepNavVisRange = "{2911, 902}"; + }; + }; + B0056D6511F3868000754B65 /* SMBIOS.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {877, 6565}}"; + sepNavSelRange = "{2060, 15}"; + sepNavVisRange = "{1863, 453}"; + }; + }; + B0056D6811F3868000754B65 /* spd.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {877, 5304}}"; + sepNavSelRange = "{8418, 0}"; + sepNavVisRange = "{8297, 642}"; + }; + }; + B0056D6A11F3868000754B65 /* stringTable.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {713, 10153}}"; + sepNavSelRange = "{12150, 20}"; + sepNavVisRange = "{12099, 456}"; + }; + }; + B0056D7F11F3868000754B65 /* CREDITS */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {782, 442}}"; + sepNavSelRange = "{170, 0}"; + sepNavVisRange = "{0, 288}"; + }; + }; + B0056D8111F3868000754B65 /* CHANGES */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {782, 949}}"; + sepNavSelRange = "{3609, 4}"; + sepNavVisRange = "{2547, 2088}"; + }; + }; + D28A88AD04BDD90700651E21 /* Chameleon */ = { + activeExec = 0; + }; +} Index: branches/slice/trunkM/Chameleon.xcodeproj/project.pbxproj =================================================================== --- branches/slice/trunkM/Chameleon.xcodeproj/project.pbxproj (revision 0) +++ branches/slice/trunkM/Chameleon.xcodeproj/project.pbxproj (revision 1171) @@ -0,0 +1,1004 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXFileReference section */ + 012E60F7137AC68F00E35218 /* ati_reg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ati_reg.h; sourceTree = ""; }; + 012E60F8137AC68F00E35218 /* smbios_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = smbios_decode.c; sourceTree = ""; }; + 012E60F9137AC68F00E35218 /* smbios_getters.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = smbios_getters.c; sourceTree = ""; }; + 012E60FA137AC68F00E35218 /* smbios_getters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smbios_getters.h; sourceTree = ""; }; + 012E60FB137AC68F00E35218 /* smbios.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = smbios.c; sourceTree = ""; }; + 0172D0DC11FB66820030222E /* dram_controllers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dram_controllers.h; sourceTree = ""; }; + 0172D0DD11FB66820030222E /* dram_controllers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dram_controllers.c; sourceTree = ""; }; + 019DFBAF11FB94090013E8CC /* MEMTEST86_LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MEMTEST86_LICENSE; sourceTree = ""; }; + 1D145307137073F40050C0CD /* bootargs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bootargs.h; sourceTree = ""; }; + 1D2A1AF513743A2600787720 /* bootargs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bootargs.h; sourceTree = ""; }; + 65ED53931204B83200B22507 /* disk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = disk.h; sourceTree = ""; }; + B0056CE711F3868000754B65 /* boot0.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = boot0.s; sourceTree = ""; }; + B0056CE811F3868000754B65 /* chain0.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = chain0.s; sourceTree = ""; }; + B0056CE911F3868000754B65 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + B0056CEB11F3868000754B65 /* boot1.asm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm.asm; path = boot1.asm; sourceTree = ""; }; + B0056CEC11F3868000754B65 /* boot1.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = boot1.s; sourceTree = ""; }; + B0056CED11F3868000754B65 /* boot1f32-install.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "boot1f32-install.sh"; sourceTree = ""; }; + B0056CEE11F3868000754B65 /* boot1f32.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = boot1f32.s; sourceTree = ""; }; + B0056CEF11F3868000754B65 /* boot1he.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = boot1he.s; sourceTree = ""; }; + B0056CF011F3868000754B65 /* boot1hp.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = boot1hp.s; sourceTree = ""; }; + B0056CF111F3868000754B65 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + B0056CF311F3868000754B65 /* appleboot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = appleboot.h; sourceTree = ""; }; + B0056CF411F3868000754B65 /* appleClut8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = appleClut8.h; sourceTree = ""; }; + B0056CF511F3868000754B65 /* bmdecompress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bmdecompress.c; sourceTree = ""; }; + B0056CF611F3868000754B65 /* boot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = boot.c; sourceTree = ""; }; + B0056CF711F3868000754B65 /* boot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = boot.h; sourceTree = ""; }; + B0056CF811F3868000754B65 /* boot2.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = boot2.s; sourceTree = ""; }; + B0056CF911F3868000754B65 /* drivers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = drivers.c; sourceTree = ""; }; + B0056CFA11F3868000754B65 /* graphic_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = graphic_utils.c; sourceTree = ""; }; + B0056CFB11F3868000754B65 /* graphic_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphic_utils.h; sourceTree = ""; }; + B0056CFC11F3868000754B65 /* graphics.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = graphics.c; sourceTree = ""; }; + B0056CFD11F3868000754B65 /* graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphics.h; sourceTree = ""; }; + B0056CFE11F3868000754B65 /* gui.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gui.c; sourceTree = ""; }; + B0056CFF11F3868000754B65 /* gui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gui.h; sourceTree = ""; }; + B0056D0011F3868000754B65 /* IOHibernatePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOHibernatePrivate.h; sourceTree = ""; }; + B0056D0111F3868000754B65 /* lzss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lzss.c; sourceTree = ""; }; + B0056D0211F3868000754B65 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + B0056D0311F3868000754B65 /* mboot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mboot.c; sourceTree = ""; }; + B0056D0411F3868000754B65 /* mboot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mboot.h; sourceTree = ""; }; + B0056D0511F3868000754B65 /* multiboot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = multiboot.h; sourceTree = ""; }; + B0056D0611F3868000754B65 /* options.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = options.c; sourceTree = ""; }; + B0056D0711F3868000754B65 /* picopng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = picopng.c; sourceTree = ""; }; + B0056D0811F3868000754B65 /* picopng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = picopng.h; sourceTree = ""; }; + B0056D0911F3868000754B65 /* prompt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = prompt.c; sourceTree = ""; }; + B0056D0A11F3868000754B65 /* ramdisk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ramdisk.c; sourceTree = ""; }; + B0056D0B11F3868000754B65 /* ramdisk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ramdisk.h; sourceTree = ""; }; + B0056D0C11F3868000754B65 /* resume.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resume.c; sourceTree = ""; }; + B0056D0D11F3868000754B65 /* WKdm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKdm.h; sourceTree = ""; }; + B0056D0E11F3868000754B65 /* WKdmDecompress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = WKdmDecompress.c; sourceTree = ""; }; + B0056D1011F3868000754B65 /* cdboot.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = cdboot.s; sourceTree = ""; }; + B0056D1111F3868000754B65 /* cdboothdd.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = cdboothdd.s; sourceTree = ""; }; + B0056D1211F3868000754B65 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + B0056D1411F3868000754B65 /* Limits */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Limits; sourceTree = ""; }; + B0056D1511F3868000754B65 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; + B0056D1711F3868000754B65 /* efi_tables.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = efi_tables.c; sourceTree = ""; }; + B0056D1811F3868000754B65 /* efi_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = efi_tables.h; sourceTree = ""; }; + B0056D1911F3868000754B65 /* error.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = error.c; sourceTree = ""; }; + B0056D1A11F3868000754B65 /* libsa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libsa.h; sourceTree = ""; }; + B0056D1B11F3868000754B65 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + B0056D1C11F3868000754B65 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = ""; }; + B0056D1D11F3868000754B65 /* prf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = prf.c; sourceTree = ""; }; + B0056D1E11F3868000754B65 /* printf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = printf.c; sourceTree = ""; }; + B0056D1F11F3868000754B65 /* qsort.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = qsort.c; sourceTree = ""; }; + B0056D2011F3868000754B65 /* setjmp.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = setjmp.s; sourceTree = ""; }; + B0056D2111F3868000754B65 /* string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = string.c; sourceTree = ""; }; + B0056D2211F3868000754B65 /* strtol.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strtol.c; sourceTree = ""; }; + B0056D2311F3868000754B65 /* zalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zalloc.c; sourceTree = ""; }; + B0056D2511F3868000754B65 /* acpi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = acpi.h; sourceTree = ""; }; + B0056D2611F3868000754B65 /* acpi_patcher.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = acpi_patcher.c; sourceTree = ""; }; + B0056D2711F3868000754B65 /* acpi_patcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = acpi_patcher.h; sourceTree = ""; }; + B0056D2811F3868000754B65 /* allocate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = allocate.c; sourceTree = ""; }; + B0056D2911F3868000754B65 /* asm.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = asm.s; sourceTree = ""; }; + B0056D2A11F3868000754B65 /* ati.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ati.c; sourceTree = ""; }; + B0056D2C11F3868000754B65 /* bios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bios.h; sourceTree = ""; }; + B0056D2D11F3868000754B65 /* bios.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = bios.s; sourceTree = ""; }; + B0056D2E11F3868000754B65 /* biosfn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = biosfn.c; sourceTree = ""; }; + B0056D2F11F3868000754B65 /* bootstruct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bootstruct.c; sourceTree = ""; }; + B0056D3011F3868000754B65 /* bootstruct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bootstruct.h; sourceTree = ""; }; + B0056D3111F3868000754B65 /* cache.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cache.c; sourceTree = ""; }; + B0056D3211F3868000754B65 /* console.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = console.c; sourceTree = ""; }; + B0056D3311F3868000754B65 /* convert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = convert.c; sourceTree = ""; }; + B0056D3411F3868000754B65 /* convert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = convert.h; sourceTree = ""; }; + B0056D3511F3868000754B65 /* cpu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cpu.c; sourceTree = ""; }; + B0056D3611F3868000754B65 /* cpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cpu.h; sourceTree = ""; }; + B0056D3711F3868000754B65 /* device_inject.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = device_inject.c; sourceTree = ""; }; + B0056D3811F3868000754B65 /* device_inject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = device_inject.h; sourceTree = ""; }; + B0056D3911F3868000754B65 /* device_tree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = device_tree.c; sourceTree = ""; }; + B0056D3A11F3868000754B65 /* device_tree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = device_tree.h; sourceTree = ""; }; + B0056D3B11F3868000754B65 /* disk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = disk.c; sourceTree = ""; }; + B0056D3C11F3868000754B65 /* efi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = efi.h; sourceTree = ""; }; + B0056D3D11F3868000754B65 /* ext2fs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ext2fs.c; sourceTree = ""; }; + B0056D3E11F3868000754B65 /* ext2fs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ext2fs.h; sourceTree = ""; }; + B0056D3F11F3868000754B65 /* fake_efi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fake_efi.c; sourceTree = ""; }; + B0056D4011F3868000754B65 /* fake_efi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fake_efi.h; sourceTree = ""; }; + B0056D4111F3868000754B65 /* fdisk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fdisk.h; sourceTree = ""; }; + B0056D4211F3868000754B65 /* hfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hfs.c; sourceTree = ""; }; + B0056D4311F3868000754B65 /* hfs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hfs.h; sourceTree = ""; }; + B0056D4411F3868000754B65 /* hfs_CaseTables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hfs_CaseTables.h; sourceTree = ""; }; + B0056D4511F3868000754B65 /* hfs_compare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hfs_compare.c; sourceTree = ""; }; + B0056D4611F3868000754B65 /* hpet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hpet.c; sourceTree = ""; }; + B0056D4711F3868000754B65 /* hpet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hpet.h; sourceTree = ""; }; + B0056D4811F3868000754B65 /* io_inline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = io_inline.h; sourceTree = ""; }; + B0056D4911F3868000754B65 /* libsaio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libsaio.h; sourceTree = ""; }; + B0056D4A11F3868000754B65 /* load.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = load.c; sourceTree = ""; }; + B0056D4B11F3868000754B65 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + B0056D4C11F3868000754B65 /* md5c.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = md5c.c; sourceTree = ""; }; + B0056D4F11F3868000754B65 /* memvendors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memvendors.h; sourceTree = ""; }; + B0056D5011F3868000754B65 /* misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = misc.c; sourceTree = ""; }; + B0056D5111F3868000754B65 /* msdos.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = msdos.c; sourceTree = ""; }; + B0056D5211F3868000754B65 /* msdos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msdos.h; sourceTree = ""; }; + B0056D5311F3868000754B65 /* msdos_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msdos_private.h; sourceTree = ""; }; + B0056D5411F3868000754B65 /* nbp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nbp.c; sourceTree = ""; }; + B0056D5511F3868000754B65 /* nbp_cmd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nbp_cmd.h; sourceTree = ""; }; + B0056D5611F3868000754B65 /* ntfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ntfs.c; sourceTree = ""; }; + B0056D5711F3868000754B65 /* ntfs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ntfs.h; sourceTree = ""; }; + B0056D5811F3868000754B65 /* ntfs_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ntfs_private.h; sourceTree = ""; }; + B0056D5911F3868000754B65 /* nvidia.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nvidia.c; sourceTree = ""; }; + B0056D5A11F3868000754B65 /* nvidia.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nvidia.h; sourceTree = ""; }; + B0056D5B11F3868000754B65 /* pci.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pci.c; sourceTree = ""; }; + B0056D5C11F3868000754B65 /* pci.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pci.h; sourceTree = ""; }; + B0056D5D11F3868000754B65 /* pci_root.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pci_root.c; sourceTree = ""; }; + B0056D5E11F3868000754B65 /* pci_root.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pci_root.h; sourceTree = ""; }; + B0056D5F11F3868000754B65 /* pci_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pci_setup.c; sourceTree = ""; }; + B0056D6011F3868000754B65 /* platform.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = platform.c; sourceTree = ""; }; + B0056D6111F3868000754B65 /* platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform.h; sourceTree = ""; }; + B0056D6211F3868000754B65 /* saio_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saio_internal.h; sourceTree = ""; }; + B0056D6311F3868000754B65 /* saio_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saio_types.h; sourceTree = ""; }; + B0056D6411F3868000754B65 /* sl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sl.h; sourceTree = ""; }; + B0056D6511F3868000754B65 /* SMBIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SMBIOS.h; sourceTree = ""; }; + B0056D6811F3868000754B65 /* spd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = spd.c; sourceTree = ""; }; + B0056D6911F3868000754B65 /* spd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spd.h; sourceTree = ""; }; + B0056D6A11F3868000754B65 /* stringTable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stringTable.c; sourceTree = ""; }; + B0056D6B11F3868000754B65 /* sys.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sys.c; sourceTree = ""; }; + B0056D6C11F3868000754B65 /* table.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = table.c; sourceTree = ""; }; + B0056D6E11F3868000754B65 /* ufs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ufs.h; sourceTree = ""; }; + B0056D7011F3868000754B65 /* ufs_byteorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ufs_byteorder.h; sourceTree = ""; }; + B0056D7111F3868000754B65 /* usb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = usb.c; sourceTree = ""; }; + B0056D7211F3868000754B65 /* vbe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vbe.c; sourceTree = ""; }; + B0056D7311F3868000754B65 /* vbe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vbe.h; sourceTree = ""; }; + B0056D7411F3868000754B65 /* xml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xml.c; sourceTree = ""; }; + B0056D7511F3868000754B65 /* xml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xml.h; sourceTree = ""; }; + B0056D7611F3868000754B65 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + B0056D7811F3868000754B65 /* MakePaths.dir */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MakePaths.dir; sourceTree = ""; }; + B0056D7A11F3868000754B65 /* machOconv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = machOconv.c; sourceTree = ""; }; + B0056D7B11F3868000754B65 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + B0056D7C11F3868000754B65 /* TODO */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TODO; sourceTree = ""; }; + B0056D7D11F3868000754B65 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + B0056D7F11F3868000754B65 /* CREDITS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CREDITS; sourceTree = ""; }; + B0056D8011F3868000754B65 /* coding_standards.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coding_standards.txt; sourceTree = ""; }; + B0056D8111F3868000754B65 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGES; sourceTree = ""; }; + B0056D8211F3868000754B65 /* APPLE_LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = APPLE_LICENSE; sourceTree = ""; }; + B0056D8411F3868000754B65 /* buildpkg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = buildpkg; sourceTree = ""; }; + B0056D8511F3868000754B65 /* Distribution */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Distribution; sourceTree = ""; }; + B0056D8611F3868000754B65 /* fdisk */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = fdisk; sourceTree = ""; }; + B0056D8811F3868000754B65 /* AHCIPortInjector.kext */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.kernel-extension"; path = AHCIPortInjector.kext; sourceTree = ""; }; + B0056D8911F3868000754B65 /* ATAPortInjector.kext */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.kernel-extension"; path = ATAPortInjector.kext; sourceTree = ""; }; + B0056D8A11F3868000754B65 /* Disabler.kext */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.kernel-extension"; path = Disabler.kext; sourceTree = ""; }; + B0056D8B11F3868000754B65 /* IOAHCIBlockStorageInjector.kext */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.kernel-extension"; path = IOAHCIBlockStorageInjector.kext; sourceTree = ""; }; + B0056D8C11F3868000754B65 /* JMicronATAInjector.kext */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.kernel-extension"; path = JMicronATAInjector.kext; sourceTree = ""; }; + B0056D8E11F3868000754B65 /* background.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = background.tiff; sourceTree = ""; }; + B0056D9011F3868000754B65 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = English; path = English.lproj/Description.html; sourceTree = ""; }; + B0056D9211F3868000754B65 /* English */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = English; path = English.lproj/License.rtf; sourceTree = ""; }; + B0056D9411F3868000754B65 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Localizable.strings; sourceTree = ""; }; + B0056D9611F3868000754B65 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.rtfd; name = English; path = English.lproj/Welcome.rtfd; sourceTree = ""; }; + B0056D9711F3868000754B65 /* French */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = French; path = French.lproj/Description.html; sourceTree = ""; }; + B0056D9811F3868000754B65 /* French */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = French; path = French.lproj/License.rtf; sourceTree = ""; }; + B0056D9911F3868000754B65 /* French */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = French; path = French.lproj/Localizable.strings; sourceTree = ""; }; + B0056D9A11F3868000754B65 /* German */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = German; path = German.lproj/Description.html; sourceTree = ""; }; + B0056D9B11F3868000754B65 /* German */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = German; path = German.lproj/License.rtf; sourceTree = ""; }; + B0056D9C11F3868000754B65 /* German */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = German; path = German.lproj/Localizable.strings; sourceTree = ""; }; + B0056D9D11F3868000754B65 /* Spanish */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = Spanish; path = Spanish.lproj/Description.html; sourceTree = ""; }; + B0056D9E11F3868000754B65 /* Spanish */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = Spanish; path = Spanish.lproj/License.rtf; sourceTree = ""; }; + B0056D9F11F3868000754B65 /* Spanish */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = Spanish; path = Spanish.lproj/Localizable.strings; sourceTree = ""; }; + B0056DA011F3868000754B65 /* Spanish */ = {isa = PBXFileReference; lastKnownFileType = wrapper.rtfd; name = Spanish; path = Spanish.lproj/Welcome.rtfd; sourceTree = ""; }; + B0056DA311F3868000754B65 /* postinstall */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = postinstall; sourceTree = ""; }; + B0056DA511F3868000754B65 /* postinstall */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = postinstall; sourceTree = ""; }; + B0056DA811F3868000754B65 /* postinstall */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = postinstall; sourceTree = ""; }; + B0056DAA11F3868000754B65 /* postinstall */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = postinstall; sourceTree = ""; }; + B0056DAC11F3868000754B65 /* postinstall */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = postinstall; sourceTree = ""; }; + B0056DAE11F3868000754B65 /* postinstall */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = postinstall; sourceTree = ""; }; + B0056DB011F3868000754B65 /* postinstall */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = postinstall; sourceTree = ""; }; + B0056DB211F3868000754B65 /* postinstall */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = postinstall; sourceTree = ""; }; + B0056DB411F3868000754B65 /* postinstall */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = postinstall; sourceTree = ""; }; + B0056DB611F3868000754B65 /* postinstall */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = postinstall; sourceTree = ""; }; + B0056DB811F3868000754B65 /* postinstall */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = postinstall; sourceTree = ""; }; + B0056DB911F3868000754B65 /* smbios.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = smbios.plist; sourceTree = ""; }; + B0056DBD11F3868000754B65 /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = background.png; sourceTree = ""; }; + B0056DBE11F3868000754B65 /* boot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = boot.png; sourceTree = ""; }; + B0056DBF11F3868000754B65 /* device_cdrom.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_cdrom.png; sourceTree = ""; }; + B0056DC011F3868000754B65 /* device_ext3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_ext3.png; sourceTree = ""; }; + B0056DC111F3868000754B65 /* device_fat16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_fat16.png; sourceTree = ""; }; + B0056DC211F3868000754B65 /* device_fat32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_fat32.png; sourceTree = ""; }; + B0056DC311F3868000754B65 /* device_generic.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_generic.png; sourceTree = ""; }; + B0056DC411F3868000754B65 /* device_hfsplus.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_hfsplus.png; sourceTree = ""; }; + B0056DC511F3868000754B65 /* device_ntfs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_ntfs.png; sourceTree = ""; }; + B0056DC611F3868000754B65 /* device_scroll_next.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_scroll_next.png; sourceTree = ""; }; + B0056DC711F3868000754B65 /* device_scroll_prev.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_scroll_prev.png; sourceTree = ""; }; + B0056DC811F3868000754B65 /* device_selection.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_selection.png; sourceTree = ""; }; + B0056DC911F3868000754B65 /* font_console.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = font_console.png; sourceTree = ""; }; + B0056DCA11F3868000754B65 /* font_small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = font_small.png; sourceTree = ""; }; + B0056DCB11F3868000754B65 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = ""; }; + B0056DCC11F3868000754B65 /* menu_boot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_boot.png; sourceTree = ""; }; + B0056DCD11F3868000754B65 /* menu_help.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_help.png; sourceTree = ""; }; + B0056DCE11F3868000754B65 /* menu_ignore_caches.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_ignore_caches.png; sourceTree = ""; }; + B0056DCF11F3868000754B65 /* menu_ignore_caches_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_ignore_caches_disabled.png; sourceTree = ""; }; + B0056DD011F3868000754B65 /* menu_memory_info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_memory_info.png; sourceTree = ""; }; + B0056DD111F3868000754B65 /* menu_selection.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_selection.png; sourceTree = ""; }; + B0056DD211F3868000754B65 /* menu_single_user.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_single_user.png; sourceTree = ""; }; + B0056DD311F3868000754B65 /* menu_single_user_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_single_user_disabled.png; sourceTree = ""; }; + B0056DD411F3868000754B65 /* menu_verbose.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_verbose.png; sourceTree = ""; }; + B0056DD511F3868000754B65 /* menu_verbose_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_verbose_disabled.png; sourceTree = ""; }; + B0056DD611F3868000754B65 /* menu_video_info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_video_info.png; sourceTree = ""; }; + B0056DD711F3868000754B65 /* progress_bar.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = progress_bar.png; sourceTree = ""; }; + B0056DD811F3868000754B65 /* progress_bar_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = progress_bar_background.png; sourceTree = ""; }; + B0056DD911F3868000754B65 /* text_scroll_next.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = text_scroll_next.png; sourceTree = ""; }; + B0056DDA11F3868000754B65 /* text_scroll_prev.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = text_scroll_prev.png; sourceTree = ""; }; + B0056DDB11F3868000754B65 /* theme.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = theme.plist; sourceTree = ""; }; + B0056DDD11F3868000754B65 /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = background.png; sourceTree = ""; }; + B0056DDE11F3868000754B65 /* boot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = boot.png; sourceTree = ""; }; + B0056DDF11F3868000754B65 /* device_cdrom.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_cdrom.png; sourceTree = ""; }; + B0056DE011F3868000754B65 /* device_ext3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_ext3.png; sourceTree = ""; }; + B0056DE111F3868000754B65 /* device_fat16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_fat16.png; sourceTree = ""; }; + B0056DE211F3868000754B65 /* device_fat32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_fat32.png; sourceTree = ""; }; + B0056DE311F3868000754B65 /* device_generic.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_generic.png; sourceTree = ""; }; + B0056DE411F3868000754B65 /* device_hfsplus.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_hfsplus.png; sourceTree = ""; }; + B0056DE511F3868000754B65 /* device_ntfs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_ntfs.png; sourceTree = ""; }; + B0056DE611F3868000754B65 /* device_scroll_next.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_scroll_next.png; sourceTree = ""; }; + B0056DE711F3868000754B65 /* device_scroll_prev.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_scroll_prev.png; sourceTree = ""; }; + B0056DE811F3868000754B65 /* device_selection.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_selection.png; sourceTree = ""; }; + B0056DE911F3868000754B65 /* font_console.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = font_console.png; sourceTree = ""; }; + B0056DEA11F3868000754B65 /* font_small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = font_small.png; sourceTree = ""; }; + B0056DEB11F3868000754B65 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = ""; }; + B0056DEC11F3868000754B65 /* menu_boot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_boot.png; sourceTree = ""; }; + B0056DED11F3868000754B65 /* menu_help.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_help.png; sourceTree = ""; }; + B0056DEE11F3868000754B65 /* menu_ignore_caches.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_ignore_caches.png; sourceTree = ""; }; + B0056DEF11F3868000754B65 /* menu_ignore_caches_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_ignore_caches_disabled.png; sourceTree = ""; }; + B0056DF011F3868000754B65 /* menu_memory_info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_memory_info.png; sourceTree = ""; }; + B0056DF111F3868000754B65 /* menu_selection.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_selection.png; sourceTree = ""; }; + B0056DF211F3868000754B65 /* menu_single_user.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_single_user.png; sourceTree = ""; }; + B0056DF311F3868000754B65 /* menu_single_user_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_single_user_disabled.png; sourceTree = ""; }; + B0056DF411F3868000754B65 /* menu_verbose.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_verbose.png; sourceTree = ""; }; + B0056DF511F3868000754B65 /* menu_verbose_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_verbose_disabled.png; sourceTree = ""; }; + B0056DF611F3868000754B65 /* menu_video_info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_video_info.png; sourceTree = ""; }; + B0056DF711F3868000754B65 /* progress_bar.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = progress_bar.png; sourceTree = ""; }; + B0056DF811F3868000754B65 /* progress_bar_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = progress_bar_background.png; sourceTree = ""; }; + B0056DF911F3868000754B65 /* text_scroll_next.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = text_scroll_next.png; sourceTree = ""; }; + B0056DFA11F3868000754B65 /* text_scroll_prev.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = text_scroll_prev.png; sourceTree = ""; }; + B0056DFB11F3868000754B65 /* theme.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = theme.plist; sourceTree = ""; }; + B0056DFD11F3868000754B65 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = ""; }; + B0056DFE11F3868000754B65 /* theme.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = theme.plist; sourceTree = ""; }; + B0056E0011F3868000754B65 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = ""; }; + B0056E0111F3868000754B65 /* theme.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = theme.plist; sourceTree = ""; }; + B0056E0311F3868000754B65 /* font_small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = font_small.png; sourceTree = ""; }; + B0056E0411F3868000754B65 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = ""; }; + B0056E0511F3868000754B65 /* theme.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = theme.plist; sourceTree = ""; }; + B0056E0811F3868000754B65 /* Users_Guide0.4.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = Users_Guide0.4.pdf; sourceTree = ""; }; + B0056E0911F3868000754B65 /* Users_Guide_v0.3.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = Users_Guide_v0.3.pdf; sourceTree = ""; }; + B0056E0A11F3868000754B65 /* UsersGuide-v0.2.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = "UsersGuide-v0.2.pdf"; sourceTree = ""; }; + B0056E0B11F3868000754B65 /* BootHelp.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BootHelp.txt; sourceTree = ""; }; + B0056E0C11F3868000754B65 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; + B0056E0D11F3868000754B65 /* themeinfo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = themeinfo.png; sourceTree = ""; }; + B0056E0F11F3868000754B65 /* Chameleon 2 v0.4.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Chameleon 2 v0.4.xml"; sourceTree = ""; }; + B0056E1011F3868000754B65 /* Chameleon 2 v0.5.docx */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Chameleon 2 v0.5.docx"; sourceTree = ""; }; + B0056E1111F3868000754B65 /* chameleon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chameleon.png; sourceTree = ""; }; + B0056E1211F3868000754B65 /* colorchart.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = colorchart.png; sourceTree = ""; }; + B0056E1311F3868000754B65 /* install_complete.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = install_complete.png; sourceTree = ""; }; + B0056E1411F3868000754B65 /* install_cust.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = install_cust.png; sourceTree = ""; }; + B0056E1511F3868000754B65 /* install_dest.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = install_dest.png; sourceTree = ""; }; + B0056E1611F3868000754B65 /* install_stand.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = install_stand.png; sourceTree = ""; }; + B0056E1711F3868000754B65 /* install_start.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = install_start.png; sourceTree = ""; }; + B0056E1811F3868000754B65 /* screen_format.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = screen_format.png; sourceTree = ""; }; + B0056E1911F3868000754B65 /* xnulogo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = xnulogo.png; sourceTree = ""; }; + B0056E1A11F3868000754B65 /* Users_Guide0.5.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = Users_Guide0.5.pdf; sourceTree = ""; }; + B00F494911F6089500B1D7C5 /* aml_generator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aml_generator.h; sourceTree = ""; }; + B00F494A11F6089500B1D7C5 /* aml_generator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aml_generator.c; sourceTree = ""; }; + B0146EFF11FDEF550010765C /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; + B0146F0011FDEFB90010765C /* GPL_V2_LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = GPL_V2_LICENSE; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* Chameleon */ = { + isa = PBXGroup; + children = ( + B0056DBA11F3868000754B65 /* artwork */, + B0056E0611F3868000754B65 /* doc */, + B0056CE511F3868000754B65 /* i386 */, + B0056D8311F3868000754B65 /* package */, + B0056D8211F3868000754B65 /* APPLE_LICENSE */, + B0056D7F11F3868000754B65 /* CREDITS */, + B0056D8111F3868000754B65 /* CHANGES */, + B0146F0011FDEFB90010765C /* GPL_V2_LICENSE */, + B0146EFF11FDEF550010765C /* README */, + 019DFBAF11FB94090013E8CC /* MEMTEST86_LICENSE */, + B0056D7C11F3868000754B65 /* TODO */, + B0056D7D11F3868000754B65 /* Makefile */, + B0056D8011F3868000754B65 /* coding_standards.txt */, + ); + name = Chameleon; + sourceTree = ""; + }; + B0056CE511F3868000754B65 /* i386 */ = { + isa = PBXGroup; + children = ( + B0056CE611F3868000754B65 /* boot0 */, + B0056CEA11F3868000754B65 /* boot1 */, + B0056CF211F3868000754B65 /* boot2 */, + B0056D0F11F3868000754B65 /* cdboot */, + B0056D1311F3868000754B65 /* doc */, + B0056D1611F3868000754B65 /* libsa */, + B0056D2411F3868000754B65 /* libsaio */, + B0056D7911F3868000754B65 /* util */, + B0056D7611F3868000754B65 /* Makefile */, + B0056D7811F3868000754B65 /* MakePaths.dir */, + ); + path = i386; + sourceTree = ""; + }; + B0056CE611F3868000754B65 /* boot0 */ = { + isa = PBXGroup; + children = ( + B0056CE711F3868000754B65 /* boot0.s */, + B0056CE811F3868000754B65 /* chain0.s */, + B0056CE911F3868000754B65 /* Makefile */, + ); + path = boot0; + sourceTree = ""; + }; + B0056CEA11F3868000754B65 /* boot1 */ = { + isa = PBXGroup; + children = ( + B0056CEB11F3868000754B65 /* boot1.asm */, + B0056CEC11F3868000754B65 /* boot1.s */, + B0056CED11F3868000754B65 /* boot1f32-install.sh */, + B0056CEE11F3868000754B65 /* boot1f32.s */, + B0056CEF11F3868000754B65 /* boot1he.s */, + B0056CF011F3868000754B65 /* boot1hp.s */, + B0056CF111F3868000754B65 /* Makefile */, + ); + path = boot1; + sourceTree = ""; + }; + B0056CF211F3868000754B65 /* boot2 */ = { + isa = PBXGroup; + children = ( + B0056CF311F3868000754B65 /* appleboot.h */, + B0056CF411F3868000754B65 /* appleClut8.h */, + B0056CF511F3868000754B65 /* bmdecompress.c */, + B0056CF611F3868000754B65 /* boot.c */, + B0056CF711F3868000754B65 /* boot.h */, + B0056CF811F3868000754B65 /* boot2.s */, + B0056CF911F3868000754B65 /* drivers.c */, + B0056CFA11F3868000754B65 /* graphic_utils.c */, + B0056CFB11F3868000754B65 /* graphic_utils.h */, + B0056CFC11F3868000754B65 /* graphics.c */, + B0056CFD11F3868000754B65 /* graphics.h */, + B0056CFE11F3868000754B65 /* gui.c */, + B0056CFF11F3868000754B65 /* gui.h */, + B0056D0011F3868000754B65 /* IOHibernatePrivate.h */, + B0056D0111F3868000754B65 /* lzss.c */, + B0056D0211F3868000754B65 /* Makefile */, + B0056D0311F3868000754B65 /* mboot.c */, + B0056D0411F3868000754B65 /* mboot.h */, + B0056D0511F3868000754B65 /* multiboot.h */, + B0056D0611F3868000754B65 /* options.c */, + B0056D0711F3868000754B65 /* picopng.c */, + B0056D0811F3868000754B65 /* picopng.h */, + B0056D0911F3868000754B65 /* prompt.c */, + B0056D0A11F3868000754B65 /* ramdisk.c */, + B0056D0B11F3868000754B65 /* ramdisk.h */, + B0056D0C11F3868000754B65 /* resume.c */, + B0056D0D11F3868000754B65 /* WKdm.h */, + B0056D0E11F3868000754B65 /* WKdmDecompress.c */, + ); + path = boot2; + sourceTree = ""; + }; + B0056D0F11F3868000754B65 /* cdboot */ = { + isa = PBXGroup; + children = ( + B0056D1011F3868000754B65 /* cdboot.s */, + B0056D1111F3868000754B65 /* cdboothdd.s */, + B0056D1211F3868000754B65 /* Makefile */, + ); + path = cdboot; + sourceTree = ""; + }; + B0056D1311F3868000754B65 /* doc */ = { + isa = PBXGroup; + children = ( + B0056D1411F3868000754B65 /* Limits */, + B0056D1511F3868000754B65 /* README */, + ); + path = doc; + sourceTree = ""; + }; + B0056D1611F3868000754B65 /* libsa */ = { + isa = PBXGroup; + children = ( + B0056D1711F3868000754B65 /* efi_tables.c */, + B0056D1811F3868000754B65 /* efi_tables.h */, + B0056D1911F3868000754B65 /* error.c */, + B0056D1A11F3868000754B65 /* libsa.h */, + B0056D1B11F3868000754B65 /* Makefile */, + B0056D1C11F3868000754B65 /* memory.h */, + B0056D1D11F3868000754B65 /* prf.c */, + B0056D1E11F3868000754B65 /* printf.c */, + B0056D1F11F3868000754B65 /* qsort.c */, + B0056D2011F3868000754B65 /* setjmp.s */, + B0056D2111F3868000754B65 /* string.c */, + B0056D2211F3868000754B65 /* strtol.c */, + B0056D2311F3868000754B65 /* zalloc.c */, + ); + path = libsa; + sourceTree = ""; + }; + B0056D2411F3868000754B65 /* libsaio */ = { + isa = PBXGroup; + children = ( + B0056D2511F3868000754B65 /* acpi.h */, + B0056D2611F3868000754B65 /* acpi_patcher.c */, + B0056D2711F3868000754B65 /* acpi_patcher.h */, + B0056D2811F3868000754B65 /* allocate.c */, + B00F494A11F6089500B1D7C5 /* aml_generator.c */, + B00F494911F6089500B1D7C5 /* aml_generator.h */, + B0056D2911F3868000754B65 /* asm.s */, + 012E60F7137AC68F00E35218 /* ati_reg.h */, + B0056D2A11F3868000754B65 /* ati.c */, + B0056D2C11F3868000754B65 /* bios.h */, + B0056D2D11F3868000754B65 /* bios.s */, + B0056D2E11F3868000754B65 /* biosfn.c */, + 1D145307137073F40050C0CD /* bootargs.h */, + B0056D2F11F3868000754B65 /* bootstruct.c */, + B0056D3011F3868000754B65 /* bootstruct.h */, + B0056D3111F3868000754B65 /* cache.c */, + B0056D3211F3868000754B65 /* console.c */, + B0056D3311F3868000754B65 /* convert.c */, + B0056D3411F3868000754B65 /* convert.h */, + B0056D3511F3868000754B65 /* cpu.c */, + B0056D3611F3868000754B65 /* cpu.h */, + B0056D3711F3868000754B65 /* device_inject.c */, + B0056D3811F3868000754B65 /* device_inject.h */, + B0056D3911F3868000754B65 /* device_tree.c */, + B0056D3A11F3868000754B65 /* device_tree.h */, + B0056D3B11F3868000754B65 /* disk.c */, + 65ED53931204B83200B22507 /* disk.h */, + 0172D0DC11FB66820030222E /* dram_controllers.h */, + 0172D0DD11FB66820030222E /* dram_controllers.c */, + B0056D3C11F3868000754B65 /* efi.h */, + B0056D3D11F3868000754B65 /* ext2fs.c */, + B0056D3E11F3868000754B65 /* ext2fs.h */, + B0056D3F11F3868000754B65 /* fake_efi.c */, + B0056D4011F3868000754B65 /* fake_efi.h */, + B0056D4111F3868000754B65 /* fdisk.h */, + B0056D4211F3868000754B65 /* hfs.c */, + B0056D4311F3868000754B65 /* hfs.h */, + B0056D4411F3868000754B65 /* hfs_CaseTables.h */, + B0056D4511F3868000754B65 /* hfs_compare.c */, + B0056D4611F3868000754B65 /* hpet.c */, + B0056D4711F3868000754B65 /* hpet.h */, + B0056D4811F3868000754B65 /* io_inline.h */, + B0056D4911F3868000754B65 /* libsaio.h */, + B0056D4A11F3868000754B65 /* load.c */, + B0056D4B11F3868000754B65 /* Makefile */, + B0056D4C11F3868000754B65 /* md5c.c */, + B0056D4F11F3868000754B65 /* memvendors.h */, + B0056D5011F3868000754B65 /* misc.c */, + B0056D5111F3868000754B65 /* msdos.c */, + B0056D5211F3868000754B65 /* msdos.h */, + B0056D5311F3868000754B65 /* msdos_private.h */, + B0056D5411F3868000754B65 /* nbp.c */, + B0056D5511F3868000754B65 /* nbp_cmd.h */, + B0056D5611F3868000754B65 /* ntfs.c */, + B0056D5711F3868000754B65 /* ntfs.h */, + B0056D5811F3868000754B65 /* ntfs_private.h */, + B0056D5911F3868000754B65 /* nvidia.c */, + B0056D5A11F3868000754B65 /* nvidia.h */, + B0056D5B11F3868000754B65 /* pci.c */, + B0056D5C11F3868000754B65 /* pci.h */, + B0056D5D11F3868000754B65 /* pci_root.c */, + B0056D5E11F3868000754B65 /* pci_root.h */, + B0056D5F11F3868000754B65 /* pci_setup.c */, + B0056D6011F3868000754B65 /* platform.c */, + B0056D6111F3868000754B65 /* platform.h */, + B0056D6211F3868000754B65 /* saio_internal.h */, + B0056D6311F3868000754B65 /* saio_types.h */, + B0056D6411F3868000754B65 /* sl.h */, + B0056D6511F3868000754B65 /* SMBIOS.h */, + 012E60F8137AC68F00E35218 /* smbios_decode.c */, + 012E60F9137AC68F00E35218 /* smbios_getters.c */, + 012E60FA137AC68F00E35218 /* smbios_getters.h */, + 012E60FB137AC68F00E35218 /* smbios.c */, + B0056D6811F3868000754B65 /* spd.c */, + B0056D6911F3868000754B65 /* spd.h */, + B0056D6A11F3868000754B65 /* stringTable.c */, + B0056D6B11F3868000754B65 /* sys.c */, + B0056D6C11F3868000754B65 /* table.c */, + B0056D6E11F3868000754B65 /* ufs.h */, + B0056D7011F3868000754B65 /* ufs_byteorder.h */, + B0056D7111F3868000754B65 /* usb.c */, + B0056D7211F3868000754B65 /* vbe.c */, + B0056D7311F3868000754B65 /* vbe.h */, + B0056D7411F3868000754B65 /* xml.c */, + B0056D7511F3868000754B65 /* xml.h */, + 1D2A1AF513743A2600787720 /* bootargs.h */, + ); + path = libsaio; + sourceTree = ""; + }; + B0056D7911F3868000754B65 /* util */ = { + isa = PBXGroup; + children = ( + B0056D7A11F3868000754B65 /* machOconv.c */, + B0056D7B11F3868000754B65 /* Makefile */, + ); + path = util; + sourceTree = ""; + }; + B0056D8311F3868000754B65 /* package */ = { + isa = PBXGroup; + children = ( + B0056D8411F3868000754B65 /* buildpkg */, + B0056D8511F3868000754B65 /* Distribution */, + B0056D8611F3868000754B65 /* fdisk */, + B0056D8711F3868000754B65 /* Kexts */, + B0056D8D11F3868000754B65 /* Resources */, + B0056DA111F3868000754B65 /* Scripts */, + B0056DB911F3868000754B65 /* smbios.plist */, + ); + path = package; + sourceTree = ""; + }; + B0056D8711F3868000754B65 /* Kexts */ = { + isa = PBXGroup; + children = ( + B0056D8811F3868000754B65 /* AHCIPortInjector.kext */, + B0056D8911F3868000754B65 /* ATAPortInjector.kext */, + B0056D8A11F3868000754B65 /* Disabler.kext */, + B0056D8B11F3868000754B65 /* IOAHCIBlockStorageInjector.kext */, + B0056D8C11F3868000754B65 /* JMicronATAInjector.kext */, + ); + path = Kexts; + sourceTree = ""; + }; + B0056D8D11F3868000754B65 /* Resources */ = { + isa = PBXGroup; + children = ( + B0056D8E11F3868000754B65 /* background.tiff */, + B0056D8F11F3868000754B65 /* Description.html */, + B0056D9111F3868000754B65 /* License.rtf */, + B0056D9311F3868000754B65 /* Localizable.strings */, + B0056D9511F3868000754B65 /* Welcome.rtfd */, + ); + path = Resources; + sourceTree = ""; + }; + B0056DA111F3868000754B65 /* Scripts */ = { + isa = PBXGroup; + children = ( + B0056DA211F3868000754B65 /* FAT */, + B0056DA411F3868000754B65 /* HFS */, + B0056DA611F3868000754B65 /* Options */, + B0056DB511F3868000754B65 /* Post */, + B0056DB711F3868000754B65 /* Standard */, + ); + path = Scripts; + sourceTree = ""; + }; + B0056DA211F3868000754B65 /* FAT */ = { + isa = PBXGroup; + children = ( + B0056DA311F3868000754B65 /* postinstall */, + ); + path = FAT; + sourceTree = ""; + }; + B0056DA411F3868000754B65 /* HFS */ = { + isa = PBXGroup; + children = ( + B0056DA511F3868000754B65 /* postinstall */, + ); + path = HFS; + sourceTree = ""; + }; + B0056DA611F3868000754B65 /* Options */ = { + isa = PBXGroup; + children = ( + B0056DA711F3868000754B65 /* EHCIacquire */, + B0056DA911F3868000754B65 /* EthernetBuiltIn */, + B0056DAB11F3868000754B65 /* ForceHPET */, + B0056DAD11F3868000754B65 /* ForceWake */, + B0056DAF11F3868000754B65 /* GraphicsEnabler */, + B0056DB111F3868000754B65 /* GUI */, + B0056DB311F3868000754B65 /* UHCIreset */, + ); + path = Options; + sourceTree = ""; + }; + B0056DA711F3868000754B65 /* EHCIacquire */ = { + isa = PBXGroup; + children = ( + B0056DA811F3868000754B65 /* postinstall */, + ); + path = EHCIacquire; + sourceTree = ""; + }; + B0056DA911F3868000754B65 /* EthernetBuiltIn */ = { + isa = PBXGroup; + children = ( + B0056DAA11F3868000754B65 /* postinstall */, + ); + path = EthernetBuiltIn; + sourceTree = ""; + }; + B0056DAB11F3868000754B65 /* ForceHPET */ = { + isa = PBXGroup; + children = ( + B0056DAC11F3868000754B65 /* postinstall */, + ); + path = ForceHPET; + sourceTree = ""; + }; + B0056DAD11F3868000754B65 /* ForceWake */ = { + isa = PBXGroup; + children = ( + B0056DAE11F3868000754B65 /* postinstall */, + ); + path = ForceWake; + sourceTree = ""; + }; + B0056DAF11F3868000754B65 /* GraphicsEnabler */ = { + isa = PBXGroup; + children = ( + B0056DB011F3868000754B65 /* postinstall */, + ); + path = GraphicsEnabler; + sourceTree = ""; + }; + B0056DB111F3868000754B65 /* GUI */ = { + isa = PBXGroup; + children = ( + B0056DB211F3868000754B65 /* postinstall */, + ); + path = GUI; + sourceTree = ""; + }; + B0056DB311F3868000754B65 /* UHCIreset */ = { + isa = PBXGroup; + children = ( + B0056DB411F3868000754B65 /* postinstall */, + ); + path = UHCIreset; + sourceTree = ""; + }; + B0056DB511F3868000754B65 /* Post */ = { + isa = PBXGroup; + children = ( + B0056DB611F3868000754B65 /* postinstall */, + ); + path = Post; + sourceTree = ""; + }; + B0056DB711F3868000754B65 /* Standard */ = { + isa = PBXGroup; + children = ( + B0056DB811F3868000754B65 /* postinstall */, + ); + path = Standard; + sourceTree = ""; + }; + B0056DBA11F3868000754B65 /* artwork */ = { + isa = PBXGroup; + children = ( + B0056DBB11F3868000754B65 /* themes */, + ); + path = artwork; + sourceTree = ""; + }; + B0056DBB11F3868000754B65 /* themes */ = { + isa = PBXGroup; + children = ( + B0056DBC11F3868000754B65 /* bullet */, + B0056DDC11F3868000754B65 /* default */, + B0056DFC11F3868000754B65 /* msi_netbook */, + B0056DFF11F3868000754B65 /* pinktink */, + B0056E0211F3868000754B65 /* twilight */, + ); + path = themes; + sourceTree = ""; + }; + B0056DBC11F3868000754B65 /* bullet */ = { + isa = PBXGroup; + children = ( + B0056DBD11F3868000754B65 /* background.png */, + B0056DBE11F3868000754B65 /* boot.png */, + B0056DBF11F3868000754B65 /* device_cdrom.png */, + B0056DC011F3868000754B65 /* device_ext3.png */, + B0056DC111F3868000754B65 /* device_fat16.png */, + B0056DC211F3868000754B65 /* device_fat32.png */, + B0056DC311F3868000754B65 /* device_generic.png */, + B0056DC411F3868000754B65 /* device_hfsplus.png */, + B0056DC511F3868000754B65 /* device_ntfs.png */, + B0056DC611F3868000754B65 /* device_scroll_next.png */, + B0056DC711F3868000754B65 /* device_scroll_prev.png */, + B0056DC811F3868000754B65 /* device_selection.png */, + B0056DC911F3868000754B65 /* font_console.png */, + B0056DCA11F3868000754B65 /* font_small.png */, + B0056DCB11F3868000754B65 /* logo.png */, + B0056DCC11F3868000754B65 /* menu_boot.png */, + B0056DCD11F3868000754B65 /* menu_help.png */, + B0056DCE11F3868000754B65 /* menu_ignore_caches.png */, + B0056DCF11F3868000754B65 /* menu_ignore_caches_disabled.png */, + B0056DD011F3868000754B65 /* menu_memory_info.png */, + B0056DD111F3868000754B65 /* menu_selection.png */, + B0056DD211F3868000754B65 /* menu_single_user.png */, + B0056DD311F3868000754B65 /* menu_single_user_disabled.png */, + B0056DD411F3868000754B65 /* menu_verbose.png */, + B0056DD511F3868000754B65 /* menu_verbose_disabled.png */, + B0056DD611F3868000754B65 /* menu_video_info.png */, + B0056DD711F3868000754B65 /* progress_bar.png */, + B0056DD811F3868000754B65 /* progress_bar_background.png */, + B0056DD911F3868000754B65 /* text_scroll_next.png */, + B0056DDA11F3868000754B65 /* text_scroll_prev.png */, + B0056DDB11F3868000754B65 /* theme.plist */, + ); + path = bullet; + sourceTree = ""; + }; + B0056DDC11F3868000754B65 /* default */ = { + isa = PBXGroup; + children = ( + B0056DDD11F3868000754B65 /* background.png */, + B0056DDE11F3868000754B65 /* boot.png */, + B0056DDF11F3868000754B65 /* device_cdrom.png */, + B0056DE011F3868000754B65 /* device_ext3.png */, + B0056DE111F3868000754B65 /* device_fat16.png */, + B0056DE211F3868000754B65 /* device_fat32.png */, + B0056DE311F3868000754B65 /* device_generic.png */, + B0056DE411F3868000754B65 /* device_hfsplus.png */, + B0056DE511F3868000754B65 /* device_ntfs.png */, + B0056DE611F3868000754B65 /* device_scroll_next.png */, + B0056DE711F3868000754B65 /* device_scroll_prev.png */, + B0056DE811F3868000754B65 /* device_selection.png */, + B0056DE911F3868000754B65 /* font_console.png */, + B0056DEA11F3868000754B65 /* font_small.png */, + B0056DEB11F3868000754B65 /* logo.png */, + B0056DEC11F3868000754B65 /* menu_boot.png */, + B0056DED11F3868000754B65 /* menu_help.png */, + B0056DEE11F3868000754B65 /* menu_ignore_caches.png */, + B0056DEF11F3868000754B65 /* menu_ignore_caches_disabled.png */, + B0056DF011F3868000754B65 /* menu_memory_info.png */, + B0056DF111F3868000754B65 /* menu_selection.png */, + B0056DF211F3868000754B65 /* menu_single_user.png */, + B0056DF311F3868000754B65 /* menu_single_user_disabled.png */, + B0056DF411F3868000754B65 /* menu_verbose.png */, + B0056DF511F3868000754B65 /* menu_verbose_disabled.png */, + B0056DF611F3868000754B65 /* menu_video_info.png */, + B0056DF711F3868000754B65 /* progress_bar.png */, + B0056DF811F3868000754B65 /* progress_bar_background.png */, + B0056DF911F3868000754B65 /* text_scroll_next.png */, + B0056DFA11F3868000754B65 /* text_scroll_prev.png */, + B0056DFB11F3868000754B65 /* theme.plist */, + ); + path = default; + sourceTree = ""; + }; + B0056DFC11F3868000754B65 /* msi_netbook */ = { + isa = PBXGroup; + children = ( + B0056DFD11F3868000754B65 /* logo.png */, + B0056DFE11F3868000754B65 /* theme.plist */, + ); + path = msi_netbook; + sourceTree = ""; + }; + B0056DFF11F3868000754B65 /* pinktink */ = { + isa = PBXGroup; + children = ( + B0056E0011F3868000754B65 /* logo.png */, + B0056E0111F3868000754B65 /* theme.plist */, + ); + path = pinktink; + sourceTree = ""; + }; + B0056E0211F3868000754B65 /* twilight */ = { + isa = PBXGroup; + children = ( + B0056E0311F3868000754B65 /* font_small.png */, + B0056E0411F3868000754B65 /* logo.png */, + B0056E0511F3868000754B65 /* theme.plist */, + ); + path = twilight; + sourceTree = ""; + }; + B0056E0611F3868000754B65 /* doc */ = { + isa = PBXGroup; + children = ( + B0056E0711F3868000754B65 /* archive */, + B0056E0B11F3868000754B65 /* BootHelp.txt */, + B0056E0C11F3868000754B65 /* README */, + B0056E0D11F3868000754B65 /* themeinfo.png */, + B0056E0E11F3868000754B65 /* User_Guide_src */, + B0056E1A11F3868000754B65 /* Users_Guide0.5.pdf */, + ); + path = doc; + sourceTree = ""; + }; + B0056E0711F3868000754B65 /* archive */ = { + isa = PBXGroup; + children = ( + B0056E0811F3868000754B65 /* Users_Guide0.4.pdf */, + B0056E0911F3868000754B65 /* Users_Guide_v0.3.pdf */, + B0056E0A11F3868000754B65 /* UsersGuide-v0.2.pdf */, + ); + path = archive; + sourceTree = ""; + }; + B0056E0E11F3868000754B65 /* User_Guide_src */ = { + isa = PBXGroup; + children = ( + B0056E0F11F3868000754B65 /* Chameleon 2 v0.4.xml */, + B0056E1011F3868000754B65 /* Chameleon 2 v0.5.docx */, + B0056E1111F3868000754B65 /* chameleon.png */, + B0056E1211F3868000754B65 /* colorchart.png */, + B0056E1311F3868000754B65 /* install_complete.png */, + B0056E1411F3868000754B65 /* install_cust.png */, + B0056E1511F3868000754B65 /* install_dest.png */, + B0056E1611F3868000754B65 /* install_stand.png */, + B0056E1711F3868000754B65 /* install_start.png */, + B0056E1811F3868000754B65 /* screen_format.png */, + B0056E1911F3868000754B65 /* xnulogo.png */, + ); + path = User_Guide_src; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXLegacyTarget section */ + D28A88AD04BDD90700651E21 /* Chameleon */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION)"; + buildConfigurationList = 1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "Chameleon" */; + buildPhases = ( + ); + buildToolPath = /usr/bin/make; + buildWorkingDirectory = ""; + dependencies = ( + ); + name = Chameleon; + passBuildSettingsInEnvironment = 1; + productName = Chameleon; + }; +/* End PBXLegacyTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0410; + }; + buildConfigurationList = 1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "Chameleon" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + Spanish, + ); + mainGroup = 08FB7794FE84155DC02AAC07 /* Chameleon */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D28A88AD04BDD90700651E21 /* Chameleon */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXVariantGroup section */ + B0056D8F11F3868000754B65 /* Description.html */ = { + isa = PBXVariantGroup; + children = ( + B0056D9011F3868000754B65 /* English */, + B0056D9711F3868000754B65 /* French */, + B0056D9A11F3868000754B65 /* German */, + B0056D9D11F3868000754B65 /* Spanish */, + ); + name = Description.html; + sourceTree = ""; + }; + B0056D9111F3868000754B65 /* License.rtf */ = { + isa = PBXVariantGroup; + children = ( + B0056D9211F3868000754B65 /* English */, + B0056D9811F3868000754B65 /* French */, + B0056D9B11F3868000754B65 /* German */, + B0056D9E11F3868000754B65 /* Spanish */, + ); + name = License.rtf; + sourceTree = ""; + }; + B0056D9311F3868000754B65 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + B0056D9411F3868000754B65 /* English */, + B0056D9911F3868000754B65 /* French */, + B0056D9C11F3868000754B65 /* German */, + B0056D9F11F3868000754B65 /* Spanish */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + B0056D9511F3868000754B65 /* Welcome.rtfd */ = { + isa = PBXVariantGroup; + children = ( + B0056D9611F3868000754B65 /* English */, + B0056DA011F3868000754B65 /* Spanish */, + ); + name = Welcome.rtfd; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1DEB919008733D9F0010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + GCC_DYNAMIC_NO_PIC = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = Chameleon; + }; + name = Debug; + }; + 1DEB919108733D9F0010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = Chameleon; + }; + name = Release; + }; + 1DEB919408733D9F0010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 1DEB919508733D9F0010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + SDKROOT = macosx; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "Chameleon" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB919008733D9F0010E9CD /* Debug */, + 1DEB919108733D9F0010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "Chameleon" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB919408733D9F0010E9CD /* Debug */, + 1DEB919508733D9F0010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} Index: branches/slice/trunkM/Chameleon.xcodeproj/slice.mode1v3 =================================================================== --- branches/slice/trunkM/Chameleon.xcodeproj/slice.mode1v3 (revision 0) +++ branches/slice/trunkM/Chameleon.xcodeproj/slice.mode1v3 (revision 1171) @@ -0,0 +1,1384 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1v3 + FavBarConfig + + PBXProjectModuleGUID + 122A5BD01375C49300795FF0 + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1v3 + MajorVersion + 33 + MinorVersion + 0 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-combo-popup + action + NSToolbarFlexibleSpaceItem + clean-target + buildOrClean + servicesModulefind + com.apple.ide.PBXToolbarStopButton + get-info + go + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 08FB7794FE84155DC02AAC07 + B0056CE511F3868000754B65 + B0056D2411F3868000754B65 + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 84 + 10 + 3 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 1020}, {186, 600}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 618}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 134 119 1146 659 0 0 1280 778 + + Module + PBXSmartGroupTreeModule + Proportion + 203pt + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + spd.c + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + spd.c + _historyCapacity + 0 + bookmark + 12D15FF513D3652300ABAAF4 + history + + 122A5BCA1375C49300795FF0 + 122A5BCB1375C49300795FF0 + 12EDC2D91376FCB300937D70 + 12B5D34713C064DF003DE4EE + 128EB70A13D31D3900E0DA4B + 128EB70B13D31D3900E0DA4B + 128EC26913D3427400E0DA4B + 128EC27313D3442900E0DA4B + 128EC27413D3442900E0DA4B + 128EC2C313D34A8300E0DA4B + 128EC2D813D34BE800E0DA4B + 128EC36A13D35A4A00E0DA4B + 128EC36B13D35A4A00E0DA4B + 12D15FC013D35DFB00ABAAF4 + 12D15FC113D35DFB00ABAAF4 + 12D15FC213D35DFB00ABAAF4 + 12D15FE813D3634F00ABAAF4 + 12D15FF213D3652300ABAAF4 + 12D15FF313D3652300ABAAF4 + 12D15FF413D3652300ABAAF4 + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {938, 264}} + RubberWindowFrame + 134 119 1146 659 0 0 1280 778 + + Module + PBXNavigatorGroup + Proportion + 264pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 269}, {938, 349}} + RubberWindowFrame + 134 119 1146 659 0 0 1280 778 + + Module + XCDetailModule + Proportion + 349pt + + + Proportion + 938pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + 12D15FF613D3652300ABAAF4 + 1CE0B1FE06471DED0097A5F4 + 12D15FF713D3652300ABAAF4 + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.shortV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 122A5BB81375BA4700795FF0 + 1C530D57069F1CE1000CFCEE + /Developer/Projects/Chameleons/slice/Musya/Chameleon.xcodeproj + + WindowString + 134 119 1146 659 0 0 1280 778 + WindowToolsV3 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {500, 218}} + RubberWindowFrame + 91 232 500 500 0 0 1280 778 + + Module + PBXNavigatorGroup + Proportion + 218pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build Results + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 223}, {500, 236}} + RubberWindowFrame + 91 232 500 500 0 0 1280 778 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 459pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + 122A5BB81375BA4700795FF0 + 12D15FF813D3652300ABAAF4 + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowContentMinSize + 486 300 + WindowString + 91 232 500 500 0 0 1280 778 + WindowToolGUID + 122A5BB81375BA4700795FF0 + WindowToolIsVisible + + + + Identifier + windowTool.debugger + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {317, 164}} + {{317, 0}, {377, 164}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 164}} + {{0, 164}, {694, 216}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleDrawerSize + {100, 120} + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 380}} + RubberWindowFrame + 321 238 694 422 0 0 1440 878 + + Module + PBXDebugSessionModule + Proportion + 100% + + + Proportion + 100% + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CD10A99069EF8BA00B06720 + 1C0AD2AB069F1E9B00FABCE6 + 1C162984064C10D400B95A72 + 1C0AD2AC069F1E9B00FABCE6 + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 321 238 694 422 0 0 1440 878 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + 0 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.find + IsVertical + + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + platform.h + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {843, 431}} + RubberWindowFrame + 562 87 843 689 0 0 1280 778 + + Module + PBXNavigatorGroup + Proportion + 843pt + + + Proportion + 431pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{0, 436}, {843, 212}} + RubberWindowFrame + 562 87 843 689 0 0 1280 778 + + Module + PBXProjectFindModule + Proportion + 212pt + + + Proportion + 648pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + + TableOfContents + + 1C530D57069F1CE1000CFCEE + 12D15FF913D3652300ABAAF4 + 12D15FFA13D3652300ABAAF4 + 1CDD528C0622207200134675 + 1CD0528E0623707200166675 + + WindowString + 562 87 843 689 0 0 1280 778 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + + + + Identifier + MENUSEPARATOR + + + Identifier + windowTool.debuggerConsole + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {650, 250}} + RubberWindowFrame + 516 632 650 250 0 0 1680 1027 + + Module + PBXDebugCLIModule + Proportion + 209pt + + + Proportion + 209pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAAD065D492600B07095 + 1C78EAAE065D492600B07095 + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + 650 41 650 250 0 0 1280 1002 + WindowToolGUID + 1C78EAAD065D492600B07095 + WindowToolIsVisible + 0 + + + Identifier + windowTool.snapshots + Layout + + + Dock + + + Module + XCSnapshotModule + Proportion + 100% + + + Proportion + 100% + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + Yes + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + 315 824 300 550 0 0 1440 878 + WindowToolIsVisible + Yes + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.0950012207031 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + Layout + + + Dock + + + BecomeActive + 1 + GeometryConfiguration + + Frame + {0, 0}, {500, 335} + RubberWindowFrame + {0, 0}, {500, 335} + + Module + XCRefactoringModule + Proportion + 100% + + + Proportion + 100% + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + WindowString + 200 200 500 356 0 0 1920 1200 + + + + Index: branches/slice/trunkM/i386/libsaio/smbios_getters.h =================================================================== --- branches/slice/trunkM/i386/libsaio/smbios_getters.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/smbios_getters.h (revision 1171) @@ -0,0 +1,48 @@ + +#include "libsaio.h" +#include "smbios.h" +#include "platform.h" +#include "pci.h" + +#ifndef __LIBSAIO_SMBIOS_GETTERS_H +#define __LIBSAIO_SMBIOS_GETTERS_H + +#define SMBIOS_RANGE_START 0x000F0000 +#define SMBIOS_RANGE_END 0x000FFFFF + +#define NOT_AVAILABLE "N/A" + +typedef enum { + kSMBString, + kSMBByte, + kSMBWord, + kSMBDWord +// kSMBQWord +} SMBValueType; + +typedef union { + const char *string; + uint8_t byte; + uint16_t word; + uint32_t dword; +// uint64_t qword; +} returnType; + +extern bool getProcessorInformationExternalClock(returnType *value); +extern bool getProcessorInformationMaximumClock(returnType *value); +extern bool getSMBOemProcessorBusSpeed(returnType *value); +extern bool getSMBOemProcessorType(returnType *value); +extern bool getSMBMemoryDeviceMemoryType(returnType *value); +extern bool getSMBMemoryDeviceMemorySpeed(returnType *value); +extern bool getSMBMemoryDeviceManufacturer(returnType *value); +extern bool getSMBMemoryDeviceSerialNumber(returnType *value); +extern bool getSMBMemoryDevicePartNumber(returnType *value); +extern bool scanDMI(void); +extern SMBStructHeader* FindFirstDmiTableOfType(int type, int minlength); +extern SMBStructHeader* FindNextDmiTableOfType(int type, int minlength); +extern void getSmbiosProductName(); + +SMBEntryPoint *getAddressOfSmbiosTable(void); +const char * smbiosStringAtIndex(SMBStructHeader* smHeader, int index, int* length); + +#endif /* !__LIBSAIO_SMBIOS_GETTERS_H */ Index: branches/slice/trunkM/i386/libsaio/fake_efi.h =================================================================== --- branches/slice/trunkM/i386/libsaio/fake_efi.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/fake_efi.h (revision 1171) @@ -0,0 +1,22 @@ +/* + * Copyright 2007 David F. Elliott. All rights reserved. + */ + +#ifndef __LIBSAIO_FAKE_EFI_H +#define __LIBSAIO_FAKE_EFI_H +#include "platform.h" +#include "pci.h" + +/* Set up space for up to 10 configuration table entries */ +#define MAX_CONFIGURATION_TABLE_ENTRIES 10 + +extern void setupFakeEfi(void); +extern void setupSystemType(void); +extern inline uint64_t ptov64(uint32_t addr); +//extern struct SMBEntryPoint * getSmbios(int which); // now cached +//extern void setup_pci_devs(pci_dt_t *pci_dt); //into pci.h +extern uint64_t smbios_p; +extern void scan_cpu_DMI(void); //PlatformInfo_t *); //Slice + + +#endif /* !__LIBSAIO_FAKE_EFI_H */ Index: branches/slice/trunkM/i386/libsaio/xml.c =================================================================== --- branches/slice/trunkM/i386/libsaio/xml.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/xml.c (revision 1171) @@ -0,0 +1,1227 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 2003 Apple Computer, Inc. All Rights + * Reserved. + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 2.0 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include "bootstruct.h" +#include "libsaio.h" +#include "sl.h" +#include "xml.h" + +string_ref *ref_strings = NULL; + +/// TODO: remove below +static char* buffer_start = NULL; +// TODO: redo the next two functions +void SaveRefString(char* string, int id) +{ + //printf("Adding Ref String %d (%s)\n", id, string); + string_ref* tmp = ref_strings; + while(tmp) + { + if(tmp->id == id) + { + tmp->string = malloc(strlen(string)+1); + sprintf(tmp->string, "%s", string); + return; + } + tmp = tmp->next; + } + + string_ref* new_ref = malloc(sizeof(string_ref)); + new_ref->string = malloc(strlen(string)+1); + sprintf(new_ref->string, "%s", string); + new_ref->id = id; + new_ref->next = ref_strings; + ref_strings = new_ref; +} + +char* GetRefString(int id) +{ + string_ref* tmp = ref_strings; + while(tmp) + { + if(tmp->id == id) return tmp->string; + tmp = tmp->next; + } + //verbose("Unable to locate Ref String %d\n", id); + return ""; +} + +struct Module { + struct Module *nextModule; + long willLoad; + TagPtr dict; + char *plistAddr; + long plistLength; + char *driverPath; +}; +typedef struct Module Module, *ModulePtr; + +struct DriverInfo { + char *plistAddr; + long plistLength; + void *moduleAddr; + long moduleLength; +}; +typedef struct DriverInfo DriverInfo, *DriverInfoPtr; + +#define kDriverPackageSignature1 'MKXT' +#define kDriverPackageSignature2 'MOSX' + +struct DriversPackage { + unsigned long signature1; + unsigned long signature2; + unsigned long length; + unsigned long adler32; + unsigned long version; + unsigned long numDrivers; + unsigned long reserved1; + unsigned long reserved2; +}; +typedef struct DriversPackage DriversPackage; + +enum { + kCFBundleType2, + kCFBundleType3 +}; + + +#define DOFREE 1 + +static long ParseTagList(char *buffer, TagPtr *tag, long type, long empty); +static long ParseTagKey(char *buffer, TagPtr *tag); +static long ParseTagString(char *buffer, TagPtr *tag); +static long ParseTagInteger(char *buffer, TagPtr *tag); +static long ParseTagData(char *buffer, TagPtr *tag); +static long ParseTagDate(char *buffer, TagPtr *tag); +static long GetNextTag(char *buffer, char **tag, long *start); +static long FixDataMatchingTag(char *buffer, char *tag); +static TagPtr NewTag(void); +static char *NewSymbol(char *string); +#if DOFREE +static void FreeSymbol(char *string); +#endif + + +//========================================================================== +// XMLGetProperty + +TagPtr +XMLGetProperty( TagPtr dict, const char * key ) +{ + TagPtr tagList, tag; + + if (dict->type != kTagTypeDict) return 0; + + tag = 0; + tagList = dict->tag; + while (tagList) + { + tag = tagList; + tagList = tag->tagNext; + + if ((tag->type != kTagTypeKey) || (tag->string == 0)) continue; + + if (!strcmp(tag->string, key)) return tag->tag; + } + + return 0; +} + +//========================================================================== +// XMLGetProperty + +TagPtr +XMLGetKey( TagPtr dict, int id ) +{ + TagPtr tagList, tag; + + if (dict->type != kTagTypeDict) return 0; + + tag = 0; + int element = 0; + tagList = dict->tag; + while (tagList && element != id) + { + tag = tagList; + tagList = tag->tagNext; + + if ((tag->type != kTagTypeKey) || (tag->string == 0)) continue; + element++; + if(id == element) return tag; + } + return 0; +} + +TagPtr XMLGetValueForKey(TagPtr key) +{ + if (!key || + key->type != kTagTypeKey) return 0; + + return key->tag; +} + + +// XMLGetTag(int index) + +// XMLTagCount( TagPtr dict ) +int XMLTagCount( TagPtr dict ) +{ + int count = 0; + TagPtr tagList, tag; + + if (dict->type != kTagTypeDict && dict->type != kTagTypeArray) return 0; + tag = 0; + tagList = dict->tag; + while (tagList) + { + tag = tagList; + tagList = tag->tagNext; + + if (((tag->type != kTagTypeKey) && ((tag->string == 0) || (tag->string[0] == 0))) + && (dict->type != kTagTypeArray) // If we are an array, any element is valid + ) continue; + + //if(tag->type == kTagTypeKey) printf("Located key %s\n", tag->string); + + count++; + } + + return count; +} + +TagPtr XMLGetElement( TagPtr dict, int id ) +{ + if(dict->type != kTagTypeArray) return 0; + + int element = 0; + TagPtr tmp = dict->tag; + + while(element < id) + { + element++; + tmp = tmp->tagNext; + } + + return tmp; +} +/* 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 +// Expects to see one dictionary in the XML file, the final pos will be returned +// If the pos is not equal to the strlen, then there are multiple dicts +// Puts the first dictionary it finds in the +// tag pointer and returns the end of the dic, or returns -1 if not found. +// +long +XMLParseFile( char * buffer, TagPtr * dict ) +{ + long length, pos; + TagPtr tag; + pos = 0; + char *configBuffer; + + int strlength = strlen(buffer); + configBuffer = malloc(strlength+1); + bcopy(buffer, configBuffer, strlength); + configBuffer[strlength] = 0; + + buffer_start = configBuffer; + + while (1) + { + length = XMLParseNextTag(configBuffer + pos, &tag); + if (length == -1) break; + + pos += length; + + if (tag == 0) continue; + if (tag->type == kTagTypeDict) break; + + XMLFreeTag(tag); + } + free(configBuffer); + if (length < 0) { + return -1; + } + *dict = tag; + return pos; +} +//#endif /* UNUSED */ + +//========================================================================== +// ParseNextTag +// TODO: cleanup +long +XMLParseNextTag( char * buffer, TagPtr * tag ) +{ + long length, pos; + char * tagName; + + length = GetNextTag(buffer, &tagName, 0); + if (length == -1) return -1; + + pos = length; + if (!strncmp(tagName, kXMLTagPList, 6)) + { + length = 0; + } + /***** dict ****/ + else if (!strcmp(tagName, kXMLTagDict)) + { + length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0); + } + else if (!strncmp(tagName, kXMLTagDict, strlen(kXMLTagDict)) && tagName[strlen(tagName)-1] == '/') + { + length = ParseTagList(buffer + pos, tag, kTagTypeDict, 1); + } + else if (!strncmp(tagName, kXMLTagDict " ", strlen(kXMLTagDict " "))) + { + length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0); + } + /***** key ****/ + else if (!strcmp(tagName, kXMLTagKey)) + { + length = ParseTagKey(buffer + pos, tag); + } + + /***** string ****/ + else if (!strcmp(tagName, kXMLTagString)) + { + length = ParseTagString(buffer + pos, tag); + } + else if (!strncmp(tagName, kXMLTagString " ", strlen(kXMLTagString " "))) + { + // TODO: save tag if if found + if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringID, strlen(kXMLStringID))) + { + // ID= + int id = 0; + int cnt = strlen(kXMLTagString " " kXMLStringID "\"") + 1; + while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; + tagName[cnt] = 0; + char* val = tagName + strlen(kXMLTagString " " kXMLStringID "\""); + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + id = (id * 10) + (*val++ - '0'); + } + else + { + printf("ParseStringID error (0x%x)\n", *val); + getchar(); + return -1; + } + } + length = ParseTagString(buffer + pos, tag); + + SaveRefString(buffer + pos, id); + } + else if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringIDRef, strlen(kXMLStringIDRef))) + { + // IDREF= + int id = 0; + int cnt = strlen(kXMLTagString " " kXMLStringIDRef "\"") + 1; + while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; + tagName[cnt] = 0; + char* val = tagName + strlen(kXMLTagString " " kXMLStringIDRef "\""); + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + id = (id * 10) + (*val++ - '0'); + } + else + { + printf("ParseStringIDREF error (0x%x)\n", *val); + getchar(); + return -1; + } + } + char* str = GetRefString(id); + + TagPtr tmpTag = NewTag(); + tmpTag->type = kTagTypeString; + tmpTag->string = str; + tmpTag->tag = 0; + tmpTag->tagNext = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0; + *tag = tmpTag; + + length = 0; + //printf("Located IDREF, id = %d, string = %s\n", id, str); + } + } + + /***** integer ****/ + else if (!strcmp(tagName, kXMLTagInteger)) + { + length = ParseTagInteger(buffer + pos, tag); + } + else if (!strncmp(tagName, kXMLTagInteger " ", strlen(kXMLTagInteger " "))) + { + if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringID, strlen(kXMLStringID))) + { + // ID= + int id = 0; + int cnt = strlen(kXMLTagInteger " " kXMLStringID "\"") + 1; + while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; + tagName[cnt] = 0; + char* val = tagName + strlen(kXMLTagInteger " " kXMLStringID "\""); + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + id = (id * 10) + (*val++ - '0'); + } + else + { + printf("ParseIntegerID error (0x%x)\n", *val); + getchar(); + return -1; + } + } + length = ParseTagInteger(buffer + pos, tag); + + SaveRefString((*tag)->string, id); + } + else if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringIDRef, strlen(kXMLStringIDRef))) + { + // IDREF= + int id = 0; + int cnt = strlen(kXMLTagInteger " " kXMLStringIDRef "\"") + 1; + while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; + tagName[cnt] = 0; + char* val = tagName + strlen(kXMLTagInteger " " kXMLStringIDRef "\""); + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + id = (id * 10) + (*val++ - '0'); + } + else + { + printf("ParseStringIDREF error (0x%x)\n", *val); + getchar(); + return -1; + } + } + int integer = (int)GetRefString(id); + + TagPtr tmpTag = NewTag(); + tmpTag->type = kTagTypeInteger; + tmpTag->string = (char*) integer; + tmpTag->tag = 0; + tmpTag->tagNext = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0; + + *tag = tmpTag; + + length = 0; + //printf("Located IDREF, id = %d, string = %s\n", id, str); + } + else + { + length = ParseTagInteger(buffer + pos, tag); + } + } + + /***** data ****/ + else if (!strcmp(tagName, kXMLTagData)) + { + length = ParseTagData(buffer + pos, tag); + } + else if (!strncmp(tagName, kXMLTagData " ", strlen(kXMLTagData " "))) + { + length = ParseTagData(buffer + pos, tag); + } + else if (!strcmp(tagName, kXMLTagDate)) + { + length = ParseTagDate(buffer + pos, tag); + } + + /***** date ****/ + else if (!strncmp(tagName, kXMLTagDate " ", strlen(kXMLTagDate " "))) + { + length = ParseTagDate(buffer + pos, tag); + } + + /***** false ****/ + else if (!strcmp(tagName, kXMLTagFalse)) + { + length = ParseTagBoolean(buffer + pos, tag, kTagTypeFalse); + } + /***** true ****/ + else if (!strcmp(tagName, kXMLTagTrue)) + { + length = ParseTagBoolean(buffer + pos, tag, kTagTypeTrue); + } + + /***** array ****/ + else if (!strcmp(tagName, kXMLTagArray)) + { + length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0); + } + else if (!strncmp(tagName, kXMLTagArray " ", strlen(kXMLTagArray " "))) + { + length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0); + } + else if (!strcmp(tagName, kXMLTagArray "/")) + { + length = ParseTagList(buffer + pos, tag, kTagTypeArray, 1); + } + + /***** unknown ****/ + else + { + *tag = 0; + length = 0; + } + + if (length == -1) return -1; + + return pos + length; +} + +//========================================================================== +// ParseTagList + +static long +ParseTagList( char * buffer, TagPtr * tag, long type, long empty ) +{ + long length, pos; + TagPtr tagList, tmpTag; + + tagList = 0; + pos = 0; + + if (!empty) + { + while (1) + { + length = XMLParseNextTag(buffer + pos, &tmpTag); + if (length == -1) break; + + pos += length; + + if (tmpTag == 0) break; + tmpTag->tagNext = tagList; + tagList = tmpTag; + } + + if (length == -1) + { + XMLFreeTag(tagList); + return -1; + } + } + + tmpTag = NewTag(); + if (tmpTag == 0) + { + XMLFreeTag(tagList); + return -1; + } + + tmpTag->type = type; + tmpTag->string = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start : 0; + tmpTag->tag = tagList; + tmpTag->tagNext = 0; + + *tag = tmpTag; + + return pos; +} + +//========================================================================== +// ParseTagKey + +static long +ParseTagKey( char * buffer, TagPtr * tag ) +{ + long length, length2; + char *string; + TagPtr tmpTag, subTag; + + length = FixDataMatchingTag(buffer, kXMLTagKey); + if (length == -1) return -1; + + length2 = XMLParseNextTag(buffer + length, &subTag); + if (length2 == -1) return -1; + + tmpTag = NewTag(); + if (tmpTag == 0) + { + XMLFreeTag(subTag); + return -1; + } + + string = NewSymbol(buffer); + if (string == 0) + { + XMLFreeTag(subTag); + XMLFreeTag(tmpTag); + return -1; + } + + tmpTag->type = kTagTypeKey; + tmpTag->string = string; + tmpTag->tag = subTag; + tmpTag->offset = buffer_start ? buffer - buffer_start: 0; + tmpTag->tagNext = 0; + + *tag = tmpTag; + + return length + length2; +} + +//========================================================================== +// ParseTagString + +static long +ParseTagString( char * buffer, TagPtr * tag ) +{ + long length; + char * string; + TagPtr tmpTag; + + length = FixDataMatchingTag(buffer, kXMLTagString); + if (length == -1) return -1; + + tmpTag = NewTag(); + if (tmpTag == 0) return -1; + + string = NewSymbol(buffer); + if (string == 0) + { + XMLFreeTag(tmpTag); + return -1; + } + + tmpTag->type = kTagTypeString; + tmpTag->string = string; + tmpTag->tag = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start: 0; + tmpTag->tagNext = 0; + + *tag = tmpTag; + return length; +} + +//========================================================================== +// ParseTagInteger + +static long +ParseTagInteger( char * buffer, TagPtr * tag ) +{ + long length, integer; + bool negative = false; + TagPtr tmpTag; + char* val = buffer; + int size; + + size = length = FixDataMatchingTag(buffer, kXMLTagInteger); + if (length == -1) return -1; + + tmpTag = NewTag(); + if (tmpTag == 0) return -1; + + integer = 0; + + if(buffer[0] == '<') + { + verbose("Warning integer is non existant\n"); + //getc(); + tmpTag->type = kTagTypeInteger; + tmpTag->string = 0; + tmpTag->tag = 0; + tmpTag->offset = 0; + tmpTag->tagNext = 0; + + *tag = tmpTag; + + return 0; + } + + + if(size > 1 && (val[1] == 'x' || val[1] == 'X')) // Hex value + { + val += 2; + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + integer = (integer * 16) + (*val++ - '0'); + } + else if ((*val >= 'a' && *val <= 'f')) // a - f + { + integer = (integer * 16) + (*val++ - 'a' + 10); + } + else if ((*val >= 'A' && *val <= 'F')) // A - F + { + integer = (integer * 16) + (*val++ - 'a' + 10); + } + else + { + printf("ParseTagInteger hex error (0x%x) in buffer %s\n", *val, buffer); + getchar(); + return -1; + } + } + } + else if ( size ) // Decimal value + { + if (*val == '-') + { + negative = true; + val++; + size--; + } + + for (integer = 0; size > 0; size--) + { + if(*val) // UGLY HACK, fix me. + { + if (*val < '0' || *val > '9') + { + printf("ParseTagInteger decimal error (0x%x) in buffer %s\n", *val, buffer); + getchar(); + return -1; + } + + integer = (integer * 10) + (*val++ - '0'); + } + } + + if (negative) + integer = -integer; + } + + tmpTag->type = kTagTypeInteger; + tmpTag->string = (char *)integer; + tmpTag->tag = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start: 0; + tmpTag->tagNext = 0; + + *tag = tmpTag; + + return length; +} + +//========================================================================== +// ParseTagData + +static long +ParseTagData( char * buffer, TagPtr * tag ) +{ + long length; + TagPtr tmpTag; + + length = FixDataMatchingTag(buffer, kXMLTagData); + if (length == -1) return -1; + + tmpTag = NewTag(); + if (tmpTag == 0) return -1; + + //printf("ParseTagData unimplimented\n"); + //printf("Data: %s\n", buffer); + // getchar(); + + // TODO: base64 decode + + char* string = NewSymbol(buffer); + tmpTag->type = kTagTypeData; + tmpTag->string = string; + tmpTag->tag = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start: 0; + tmpTag->tagNext = 0; + + *tag = tmpTag; + + return length; +} + +//========================================================================== +// ParseTagDate + +static long +ParseTagDate( char * buffer, TagPtr * tag ) +{ + long length; + TagPtr tmpTag; + + length = FixDataMatchingTag(buffer, kXMLTagDate); + if (length == -1) return -1; + + tmpTag = NewTag(); + if (tmpTag == 0) return -1; + + printf("ParseTagDate unimplimented\n"); + getchar(); + + tmpTag->type = kTagTypeDate; + tmpTag->string = 0; + tmpTag->tag = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start: 0; + tmpTag->tagNext = 0; + + *tag = tmpTag; + + return length; +} + +//========================================================================== +// ParseTagBoolean + +long +ParseTagBoolean( char * buffer, TagPtr * tag, long type ) +{ + TagPtr tmpTag; + + tmpTag = NewTag(); + if (tmpTag == 0) return -1; + + tmpTag->type = type; + tmpTag->string = 0; + tmpTag->tag = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start: 0; + tmpTag->tagNext = 0; + + *tag = tmpTag; + + return 0; +} + +//========================================================================== +// GetNextTag + +static long +GetNextTag( char * buffer, char ** tag, long * start ) +{ + long cnt, cnt2; + + if (tag == 0) return -1; + + // Find the start of the tag. + cnt = 0; + while ((buffer[cnt] != '\0') && (buffer[cnt] != '<')) cnt++; + if (buffer[cnt] == '\0') return -1; + + // Find the end of the tag. + cnt2 = cnt + 1; + while ((buffer[cnt2] != '\0') && (buffer[cnt2] != '>')) cnt2++; + if (buffer[cnt2] == '\0') return -1; + + // Fix the tag data. + *tag = buffer + cnt + 1; + buffer[cnt2] = '\0'; + if (start) *start = cnt; + + return cnt2 + 1; +} + +//========================================================================== +// FixDataMatchingTag +// Modifies 'buffer' to add a '\0' at the end of the tag matching 'tag'. +// Returns the length of the data found, counting the end tag, +// or -1 if the end tag was not found. + +static long +FixDataMatchingTag( char * buffer, char * tag ) +{ + long length, start, stop; + char * endTag; + + start = 0; + while (1) + { + length = GetNextTag(buffer + start, &endTag, &stop); + if (length == -1) return -1; + + if ((*endTag == '/') && !strcmp(endTag + 1, tag)) break; + start += length; + } + + buffer[start + stop] = '\0'; + + return start + length; +} + +//========================================================================== +// NewTag + +#define kTagsPerBlock (0x1000) + +static TagPtr gTagsFree; + +static TagPtr +NewTag( void ) +{ + long cnt; + TagPtr tag; + + if (gTagsFree == 0) + { + tag = (TagPtr)malloc(kTagsPerBlock * sizeof(Tag)); + if (tag == 0) return 0; + + // Initalize the new tags. + for (cnt = 0; cnt < kTagsPerBlock; cnt++) + { + tag[cnt].type = kTagTypeNone; + tag[cnt].string = 0; + tag[cnt].tag = 0; + tag[cnt].tagNext = tag + cnt + 1; + } + tag[kTagsPerBlock - 1].tagNext = 0; + + gTagsFree = tag; + } + + tag = gTagsFree; + gTagsFree = tag->tagNext; + + return tag; +} + +//========================================================================== +// XMLFreeTag + +void +XMLFreeTag( TagPtr tag ) +{ +#if DOFREE + if (tag == 0) return; + + if (tag->string) FreeSymbol(tag->string); + + XMLFreeTag(tag->tag); + XMLFreeTag(tag->tagNext); + + // Clear and free the tag. + tag->type = kTagTypeNone; + tag->string = 0; + tag->tag = 0; + tag->offset = 0; + tag->tagNext = gTagsFree; + gTagsFree = tag; +#else + return; +#endif +} + +//========================================================================== +// Symbol object. + +struct Symbol +{ + long refCount; + struct Symbol *next; + char string[]; +}; +typedef struct Symbol Symbol, *SymbolPtr; + +static SymbolPtr FindSymbol(char * string, SymbolPtr * prevSymbol); + +static SymbolPtr gSymbolsHead; + +//========================================================================== +// NewSymbol + +static char * +NewSymbol( char * string ) +{ +static SymbolPtr lastGuy = 0; + SymbolPtr symbol; + + // Look for string in the list of symbols. + symbol = FindSymbol(string, 0); + + // Add the new symbol. + if (symbol == 0) + { + symbol = (SymbolPtr)malloc(sizeof(Symbol) + 1 + strlen(string)); + if (symbol == 0) //return 0; + stop("NULL symbol!"); + + // Set the symbol's data. + symbol->refCount = 0; + strcpy(symbol->string, string); + + // Add the symbol to the list. + symbol->next = gSymbolsHead; + gSymbolsHead = symbol; + } + + // Update the refCount and return the string. + symbol->refCount++; + + if (lastGuy && lastGuy->next != 0) stop("last guy not last!"); + return symbol->string; +} + +//========================================================================== +// FreeSymbol + +#if DOFREE +static void +FreeSymbol( char * string ) +{ + SymbolPtr symbol, prev; + prev = 0; + + // Look for string in the list of symbols. + symbol = FindSymbol(string, &prev); + if (symbol == 0) return; + + // Update the refCount. + symbol->refCount--; + + if (symbol->refCount != 0) return; + + // Remove the symbol from the list. + if (prev != 0) prev->next = symbol->next; + else gSymbolsHead = symbol->next; + + // Free the symbol's memory. + free(symbol); +} +#endif + +//========================================================================== +// FindSymbol + +static SymbolPtr +FindSymbol( char * string, SymbolPtr * prevSymbol ) +{ + SymbolPtr symbol, prev; + + symbol = gSymbolsHead; + prev = 0; + + while (symbol != 0) { + if (!strcmp(symbol->string, string)) break; + + prev = symbol; + symbol = symbol->next; + } + + if ((symbol != 0) && (prevSymbol != 0)) *prevSymbol = prev; + + return symbol; +} + +bool XMLIsType(TagPtr dict, enum xmltype type) +{ + if(!dict) return (type == kTagTypeNone); + return (dict->type == type); +} + +/*** Cast functions ***/ +bool XMLIsArray(TagPtr entry) +{ + return entry && (entry->type == kTagTypeArray); +} + +TagPtr XMLCastArray(TagPtr dict) +{ + if(!dict) return NULL; + if(dict->type == kTagTypeArray) return dict; + else return NULL; +} + +bool XMLIsDict(TagPtr entry) +{ + return entry && (entry->type == kTagTypeDict); +} + + +TagPtr XMLCastDict(TagPtr dict) +{ + if(!dict) return NULL; + if(dict->type == kTagTypeDict) return dict; + else return NULL; +} + +bool XMLIsString(TagPtr entry) +{ + return entry && + ((entry->type == kTagTypeString) || + (entry->type == kTagTypeKey)); +} + +char* XMLCastString(TagPtr dict) +{ + if(!dict) return NULL; + + if((dict->type == kTagTypeString) || + (dict->type == kTagTypeKey)) return dict->string; + + return NULL; +} + +long XMLCastStringOffset(TagPtr dict) +{ + if(dict && + ((dict->type == kTagTypeString) || + (dict->type == kTagTypeKey))) + { + return dict->offset; + } + else + { + return -1; + } +} + +bool XMLIsBoolean(TagPtr entry) +{ + return entry && + ((entry->type == kTagTypeTrue) || + (entry->type == kTagTypeFalse)); +} + +bool XMLCastBoolean(TagPtr dict) +{ + if(!dict) return false; + if(dict->type == kTagTypeTrue) return true; + return false; +} + +bool XMLIsInteger(TagPtr entry) +{ + return entry && (entry->type == kTagTypeInteger); +} + +int XMLCastInteger(TagPtr dict) +{ + if(!dict) + { + //printf("XMLCastInteger: null dict\n"); + return 0; + } + if(dict->type == kTagTypeInteger) return (int)(dict->string); + return 0; +} + +bool XMLAddTagToDictionary(TagPtr dict, char* key, TagPtr value) +{ + if (!dict || dict->type != kTagTypeDict) return false; + + TagPtr tmpTag; + char* string; + + tmpTag = NewTag(); + if (tmpTag == 0) + { + return false; + } + + string = NewSymbol(key); + if (string == 0) + { + XMLFreeTag(tmpTag); + return false; + } + + tmpTag->type = kTagTypeKey; + tmpTag->string = string; + tmpTag->tag = value; + tmpTag->offset = 0; + tmpTag->tagNext = 0; + + TagPtr tagList = dict->tag; + if(!tagList) + { + // First tag + dict->tag = tmpTag; + return true; + } + while(tagList && tagList->tagNext) tagList = tagList->tagNext; + if(tagList) + { + tagList->tagNext = tmpTag; + return true; + } + return false; +} \ No newline at end of file Index: branches/slice/trunkM/i386/libsaio/asm.s =================================================================== --- branches/slice/trunkM/i386/libsaio/asm.s (revision 0) +++ branches/slice/trunkM/i386/libsaio/asm.s (revision 1171) @@ -0,0 +1,497 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Mach Operating System + * Copyright (c) 1990 Carnegie-Mellon University + * Copyright (c) 1989 Carnegie-Mellon University + * All rights reserved. The CMU software License Agreement specifies + * the terms and conditions for use and redistribution. + */ +/* + * HISTORY + * $Log: asm.s,v $ + * Revision 1.8 2005/06/24 22:47:12 curtisg + * Merging changes for 4159531 to pass data to the kernel in EFI format. + * + * Revision 1.7 2004/05/13 17:58:38 curtisg + * Integrating: + * : (Silent boot) + * : (5 sec boot timeout is too short) + * : (Boot option to display graphics modes) + * : (Default graphics mode should be 32-bit) + * : (Booter should always find a video mode) + * : (Booter displays "0MB" VRAM) + * + * Revision 1.6 2003/11/05 20:51:02 curtisg + * Integrated 3069695,3331770,3370488,3371823 + * + * Revision 1.5.26.1 2003/10/27 23:57:59 curtisg + * Added printing of volume names, better handling of extended + * partitions, and updated Apple license strings. + * New chain booter should work better with foreign operating + * systems. + * + * Revision 1.5 2002/11/05 20:34:26 jliu + * Integrating: + * 3051234 boot shouldnt require Graphics = Yes + * 3091627 Need support for refresh rate adjustment + * + * Revision 1.4 2002/10/02 00:06:18 curtisg + * Integrating PR-3032510. + * + * Revision 1.3.6.1 2002/08/30 21:16:29 curtisg + * KERNBOOTSTRUCT is going away in favor of KernelBootArgs_t in . + * + * Revision 1.3 2002/07/09 14:06:21 jliu + * Merging changes from PR-2954224 branch in boot/i386. + * + * Revision 1.2.30.1 2002/07/05 16:24:51 jliu + * Merged UFS/HFS/HFS+ filesystem support from BootX. + * Moved boot2 load address due to increased size. boot0/boot1 also changed. + * Updated boot graphics and CLUT. + * Added support to chain load foreign booters. + * Fixed param passing bug in network loader. + * Misc cleanup in libsaio. + * + * Revision 1.2 2000/05/23 23:01:11 lindak + * Merged PR-2309530 into Kodiak (liu i386 booter: does not support label-less + * ufs partitions) + * + * Revision 1.1.1.2.4.1 2000/05/13 17:07:39 jliu + * New boot0 (boot1 has been deprecated). Booter must now reside in its own partition, no disk label required. + * + * Revision 1.1.1.2 1999/08/04 21:16:57 wsanchez + * Impoort of boot-66 + * + * Revision 1.3 1999/08/04 21:12:12 wsanchez + * Update APSL + * + * Revision 1.2 1999/03/25 05:48:30 wsanchez + * Add APL. + * Remove unused gzip code. + * Remove unused Adobe fonts. + * + * Revision 1.1.1.1.66.2 1999/03/16 16:08:54 wsanchez + * Substitute License + * + * Revision 1.1.1.1.66.1 1999/03/16 07:33:21 wsanchez + * Add APL + * + * Revision 1.1.1.1 1997/12/05 21:57:57 wsanchez + * Import of boot-25 (~mwatson) + * + * Revision 2.1.1.2 90//03//22 17:59:50 rvb + * Added _sp() => where is the stack at. [kupfer] + * + * Revision 2.1.1.1 90//02//09 17:25:04 rvb + * Add Intel copyright + * [90//02//09 rvb] + * + */ + + +// INTEL CORPORATION PROPRIETARY INFORMATION +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Intel Corporation and may not be copied +// nor disclosed except in accordance with the terms of that agreement. +// +// Copyright 1988 Intel Corporation +// Copyright 1988, 1989 by Intel Corporation +// + +#include +#include "memory.h" + +#define data32 .byte 0x66 +#define addr32 .byte 0x67 + + .file "asm.s" + +CR0_PE_ON = 0x1 +#ifdef BOOT1 +CR0_PE_OFF = 0x7ffffffe +#else +CR0_PE_OFF = 0x7ffffff0 +#endif + +STACK32_BASE = ADDR32(STACK_SEG, 0) +STACK16_SEG = STACK_SEG +CODE32_BASE = ADDR32(BASE_SEG, 0) +CODE16_SEG = BASE_SEG + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Pointer to 6-bytes in memory that contains the base address and the limit +// (size of GDT table in bytes) of the GDT. The LGDT is the only instruction +// that directly loads a linear address (not a segment relative address) and +// a limit in protected mode. + +.globl _Gdtr + //.data + .section __INIT,__data // turbo - Data that must be in the first segment + .align 2, 0x90 +_Gdtr: + .word GDTLIMIT + .long vtop(_Gdt) + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// IDTR representing real-mode IVT. The values are constant. + //.const + .section __INIT,__data // turbo - Data that must be in the first segment +// Real mode IDT + .align 2 +.globl _Idtr_real +_Idtr_real: + .word 0x03ff + .long 0x00000000 + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// IDTR representing protected-mode IDT. It is initially NULL which tells the +// procesor that no IDT is available. After we get into protected mode we can +// allocate memory for a proper IDT and update this IDTR to point to it. + //.data + .section __INIT,__data // turbo - Data that must be in the first segment + .align 2 +.globl _Idtr_prot +_Idtr_prot: + .word 0 + .long 0 + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Data area for __switch_stack. +// +save_sp: .long STACK_OFS +save_ss: .long STACK_SEG + + //.text + .section __INIT,__text // turbo - This code must reside within the first segment +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// real_to_prot() +// +// Transfer from real mode to protected mode. +// Preserves all registers except EAX. +// +LABEL(__real_to_prot) + + // Interrupts are disabled in protected mode. + + cli + + // Load the Global Descriptor Table Register (GDTR). + + addr32 + data32 + lgdt OFFSET16(_Gdtr) + + // Enter protected mode by setting the PE bit in CR0. + + mov %cr0, %eax + data32 + or $CR0_PE_ON, %eax + mov %eax, %cr0 + + // Make intrasegment jump to flush the processor pipeline and + // reload CS register. + + data32 + ljmp $0x08, $xprot + +xprot: + // we are in USE32 mode now + // set up the protected mode segment registers : DS, SS, ES, FS, GS + + mov $0x10, %eax + movw %ax, %ds + movw %ax, %ss + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + + // set up the PM IDT + lidt _Idtr_prot + + // Convert STACK_SEG:SP to 32-bit linear stack pointer. + + movzwl %sp, %eax + addl $STACK32_BASE, %eax + movl %eax, %esp + + // Convert STACK_SEG:BP to 32-bit linear base pointer. + + movzwl %bp, %eax + addl $STACK32_BASE, %eax + movl %eax, %ebp + + // Modify the caller's return address on the stack from + // segment offset to linear address. + + popl %eax + addl $CODE32_BASE, %eax + pushl %eax + + ret + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// prot_to_real() +// +// Transfer from protected mode to real mode. +// Preserves all registers except EAX. +// +LABEL(__prot_to_real) + + // Load real-mode IDT while we're still in USE32 mode so we don't need + // 32-bit addressing prefixes. + lidt _Idtr_real + + // Set up segment registers appropriate for real mode. + + movw $0x30, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + ljmp $0x18, $x16 // change to USE16 mode + +x16: + mov %cr0, %eax // clear the PE bit of CR0 + data32 + and $CR0_PE_OFF, %eax + mov %eax, %cr0 + + // make intersegment jmp to flush the processor pipeline + // and reload CS register + + data32 + ljmp $CODE16_SEG, $xreal - CODE32_BASE + +xreal: + // we are in real mode now + // set up the real mode segment registers : DS, DS, ES, FS, GS + + movw %cs, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + + // load stack segment register SS. + + data32 + movl $STACK16_SEG, %eax + movw %ax, %ss + + // clear top 16-bits of ESP and EBP. + + data32 + movzwl %sp, %esp + data32 + movzwl %bp, %ebp + + // Modify caller's return address on the stack + // from linear address to segment offset. + + data32 + popl %eax + data32 + movzwl %ax, %eax + data32 + pushl %eax + + // Reenable maskable interrupts. + + sti + + data32 + ret + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// halt() +// +LABEL(_halt) +#ifdef BOOT1 + hlt +#else + call _bgetc +#endif + jmp _halt + +#ifndef BOOT1 +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// startprog(phyaddr, arg) +// Start the program on protected mode where phyaddr is the entry point. +// Passes arg to the program in %eax. +// +LABEL(_startprog) + push %ebp + mov %esp, %ebp + + mov 0xc(%ebp), %eax // argument to program + mov 0x8(%ebp), %ecx // entry offset + mov $0x28, %ebx // segment + push %ebx + push %ecx + + // set up %ds and %es + + mov $0x20, %ebx + movw %bx, %ds + movw %bx, %es + + lret +#endif + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Returns the current stack pointer. +// +LABEL(__sp) + mov %esp, %eax + ret + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Returns the current frame pointer. +// +LABEL(__bp) + mov %ebp, %eax + ret + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// switch_stack() +// +// Switches stack pointer between SS:SP and memory save_ss:save_sp. +// Call this function from real mode only!!! +// +// AX, DI, and SI are clobbered. +// +LABEL(__switch_stack) + popl %eax # save return address + popl %edi # discard upper 16-bit + + data32 + addr32 + movl OFFSET16(save_ss), %esi # new SS to SI + + data32 + addr32 + movl OFFSET16(save_sp), %edi # new SP to DI + + addr32 + mov %ss, OFFSET16(save_ss) # save current SS to memory + + data32 + addr32 + movl %esp, OFFSET16(save_sp) # save current SP to memory + + cli + mov %si, %ss # switch stack + mov %di, %sp + sti + + pushl %eax # push IP of caller onto the new stack + + xorl %eax, %eax + xorl %esi, %esi + xorl %edi, %edi + + ret + +#ifndef BOOT1 +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// loader() +// +// Issue a request to the network loader. +// +LABEL(_loader) + enter $0, $0 + pushal + + # + # Pass a far pointer to the command structure + # to the INT call through DX:CX. + # + # The command code is in BX. + # + + movw 8(%ebp), %bx # 8[EBP] = command code + movw 12(%ebp), %cx # 12[EBP] = command structure offset + movw 14(%ebp), %dx # 14[EBP] = command structure segment + + call __prot_to_real # Revert to real mode + + ###### Real Mode Begin ###### + + data32 + call __switch_stack # Switch to NBP stack + + int $0x2b # Call NBP + + data32 + call __switch_stack # Restore stack + + data32 + call __real_to_prot # Back to protected mode + + ###### Real Mode End ###### + + popal + leave + ret +#endif + +#if UNUSED +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// pcpy(src, dst, cnt) +// where src is a virtual address and dst is a physical address +// +LABEL(_pcpy) + push %ebp + mov %esp, %ebp + push %es + push %esi + push %edi + push %ecx + + cld + + // set %es to point at the flat segment + + mov $0x20, %eax + movw %ax , %es + + mov 0x8(%ebp), %esi // source + mov 0xc(%ebp), %edi // destination + mov 0x10(%ebp), %ecx // count + + rep + movsb + + pop %ecx + pop %edi + pop %esi + pop %es + pop %ebp + + ret +#endif Index: branches/slice/trunkM/i386/libsaio/console.c =================================================================== --- branches/slice/trunkM/i386/libsaio/console.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/console.c (revision 1171) @@ -0,0 +1,267 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Mach Operating System + * Copyright (c) 1990 Carnegie-Mellon University + * Copyright (c) 1989 Carnegie-Mellon University + * All rights reserved. The CMU software License Agreement specifies + * the terms and conditions for use and redistribution. + */ + +/* + * INTEL CORPORATION PROPRIETARY INFORMATION + * + * This software is supplied under the terms of a license agreement or + * nondisclosure agreement with Intel Corporation and may not be copied + * nor disclosed except in accordance with the terms of that agreement. + * + * Copyright 1988, 1989 Intel Corporation + */ + +/* + * Copyright 1993 NeXT, Inc. + * All rights reserved. + */ + +#include "libsaio.h" +#include "bootstruct.h" +#include + +extern int vprf(const char * fmt, va_list ap); + +bool gVerboseMode; +bool gErrors; + +/* + * Azi: Doubled available log size; this seems to fix some hangs and instant reboots caused by + * booting with -f (ignore caches). 96kb are enough to hold full log, booting with -f; even so, + * this depends on how much we "play" at the boot prompt and with what patches we're playing, + * depending on how much they print to the log. + * + * Kabyl: BooterLog + */ +#define BOOTER_LOG_SIZE (128 * 1024) +#define SAFE_LOG_SIZE 134 + +char *msgbuf = 0; +char *cursor = 0; + +struct putc_info //Azi: exists on gui.c & printf.c +{ + char * str; + char * last_str; +}; + +static int +sputc(int c, struct putc_info * pi) //Azi: same as above +{ + if (pi->last_str) + if (pi->str == pi->last_str) + { + *(pi->str) = '\0'; + return 0; + } + *(pi->str)++ = c; + return c; +} + +void initBooterLog(void) +{ + msgbuf = malloc(BOOTER_LOG_SIZE); + bzero(msgbuf, BOOTER_LOG_SIZE); + cursor = msgbuf; + msglog("%s\n", "Chameleon " I386BOOT_CHAMELEONVERSION " (svn-r" I386BOOT_CHAMELEONREVISION ")" " [" I386BOOT_BUILDDATE "]"); +} + +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 + */ +int putchar(int c) +{ + if ( c == '\t' ) + { + for (c = 0; c < 8; c++) bios_putchar(' '); + return c; + } + + if ( c == '\n' ) + { + bios_putchar('\r'); + } + + bios_putchar(c); + + return c; +} + +int getc() +{ + int c = bgetc(); + + if ((c & 0xff) == 0) + return c; + else + return (c & 0xff); +} + +// Read and echo a character from console. This doesn't echo backspace +// since that screws up higher level handling + +int getchar() +{ + register int c = getc(); + +// if ( c == '\r' ) c = '\n'; + +// if ( c >= ' ' && c < 0x7f) putchar(c); + + return (c); +} + +int printf(const char * fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (bootArgs->Video.v_display == VGA_TEXT_MODE) + 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; +} + +int verbose(const char * fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (gVerboseMode) + { + if (bootArgs->Video.v_display == VGA_TEXT_MODE) + 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); +} + +int error(const char * fmt, ...) +{ + va_list ap; + gErrors = true; + va_start(ap, fmt); + if (bootArgs->Video.v_display == VGA_TEXT_MODE) + prf(fmt, ap, putchar, 0); + else + vprf(fmt, ap); + va_end(ap); + return(0); +} + +void stop(const char * fmt, ...) +{ + va_list ap; + + printf("\n"); + va_start(ap, fmt); + if (bootArgs->Video.v_display == VGA_TEXT_MODE) { + prf(fmt, ap, putchar, 0); + } else { + vprf(fmt, ap); + } + va_end(ap); + printf("\nThis is a non recoverable error! System HALTED!!!"); + halt(); + while (1); +} + +/** Print a "Press a key to continue..." message and wait for a key press. */ +void pause() +{ + printf("Press a key to continue...\n"); + getchar(); // replace getchar() by pause() were useful. +} Index: branches/slice/trunkM/i386/libsaio/xml.h =================================================================== --- branches/slice/trunkM/i386/libsaio/xml.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/xml.h (revision 1171) @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __LIBSAIO_XML_H +#define __LIBSAIO_XML_H + +enum xmltype { + kTagTypeNone = 0, + kTagTypeDict, + kTagTypeKey, + kTagTypeString, + kTagTypeInteger, + kTagTypeData, + kTagTypeDate, + kTagTypeFalse, + kTagTypeTrue, + kTagTypeArray +}; + +struct string_ref +{ + char* string; + int id; + struct string_ref* next; +}; +typedef struct string_ref string_ref; + +extern string_ref* ref_strings; + +#define kXMLTagPList "plist " +#define kXMLTagDict "dict" +#define kXMLTagKey "key" +#define kXMLTagString "string" +#define kXMLTagInteger "integer" +#define kXMLTagData "data" +#define kXMLTagDate "date" +#define kXMLTagFalse "false/" +#define kXMLTagTrue "true/" +#define kXMLTagArray "array" + +#define kXMLStringID "ID=" +#define kXMLStringIDRef "IDREF=" + +#define kPropCFBundleIdentifier ("CFBundleIdentifier") +#define kPropCFBundleExecutable ("CFBundleExecutable") +#define kPropOSBundleRequired ("OSBundleRequired") +#define kPropOSBundleLibraries ("OSBundleLibraries") +#define kPropIOKitPersonalities ("IOKitPersonalities") +#define kPropIONameMatch ("IONameMatch") + +/* +struct Tag { + long type; + char *string; + struct Tag *tag; + struct Tag *tagNext; +}; +typedef struct Tag Tag, *TagPtr; + */ + +extern long gImageFirstBootXAddr; +extern long gImageLastKernelAddr; + +TagPtr XMLGetProperty( TagPtr dict, const char * key ); +TagPtr XMLGetElement( TagPtr dict, int id ); +TagPtr XMLGetKey( TagPtr dict, int id ); +TagPtr XMLGetValueForKey(TagPtr key); + +int XMLTagCount( TagPtr dict ); + +bool XMLIsType(TagPtr dict, enum xmltype type); + +bool XMLCastBoolean( TagPtr dict ); +char* XMLCastString( TagPtr dict ); +long XMLCastStringOffset(TagPtr dict); +int XMLCastInteger ( TagPtr dict ); +TagPtr XMLCastDict ( TagPtr dict ); +TagPtr XMLCastArray( TagPtr dict ); + +bool XMLIsBoolean(TagPtr entry); +bool XMLIsString (TagPtr entry); +bool XMLIsInteger(TagPtr entry); +bool XMLIsDict (TagPtr entry); +bool XMLIsArray (TagPtr entry); + + +bool XMLAddTagToDictionary(TagPtr dict, char* key, TagPtr value); + +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. +// Puts the first dictionary it finds in the +// tag pointer and returns 0, or returns -1 if not found. +// +long XMLParseFile( char * buffer, TagPtr * dict ); + +//========================================================================== +// ParseTag* +long ParseTagBoolean( char * buffer, TagPtr * tag, long type ); + + +#endif /* __LIBSAIO_XML_H */ Index: branches/slice/trunkM/i386/libsaio/bootstruct.c =================================================================== --- branches/slice/trunkM/i386/libsaio/bootstruct.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/bootstruct.c (revision 1171) @@ -0,0 +1,214 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright 1993 NeXT, Inc. + * All rights reserved. + */ + +#include "libsaio.h" +#include "bootstruct.h" + +/*========================================================================== + * Initialize the structure of parameters passed to + * the kernel by the booter. + */ + +boot_args *bootArgs; +boot_args_pre_lion *bootArgsPreLion; +PrivateBootInfo_t *bootInfo; +Node *gMemoryMapNode; + +static char platformName[64]; + +void initKernBootStruct( void ) +{ + Node *node; + int nameLen; + static int init_done = 0; + + if ( !init_done ) + { + bootArgs = (boot_args *)malloc(sizeof(boot_args)); + bootArgsPreLion = (boot_args_pre_lion *)malloc(sizeof(boot_args_pre_lion)); + bootInfo = (PrivateBootInfo_t *)malloc(sizeof(PrivateBootInfo_t)); + if (bootArgs == 0 || bootInfo == 0) + stop("Couldn't allocate boot info\n"); + + bzero(bootArgs, sizeof(boot_args)); + bzero(bootArgsPreLion, sizeof(boot_args_pre_lion)); + bzero(bootInfo, sizeof(PrivateBootInfo_t)); + + // Get system memory map. Also update the size of the + // conventional/extended memory for backwards compatibility. + + bootInfo->memoryMapCount = + getMemoryMap( bootInfo->memoryMap, kMemoryMapCountMax, + (unsigned long *) &bootInfo->convmem, + (unsigned long *) &bootInfo->extmem ); + + if ( bootInfo->memoryMapCount == 0 ) + { + // BIOS did not provide a memory map, systems with + // discontiguous memory or unusual memory hole locations + // may have problems. + + bootInfo->convmem = getConventionalMemorySize(); + bootInfo->extmem = getExtendedMemorySize(); + } + + bootInfo->configEnd = bootInfo->config; + bootArgs->Video.v_display = VGA_TEXT_MODE; + + DT__Initialize(); + + node = DT__FindNode("/", true); + if (node == 0) { + stop("Couldn't create root node"); + } + getPlatformName(platformName); + nameLen = strlen(platformName) + 1; + DT__AddProperty(node, "compatible", nameLen, platformName); + DT__AddProperty(node, "model", nameLen, platformName); + + gMemoryMapNode = DT__FindNode("/chosen/memory-map", true); + + bootArgs->Version = kBootArgsVersion; + bootArgs->Revision = kBootArgsRevision; + + bootArgsPreLion->Version = kBootArgsPreLionVersion; + bootArgsPreLion->Revision = kBootArgsPreLionRevision; + + init_done = 1; + } +} + + +/* Copy boot args after kernel and record address. */ + +void +reserveKernBootStruct(void) +{ + if ((gMacOSVersion[0] == '1') && (gMacOSVersion[1] == '0') + && (gMacOSVersion[2] == '.') && (gMacOSVersion[3] == '7')) + { + void *oldAddr = bootArgs; + bootArgs = (boot_args *)AllocateKernelMemory(sizeof(boot_args)); + bcopy(oldAddr, bootArgs, sizeof(boot_args)); + } + else + { + void *oldAddr = bootArgsPreLion; + bootArgsPreLion = (boot_args_pre_lion *)AllocateKernelMemory(sizeof(boot_args_pre_lion)); + bcopy(oldAddr, bootArgsPreLion, sizeof(boot_args_pre_lion)); + } +} + +void +finalizeBootStruct(void) +{ + uint32_t size; + void *addr; + int i; + EfiMemoryRange *memoryMap; + MemoryRange *range; + int memoryMapCount = bootInfo->memoryMapCount; + + if (memoryMapCount == 0) { + // XXX could make a two-part map here + stop("Unable to convert memory map into proper format\n"); + } + + // convert memory map to boot_args memory map + memoryMap = (EfiMemoryRange *)AllocateKernelMemory(sizeof(EfiMemoryRange) * memoryMapCount); + bootArgs->MemoryMap = (uint32_t)memoryMap; + bootArgs->MemoryMapSize = sizeof(EfiMemoryRange) * memoryMapCount; + bootArgs->MemoryMapDescriptorSize = sizeof(EfiMemoryRange); + bootArgs->MemoryMapDescriptorVersion = 0; + + for (i=0; imemoryMap[i]; + switch(range->type) { + case kMemoryRangeACPI: + memoryMap->Type = kEfiACPIReclaimMemory; + break; + case kMemoryRangeNVS: + memoryMap->Type = kEfiACPIMemoryNVS; + break; + case kMemoryRangeUsable: + memoryMap->Type = kEfiConventionalMemory; + break; + case kMemoryRangeReserved: + default: + memoryMap->Type = kEfiReservedMemoryType; + break; + } + memoryMap->PhysicalStart = range->base; + memoryMap->VirtualStart = range->base; + memoryMap->NumberOfPages = range->length >> I386_PGSHIFT; + memoryMap->Attribute = 0; + } + + // copy bootFile into device tree + // XXX + + // add PCI info somehow into device tree + // XXX + + // Flatten device tree + DT__FlattenDeviceTree(0, &size); + addr = (void *)AllocateKernelMemory(size); + if (addr == 0) { + stop("Couldn't allocate device tree\n"); + } + + DT__FlattenDeviceTree((void **)&addr, &size); + bootArgs->deviceTreeP = (uint32_t)addr; + bootArgs->deviceTreeLength = size; + + // Copy BootArgs values to older structure + + memcpy(&bootArgsPreLion->CommandLine, &bootArgs->CommandLine, BOOT_LINE_LENGTH); + memcpy(&bootArgsPreLion->Video, &bootArgs->Video, sizeof(Boot_Video)); + + bootArgsPreLion->MemoryMap = bootArgs->MemoryMap; + bootArgsPreLion->MemoryMapSize = bootArgs->MemoryMapSize; + bootArgsPreLion->MemoryMapDescriptorSize = bootArgs->MemoryMapDescriptorSize; + bootArgsPreLion->MemoryMapDescriptorVersion = bootArgs->MemoryMapDescriptorVersion; + + bootArgsPreLion->deviceTreeP = bootArgs->deviceTreeP; + bootArgsPreLion->deviceTreeLength = bootArgs->deviceTreeLength; + + bootArgsPreLion->kaddr = bootArgs->kaddr; + bootArgsPreLion->ksize = bootArgs->ksize; + + bootArgsPreLion->efiRuntimeServicesPageStart = bootArgs->efiRuntimeServicesPageStart; + bootArgsPreLion->efiRuntimeServicesPageCount = bootArgs->efiRuntimeServicesPageCount; + bootArgsPreLion->efiSystemTable = bootArgs->efiSystemTable; + + bootArgsPreLion->efiMode = bootArgs->efiMode; + + bootArgsPreLion->performanceDataStart = bootArgs->performanceDataStart; + bootArgsPreLion->performanceDataSize = bootArgs->performanceDataSize; + bootArgsPreLion->efiRuntimeServicesVirtualPageStart = bootArgs->efiRuntimeServicesVirtualPageStart; +} Index: branches/slice/trunkM/i386/libsaio/efi.h =================================================================== --- branches/slice/trunkM/i386/libsaio/efi.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/efi.h (revision 1171) @@ -0,0 +1,558 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _PEXPERT_I386_EFI_H +#define _PEXPERT_I386_EFI_H + +#include + +typedef uint8_t EFI_UINT8; +typedef uint16_t EFI_UINT16; +typedef uint32_t EFI_UINT32; +typedef uint64_t EFI_UINT64; + +typedef uint32_t EFI_UINTN; /* natural size for firmware, not kernel */ + +typedef int8_t EFI_INT8; +typedef int16_t EFI_INT16; +typedef int32_t EFI_INT32; +typedef int64_t EFI_INT64; + +typedef int8_t EFI_CHAR8; +typedef int16_t EFI_CHAR16; +typedef int32_t EFI_CHAR32; +typedef int64_t EFI_CHAR64; + +typedef uint32_t EFI_STATUS; +typedef uint8_t EFI_BOOLEAN; +typedef void VOID; + +typedef uint32_t EFI_PTR32; +typedef uint32_t EFI_HANDLE32; + +typedef uint64_t EFI_PTR64; +typedef uint64_t EFI_HANDLE64; +/* + +Portions Copyright 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + + +// +// Modifiers for EFI Runtime and Boot Services +// +#define EFI_RUNTIMESERVICE +#define EFIAPI +#define IN +#define OUT +#define OPTIONAL + +#define EFI_MAX_BIT 0x80000000 + +// +// Set the upper bit to indicate EFI Error. +// +#define EFIERR(a) (EFI_MAX_BIT | (a)) + +#define EFIWARN(a) (a) +#define EFI_ERROR(a) (((INTN) (a)) < 0) + +#define EFI_SUCCESS 0 +#define EFI_LOAD_ERROR EFIERR (1) +#define EFI_INVALID_PARAMETER EFIERR (2) +#define EFI_UNSUPPORTED EFIERR (3) +#define EFI_BAD_BUFFER_SIZE EFIERR (4) +#define EFI_BUFFER_TOO_SMALL EFIERR (5) +#define EFI_NOT_READY EFIERR (6) +#define EFI_DEVICE_ERROR EFIERR (7) +#define EFI_WRITE_PROTECTED EFIERR (8) +#define EFI_OUT_OF_RESOURCES EFIERR (9) +#define EFI_VOLUME_CORRUPTED EFIERR (10) +#define EFI_VOLUME_FULL EFIERR (11) +#define EFI_NO_MEDIA EFIERR (12) +#define EFI_MEDIA_CHANGED EFIERR (13) +#define EFI_NOT_FOUND EFIERR (14) +#define EFI_ACCESS_DENIED EFIERR (15) +#define EFI_NO_RESPONSE EFIERR (16) +#define EFI_NO_MAPPING EFIERR (17) +#define EFI_TIMEOUT EFIERR (18) +#define EFI_NOT_STARTED EFIERR (19) +#define EFI_ALREADY_STARTED EFIERR (20) +#define EFI_ABORTED EFIERR (21) +#define EFI_ICMP_ERROR EFIERR (22) +#define EFI_TFTP_ERROR EFIERR (23) +#define EFI_PROTOCOL_ERROR EFIERR (24) +#define EFI_INCOMPATIBLE_VERSION EFIERR (25) +#define EFI_SECURITY_VIOLATION EFIERR (26) +#define EFI_CRC_ERROR EFIERR (27) + +#define EFI_WARN_UNKNOWN_GLYPH EFIWARN (1) +#define EFI_WARN_DELETE_FAILURE EFIWARN (2) +#define EFI_WARN_WRITE_FAILURE EFIWARN (3) +#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN (4) + +// +// EFI Specification Revision information +// +#define EFI_SPECIFICATION_MAJOR_REVISION 1 +#define EFI_SPECIFICATION_MINOR_REVISION 10 + +typedef struct { + EFI_UINT32 Data1; + EFI_UINT16 Data2; + EFI_UINT16 Data3; + EFI_UINT8 Data4[8]; +} EFI_GUID; + +#define APPLE_VENDOR_GUID \ + {0xAC39C713, 0x7E50, 0x423D, {0x88, 0x9D, 0x27,0x8F, 0xCC, 0x34, 0x22, 0xB6} } + +#define EFI_GLOBAL_VARIABLE_GUID \ + {0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C} } + +typedef union { + EFI_GUID Guid; + EFI_UINT8 Raw[16]; +} EFI_GUID_UNION; + +// +// EFI Time Abstraction: +// Year: 2000 - 20XX +// Month: 1 - 12 +// Day: 1 - 31 +// Hour: 0 - 23 +// Minute: 0 - 59 +// Second: 0 - 59 +// Nanosecond: 0 - 999,999,999 +// TimeZone: -1440 to 1440 or 2047 +// +typedef struct { + EFI_UINT16 Year; + EFI_UINT8 Month; + EFI_UINT8 Day; + EFI_UINT8 Hour; + EFI_UINT8 Minute; + EFI_UINT8 Second; + EFI_UINT8 Pad1; + EFI_UINT32 Nanosecond; + EFI_INT16 TimeZone; + EFI_UINT8 Daylight; + EFI_UINT8 Pad2; +} EFI_TIME; + +// +// Bit definitions for EFI_TIME.Daylight +// +#define EFI_TIME_ADJUST_DAYLIGHT 0x01 +#define EFI_TIME_IN_DAYLIGHT 0x02 + +// +// Value definition for EFI_TIME.TimeZone +// +#define EFI_UNSPECIFIED_TIMEZONE 0x07FF + +typedef enum { + EfiReservedMemoryType, + EfiLoaderCode, + EfiLoaderData, + EfiBootServicesCode, + EfiBootServicesData, + EfiRuntimeServicesCode, + EfiRuntimeServicesData, + EfiConventionalMemory, + EfiUnusableMemory, + EfiACPIReclaimMemory, + EfiACPIMemoryNVS, + EfiMemoryMappedIO, + EfiMemoryMappedIOPortSpace, + EfiPalCode, + EfiMaxMemoryType +} EFI_MEMORY_TYPE; + +typedef struct { + EFI_UINT64 Signature; + EFI_UINT32 Revision; + EFI_UINT32 HeaderSize; + EFI_UINT32 CRC32; + EFI_UINT32 Reserved; +} __attribute__((aligned(8))) EFI_TABLE_HEADER; + +// +// possible caching types for the memory range +// +#define EFI_MEMORY_UC 0x0000000000000001ULL +#define EFI_MEMORY_WC 0x0000000000000002ULL +#define EFI_MEMORY_WT 0x0000000000000004ULL +#define EFI_MEMORY_WB 0x0000000000000008ULL +#define EFI_MEMORY_UCE 0x0000000000000010ULL + +// +// physical memory protection on range +// +#define EFI_MEMORY_WP 0x0000000000001000ULL +#define EFI_MEMORY_RP 0x0000000000002000ULL +#define EFI_MEMORY_XP 0x0000000000004000ULL + +// +// range requires a runtime mapping +// +#define EFI_MEMORY_RUNTIME 0x8000000000000000ULL +#define EFI_MEMORY_KERN_RESERVED (1ULL << 59) +typedef EFI_UINT64 EFI_PHYSICAL_ADDRESS; +typedef EFI_UINT64 EFI_VIRTUAL_ADDRESS; + +#define EFI_MEMORY_DESCRIPTOR_VERSION 1 +typedef struct { + EFI_UINT32 Type; + EFI_UINT32 Pad; + EFI_PHYSICAL_ADDRESS PhysicalStart; + EFI_VIRTUAL_ADDRESS VirtualStart; + EFI_UINT64 NumberOfPages; + EFI_UINT64 Attribute; +} __attribute__((aligned(8))) EFI_MEMORY_DESCRIPTOR; + + +typedef +EFI_RUNTIMESERVICE +EFI_STATUS +(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP) ( + IN EFI_UINTN MemoryMapSize, + IN EFI_UINTN DescriptorSize, + IN EFI_UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR * VirtualMap + ) __attribute__((regparm(0))); + +typedef +EFI_RUNTIMESERVICE +EFI_STATUS +(EFIAPI *EFI_CONVERT_POINTER) ( + IN EFI_UINTN DebugDisposition, + IN OUT VOID **Address + ) __attribute__((regparm(0))); + +// +// Variable attributes +// +#define EFI_VARIABLE_NON_VOLATILE 0x00000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 +#define EFI_VARIABLE_READ_ONLY 0x00000008 + +typedef +EFI_RUNTIMESERVICE +EFI_STATUS +(EFIAPI *EFI_GET_VARIABLE) ( + IN EFI_CHAR16 * VariableName, + IN EFI_GUID * VendorGuid, + OUT EFI_UINT32 * Attributes OPTIONAL, + IN OUT EFI_UINTN * DataSize, + OUT VOID * Data + ) __attribute__((regparm(0))); + +typedef +EFI_RUNTIMESERVICE +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME) ( + IN OUT EFI_UINTN * VariableNameSize, + IN OUT EFI_CHAR16 * VariableName, + IN OUT EFI_GUID * VendorGuid + ) __attribute__((regparm(0))); + +typedef +EFI_RUNTIMESERVICE +EFI_STATUS +(EFIAPI *EFI_SET_VARIABLE) ( + IN EFI_CHAR16 * VariableName, + IN EFI_GUID * VendorGuid, + IN EFI_UINT32 Attributes, + IN EFI_UINTN DataSize, + IN VOID * Data + ) __attribute__((regparm(0))); + +// +// EFI Time +// +typedef struct { + EFI_UINT32 Resolution; + EFI_UINT32 Accuracy; + EFI_BOOLEAN SetsToZero; +} __attribute__((aligned(4))) EFI_TIME_CAPABILITIES; + +typedef +EFI_RUNTIMESERVICE +EFI_STATUS +(EFIAPI *EFI_GET_TIME) ( + OUT EFI_TIME * Time, + OUT EFI_TIME_CAPABILITIES * Capabilities OPTIONAL + ) __attribute__((regparm(0))); + +typedef +EFI_RUNTIMESERVICE +EFI_STATUS +(EFIAPI *EFI_SET_TIME) ( + IN EFI_TIME * Time + ) __attribute__((regparm(0))); + +typedef +EFI_RUNTIMESERVICE +EFI_STATUS +(EFIAPI *EFI_GET_WAKEUP_TIME) ( + OUT EFI_BOOLEAN * Enabled, + OUT EFI_BOOLEAN * Pending, + OUT EFI_TIME * Time + ) __attribute__((regparm(0))); + +typedef +EFI_RUNTIMESERVICE +EFI_STATUS +(EFIAPI *EFI_SET_WAKEUP_TIME) ( + IN EFI_BOOLEAN Enable, + IN EFI_TIME * Time OPTIONAL + ) __attribute((regparm(0))); + +typedef enum { + EfiResetCold, + EfiResetWarm, + EfiResetShutdown, + +#ifdef TIANO_EXTENSION_FLAG + EfiResetUpdate +#endif + +} EFI_RESET_TYPE; + +typedef +EFI_RUNTIMESERVICE +VOID +(EFIAPI *EFI_RESET_SYSTEM) ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN EFI_UINTN DataSize, + IN EFI_CHAR16 * ResetData OPTIONAL + ) __attribute__((regparm(0))); + +typedef +EFI_RUNTIMESERVICE +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT) ( + OUT EFI_UINT32 * HighCount + ) __attribute__((regparm(0))); + +// +// Definition of Status Code extended data header +// +// HeaderSize The size of the architecture. This is specified to enable +// the future expansion +// +// Size The size of the data in bytes. This does not include the size +// of the header structure. +// +// Type A GUID defining the type of the data +// +// +#ifdef TIANO_EXTENSION_FLAG + +typedef +EFI_RUNTIMESERVICE +EFI_STATUS +(EFIAPI *EFI_REPORT_STATUS_CODE) ( + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value, + IN EFI_UINT32 Instance, + IN EFI_GUID * CallerId OPTIONAL, + IN EFI_STATUS_CODE_DATA * Data OPTIONAL + ) __attribute__((regparm(0))); + +#endif +// +// EFI Runtime Services Table +// +#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552ULL +#define EFI_RUNTIME_SERVICES_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION << 16) | (EFI_SPECIFICATION_MINOR_REVISION)) + +typedef struct { + EFI_TABLE_HEADER Hdr; + + // + // Time services + // + EFI_PTR32 GetTime; + EFI_PTR32 SetTime; + EFI_PTR32 GetWakeupTime; + EFI_PTR32 SetWakeupTime; + + // + // Virtual memory services + // + EFI_PTR32 SetVirtualAddressMap; + EFI_PTR32 ConvertPointer; + + // + // Variable services + // + EFI_PTR32 GetVariable; + EFI_PTR32 GetNextVariableName; + EFI_PTR32 SetVariable; + + // + // Misc + // + EFI_PTR32 GetNextHighMonotonicCount; + EFI_PTR32 ResetSystem; + +#ifdef TIANO_EXTENSION_FLAG + // + // //////////////////////////////////////////////////// + // Extended EFI Services + ////////////////////////////////////////////////////// + // + EFI_PTR32 ReportStatusCode; +#endif + +} __attribute__((aligned(8))) EFI_RUNTIME_SERVICES_32; + +typedef struct { + EFI_TABLE_HEADER Hdr; + + // + // Time services + // + EFI_PTR64 GetTime; + EFI_PTR64 SetTime; + EFI_PTR64 GetWakeupTime; + EFI_PTR64 SetWakeupTime; + + // + // Virtual memory services + // + EFI_PTR64 SetVirtualAddressMap; + EFI_PTR64 ConvertPointer; + + // + // Variable services + // + EFI_PTR64 GetVariable; + EFI_PTR64 GetNextVariableName; + EFI_PTR64 SetVariable; + + // + // Misc + // + EFI_PTR64 GetNextHighMonotonicCount; + EFI_PTR64 ResetSystem; + +#ifdef TIANO_EXTENSION_FLAG + // + // //////////////////////////////////////////////////// + // Extended EFI Services + ////////////////////////////////////////////////////// + // + EFI_PTR64 ReportStatusCode; +#endif + +} __attribute__((aligned(8))) EFI_RUNTIME_SERVICES_64; + +// +// EFI Configuration Table +// +typedef struct { + EFI_GUID VendorGuid; + EFI_PTR32 VendorTable; +} EFI_CONFIGURATION_TABLE_32; + +typedef struct { + EFI_GUID VendorGuid; + EFI_PTR64 VendorTable; +} __attribute__((aligned(8))) EFI_CONFIGURATION_TABLE_64; + +// +// EFI System Table +// +#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249ULL +#define EFI_SYSTEM_TABLE_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION << 16) | (EFI_SPECIFICATION_MINOR_REVISION)) +#define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | 00) +#define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | 02) +#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | 10) + +typedef struct EFI_SYSTEM_TABLE_32 { + EFI_TABLE_HEADER Hdr; + + EFI_PTR32 FirmwareVendor; + EFI_UINT32 FirmwareRevision; + + EFI_HANDLE32 ConsoleInHandle; + EFI_PTR32 ConIn; + + EFI_HANDLE32 ConsoleOutHandle; + EFI_PTR32 ConOut; + + EFI_HANDLE32 StandardErrorHandle; + EFI_PTR32 StdErr; + + EFI_PTR32 RuntimeServices; + EFI_PTR32 BootServices; + + EFI_UINT32 NumberOfTableEntries; + EFI_PTR32 ConfigurationTable; + +} __attribute__((aligned(8))) EFI_SYSTEM_TABLE_32; + +typedef struct EFI_SYSTEM_TABLE_64 { + EFI_TABLE_HEADER Hdr; + + EFI_PTR64 FirmwareVendor; + EFI_UINT32 FirmwareRevision; + + EFI_UINT32 __pad; + + EFI_HANDLE64 ConsoleInHandle; + EFI_PTR64 ConIn; + + EFI_HANDLE64 ConsoleOutHandle; + EFI_PTR64 ConOut; + + EFI_HANDLE64 StandardErrorHandle; + EFI_PTR64 StdErr; + + EFI_PTR64 RuntimeServices; + EFI_PTR64 BootServices; + + EFI_UINT64 NumberOfTableEntries; + EFI_PTR64 ConfigurationTable; + +} __attribute__((aligned(8))) EFI_SYSTEM_TABLE_64; + +#endif /* _PEXPERT_I386_EFI_H */ Index: branches/slice/trunkM/i386/libsaio/ntfs_private.h =================================================================== --- branches/slice/trunkM/i386/libsaio/ntfs_private.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/ntfs_private.h (revision 1171) @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* $NetBSD: ntfs.h,v 1.9 1999/10/31 19:45:26 jdolecek Exp $ */ + +/*- + * Copyright (c) 1998, 1999 Semen Ustimenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/fs/ntfs/ntfs.h,v 1.14 2001/11/27 00:18:33 jhb Exp $ + */ + +/*#define NTFS_DEBUG 1*/ + +#ifdef APPLE +/* We're using FreeBSD style byte order macros in the source. */ +#include +#define le16toh(x) OSSwapLittleToHostInt16(x) +#define le32toh(x) OSSwapLittleToHostInt32(x) +#define le64toh(x) OSSwapLittleToHostInt64(x) + +/* FreeBSD mutexes correspond to Darwin's simple locks */ +#define mtx_lock(lock) simple_lock(lock) +#define mtx_unlock(lock) simple_unlock(lock) +#define mtx_destroy(lock) /* Nothing. */ + +#define lockdestroy(lock) /* Nothing. */ + +#endif + +typedef u_int64_t cn_t; +typedef u_int16_t wchar; + +#pragma pack(1) +#define BBSIZE 1024 +#define BBOFF ((off_t)(0)) +#define BBLOCK ((daddr_t)(0)) +#define NTFS_MFTINO 0 +#define NTFS_VOLUMEINO 3 +#define NTFS_ATTRDEFINO 4 +#define NTFS_ROOTINO 5 +#define NTFS_BITMAPINO 6 +#define NTFS_BOOTINO 7 +#define NTFS_BADCLUSINO 8 +#define NTFS_UPCASEINO 10 +#define NTFS_MAXFILENAME 255 + +struct fixuphdr { + u_int32_t fh_magic; + u_int16_t fh_foff; + u_int16_t fh_fnum; +}; + +#define NTFS_AF_INRUN 0x00000001 +struct attrhdr { + u_int32_t a_type; + u_int32_t reclen; + u_int8_t a_flag; + u_int8_t a_namelen; + u_int8_t a_nameoff; + u_int8_t reserved1; + u_int8_t a_compression; + u_int8_t reserved2; + u_int16_t a_index; +}; +#define NTFS_A_STD 0x10 +#define NTFS_A_ATTRLIST 0x20 +#define NTFS_A_NAME 0x30 +#define NTFS_A_VOLUMENAME 0x60 +#define NTFS_A_DATA 0x80 +#define NTFS_A_INDXROOT 0x90 +#define NTFS_A_INDX 0xA0 +#define NTFS_A_INDXBITMAP 0xB0 + +#define NTFS_MAXATTRNAME 255 +struct attr { + struct attrhdr a_hdr; + union { + struct { + u_int16_t a_datalen; + u_int16_t reserved1; + u_int16_t a_dataoff; + u_int16_t a_indexed; + } a_S_r; + struct { + cn_t a_vcnstart; + cn_t a_vcnend; + u_int16_t a_dataoff; + u_int16_t a_compressalg; + u_int32_t reserved1; + u_int64_t a_allocated; + u_int64_t a_datalen; + u_int64_t a_initialized; + } a_S_nr; + } a_S; +}; +#define a_r a_S.a_S_r +#define a_nr a_S.a_S_nr + +typedef struct { + u_int64_t t_create; + u_int64_t t_write; + u_int64_t t_mftwrite; + u_int64_t t_access; +} ntfs_times_t; + +#define NTFS_FFLAG_RDONLY 0x01LL +#define NTFS_FFLAG_HIDDEN 0x02LL +#define NTFS_FFLAG_SYSTEM 0x04LL +#define NTFS_FFLAG_ARCHIVE 0x20LL +#define NTFS_FFLAG_COMPRESSED 0x0800LL +#define NTFS_FFLAG_DIR 0x10000000LL + +struct attr_name { + u_int32_t n_pnumber; /* Parent ntnode */ + u_int32_t reserved; + ntfs_times_t n_times; + u_int64_t n_size; + u_int64_t n_attrsz; + u_int64_t n_flag; + u_int8_t n_namelen; + u_int8_t n_nametype; + u_int16_t n_name[1]; +}; + +#define NTFS_IRFLAG_INDXALLOC 0x00000001 +struct attr_indexroot { + u_int32_t ir_unkn1; /* attribute type (0x30 for $FILE_NAME) */ + u_int32_t ir_unkn2; /* collation rule (0x01 for file names) */ + u_int32_t ir_size; /* size of index allocation entry */ + u_int32_t ir_unkn3; /* clusters per index record, and 3 bytes padding */ + u_int32_t ir_unkn4; /* (offset to first index entry?) always 0x10 */ + u_int32_t ir_datalen; /* (total size of index enties?) sizeof something */ + u_int32_t ir_allocated; /* (allocated size of index entries?) */ + u_int8_t ir_flag; /* 1=index allocation needed (large index) */ + u_int8_t ir_pad1; /* padding */ + u_int16_t ir_pad2; /* padding */ +}; + +struct attr_attrlist { + u_int32_t al_type; /* Attribute type */ + u_int16_t reclen; /* length of this entry */ + u_int8_t al_namelen; /* Attribute name len */ + u_int8_t al_nameoff; /* Name offset from entry start */ + u_int64_t al_vcnstart; /* VCN number */ + u_int32_t al_inumber; /* Parent ntnode */ + u_int32_t reserved; + u_int16_t al_index; /* Attribute index in MFT record */ + u_int16_t al_name[1]; /* Name */ +}; + +#define NTFS_INDXMAGIC (u_int32_t)(0x58444E49) +struct attr_indexalloc { + struct fixuphdr ia_fixup; + u_int64_t unknown1; + cn_t ia_bufcn; + u_int16_t ia_hdrsize; + u_int16_t unknown2; + u_int32_t ia_inuse; + u_int32_t ia_allocated; +}; + +#define NTFS_IEFLAG_SUBNODE 0x00000001 +#define NTFS_IEFLAG_LAST 0x00000002 + +struct attr_indexentry { + u_int32_t ie_number; + u_int32_t unknown1; + u_int16_t reclen; + u_int16_t ie_size; + u_int32_t ie_flag;/* 1 - has subnodes, 2 - last */ + u_int32_t ie_fpnumber; + u_int32_t unknown2; + ntfs_times_t ie_ftimes; + u_int64_t ie_fallocated; + u_int64_t ie_fsize; + u_int32_t ie_fflag; + u_int32_t unknown3; /* used by reparse points and external attributes? */ + u_int8_t ie_fnamelen; + u_int8_t ie_fnametype; + wchar ie_fname[NTFS_MAXFILENAME]; + /* cn_t ie_bufcn; buffer with subnodes */ +}; + +#define NTFS_FILEMAGIC (u_int32_t)(0x454C4946) +#define NTFS_FRFLAG_DIR 0x0002 +struct filerec { + struct fixuphdr fr_fixup; + u_int8_t reserved[8]; + u_int16_t fr_seqnum; /* Sequence number */ + u_int16_t fr_nlink; + u_int16_t fr_attroff; /* offset to attributes */ + u_int16_t fr_flags; /* 1-nonresident attr, 2-directory */ + u_int32_t fr_size;/* hdr + attributes */ + u_int32_t fr_allocated; /* allocated length of record */ + u_int64_t fr_mainrec; /* main record */ + u_int16_t fr_attrnum; /* maximum attr number + 1 ??? */ +}; + +#define NTFS_ATTRNAME_MAXLEN 0x40 +#define NTFS_ADFLAG_NONRES 0x0080 /* Attrib can be non resident */ +#define NTFS_ADFLAG_INDEX 0x0002 /* Attrib can be indexed */ +struct attrdef { + wchar ad_name[NTFS_ATTRNAME_MAXLEN]; + u_int32_t ad_type; + u_int32_t reserved1[2]; + u_int32_t ad_flag; + u_int64_t ad_minlen; + u_int64_t ad_maxlen; /* -1 for nonlimited */ +}; + +struct ntvattrdef { + char ad_name[0x40]; + int ad_namelen; + u_int32_t ad_type; +}; + +#define NTFS_BBID "NTFS " +#define NTFS_BBIDLEN 8 +struct bootfile { + u_int8_t reserved1[3]; /* asm jmp near ... */ + u_int8_t bf_sysid[8]; /* 'NTFS ' */ + u_int16_t bf_bps; /* bytes per sector */ + u_int8_t bf_spc; /* sectors per cluster */ + u_int8_t reserved2[7]; /* unused (zeroed) */ + u_int8_t bf_media; /* media desc. (0xF8) */ + u_int8_t reserved3[2]; + u_int16_t bf_spt; /* sectors per track */ + u_int16_t bf_heads; /* number of heads */ + u_int8_t reserver4[12]; + u_int64_t bf_spv; /* sectors per volume */ + cn_t bf_mftcn; /* $MFT cluster number */ + cn_t bf_mftmirrcn; /* $MFTMirr cn */ + u_int8_t bf_mftrecsz; /* MFT record size (clust) */ + /* 0xF6 inducates 1/4 */ + 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. */ +}; + +/* + * Darwin's ntfs.util needs to include this file to get definitions + * for the on-disk structures. It doesn't need the ntfsmount structure. + * In fact, since it doesn't #define KERNEL, the struct netexport below + * won't be defined. + * + * So, I'm using #ifdef KERNEL around the things that are only relevant + * to the in-kernel implementation. + * + * I don't know if FreeBSD defines KERNEL, or if I need to use or + * invent a different conditional here. + */ +#ifdef KERNEL + +#define NTFS_SYSNODESNUM 0x0B +struct ntfsmount { + struct mount *ntm_mountp; /* filesystem vfs structure */ + struct bootfile ntm_bootfile; + dev_t ntm_dev; /* device mounted */ + struct vnode *ntm_devvp; /* block device mounted vnode */ + struct vnode *ntm_sysvn[NTFS_SYSNODESNUM]; + u_int32_t ntm_bpmftrec; + uid_t ntm_uid; + gid_t ntm_gid; + mode_t ntm_mode; + u_long ntm_flag; + cn_t ntm_cfree; + struct ntvattrdef *ntm_ad; /* attribute names are stored in native byte order */ + int ntm_adnum; + wchar * ntm_82u; /* 8bit to Unicode */ + char ** ntm_u28; /* Unicode to 8 bit */ +#ifdef APPLE + struct netexport ntm_export; /* NFS export information */ +#endif +}; + +#define ntm_mftcn ntm_bootfile.bf_mftcn +#define ntm_mftmirrcn ntm_bootfile.bf_mftmirrcn +#define ntm_mftrecsz ntm_bootfile.bf_mftrecsz +#define ntm_spc ntm_bootfile.bf_spc +#define ntm_bps ntm_bootfile.bf_bps + +#pragma pack() + +#define NTFS_NEXTREC(s, type) ((type)(((caddr_t) s) + le16toh((s)->reclen))) + +/* Convert mount ptr to ntfsmount ptr. */ +#define VFSTONTFS(mp) ((struct ntfsmount *)((mp)->mnt_data)) +#define VTONT(v) FTONT(VTOF(v)) +#define VTOF(v) ((struct fnode *)((v)->v_data)) +#define FTOV(f) ((f)->f_vp) +#define FTONT(f) ((f)->f_ip) +#define ntfs_cntobn(cn) ((daddr_t)(cn) * (ntmp->ntm_spc)) +#define ntfs_cntob(cn) ((off_t)(cn) * (ntmp)->ntm_spc * (ntmp)->ntm_bps) +#define ntfs_btocn(off) (cn_t)((off) / ((ntmp)->ntm_spc * (ntmp)->ntm_bps)) +#define ntfs_btocl(off) (cn_t)((off + ntfs_cntob(1) - 1) / ((ntmp)->ntm_spc * (ntmp)->ntm_bps)) +#define ntfs_btocnoff(off) (off_t)((off) % ((ntmp)->ntm_spc * (ntmp)->ntm_bps)) +#define ntfs_bntob(bn) (daddr_t)((bn) * (ntmp)->ntm_bps) + +#define ntfs_bpbl (daddr_t)((ntmp)->ntm_bps) + +#ifdef MALLOC_DECLARE +MALLOC_DECLARE(M_NTFSMNT); +MALLOC_DECLARE(M_NTFSNTNODE); +MALLOC_DECLARE(M_NTFSFNODE); +MALLOC_DECLARE(M_NTFSDIR); +MALLOC_DECLARE(M_NTFSNTHASH); +#endif + +#ifndef M_NTFSMNT +#define M_NTFSMNT M_TEMP +#endif +#ifndef M_NTFSNTNODE +#define M_NTFSNTNODE M_TEMP +#endif +#ifndef M_NTFSFNODE +#define M_NTFSFNODE M_TEMP +#endif +#ifndef M_NTFSDIR +#define M_NTFSDIR M_TEMP +#endif +#ifndef M_NTFSNTHASH +#define M_NTFSNTHASH M_TEMP +#endif +#ifndef M_NTFSRUN +#define M_NTFSRUN M_TEMP +#endif +#ifndef M_NTFSRDATA +#define M_NTFSRDATA M_TEMP +#endif +#ifndef M_NTFSNTVATTR +#define M_NTFSNTVATTR M_TEMP +#endif +#ifndef M_NTFSDECOMP +#define M_NTFSDECOMP M_TEMP +#endif +#define VT_NTFS VT_OTHER + +#if defined(NTFS_DEBUG) +#define dprintf(a) printf a +#if NTFS_DEBUG > 1 +#define ddprintf(a) printf a +#else +#define ddprintf(a) +#endif +#else +#define dprintf(a) +#define ddprintf(a) +#endif + +#ifdef APPLE +typedef int vop_t(void *); +#else +#endif +extern vop_t **ntfs_vnodeop_p; +#endif /* KERNEL */ Index: branches/slice/trunkM/i386/libsaio/io_inline.h =================================================================== --- branches/slice/trunkM/i386/libsaio/io_inline.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/io_inline.h (revision 1171) @@ -0,0 +1,82 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1992 NeXT Computer, Inc. + * + * Inlines for io space access. + * + * HISTORY + * + * 20 May 1992 ? at NeXT + * Created. + */ + +#ifndef __LIBSAIO_IO_INLINE_H +#define __LIBSAIO_IO_INLINE_H + +/* + *############################################################################ + * + * x86 IN/OUT I/O inline functions. + * + * IN : inb, inw, inl + * IN(port) + * + * OUT: outb, outw, outl + * OUT(port, data) + * + *############################################################################ + */ + +#define __IN(s, u) \ +static inline unsigned u \ +in##s(unsigned short port) \ +{ \ + unsigned u data; \ + asm volatile ( \ + "in" #s " %1,%0" \ + : "=a" (data) \ + : "d" (port)); \ + return (data); \ +} + +#define __OUT(s, u) \ +static inline void \ +out##s(unsigned short port, unsigned u data) \ +{ \ + asm volatile ( \ + "out" #s " %1,%0" \ + : \ + : "d" (port), "a" (data)); \ +} + +__IN(b, char) /* inb() */ +__IN(w, short) /* inw() */ +__IN(l, long) /* inl() */ + +__OUT(b, char) /* outb() */ +__OUT(w, short) /* outw() */ +__OUT(l, long) /* outl() */ + +#endif /* !__LIBSAIO_IO_INLINE_H */ Index: branches/slice/trunkM/i386/libsaio/ext2fs.c =================================================================== --- branches/slice/trunkM/i386/libsaio/ext2fs.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/ext2fs.c (revision 1171) @@ -0,0 +1,42 @@ +/* + * ext2fs.c + * + * + * Created by mackerintel on 1/26/09. + * Copyright 2009 __MyCompanyName__. All rights reserved. + * + */ + +#include "libsaio.h" +#include "sl.h" +#include "ext2fs.h" + +#define EX2ProbeSize 2048 + +bool EX2Probe (const void *buf) +{ + return (OSReadLittleInt16(buf+0x438,0)==0xEF53); +} + +void EX2GetDescription(CICell ih, char *str, long strMaxLen) +{ + char * buf=malloc (EX2ProbeSize); + str[0]=0; + if (!buf) + return; + Seek(ih, 0); + Read(ih, (long)buf, EX2ProbeSize); + if (!EX2Probe (buf)) + { + free (buf); + return; + } + if (OSReadLittleInt32 (buf+0x44c,0)<1) + { + free (buf); + return; + } + str[strMaxLen]=0; + strncpy (str, buf+0x478, MIN(strMaxLen, 16)); + free (buf); +} Index: branches/slice/trunkM/i386/libsaio/hfs_CaseTables.h =================================================================== --- branches/slice/trunkM/i386/libsaio/hfs_CaseTables.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/hfs_CaseTables.h (revision 1171) @@ -0,0 +1,560 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 2.0 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + File: CaseTables.h +*/ + + +/* The lower case table consists of a 256-entry high-byte table followed by some number of + 256-entry subtables. The high-byte table contains either an offset to the subtable for + characters with that high byte or zero, which means that there are no case mappings or + ignored characters in that block. Ignored characters are mapped to zero. + */ + +#if UNCOMPRESSED +u_int16_t gLowerCaseTable[] = { + + // High-byte indices ( == 0 iff no case mapping and no ignorables ) + + /* 0 */ 0x0100, 0x0200, 0x0000, 0x0300, 0x0400, 0x0500, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 1 */ 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 2 */ 0x0700, 0x0800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 3 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 4 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 5 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 6 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 7 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 9 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* A */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* B */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* C */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* D */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* E */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* F */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0900, 0x0A00, + + // Table 1 (for high byte 0x00) + + /* 0 */ 0xFFFF, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + /* 1 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + /* 2 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + /* 3 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + /* 4 */ 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + /* 5 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + /* 6 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + /* 7 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + /* 8 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + /* 9 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + /* A */ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + /* B */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + /* C */ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00E6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + /* D */ 0x00F0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00F8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00FE, 0x00DF, + /* E */ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + /* F */ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, + + // Table 2 (for high byte 0x01) + + /* 0 */ 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x0108, 0x0109, 0x010A, 0x010B, 0x010C, 0x010D, 0x010E, 0x010F, + /* 1 */ 0x0111, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117, 0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E, 0x011F, + /* 2 */ 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0127, 0x0127, 0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F, + /* 3 */ 0x0130, 0x0131, 0x0133, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137, 0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x0140, + /* 4 */ 0x0140, 0x0142, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147, 0x0148, 0x0149, 0x014B, 0x014B, 0x014C, 0x014D, 0x014E, 0x014F, + /* 5 */ 0x0150, 0x0151, 0x0153, 0x0153, 0x0154, 0x0155, 0x0156, 0x0157, 0x0158, 0x0159, 0x015A, 0x015B, 0x015C, 0x015D, 0x015E, 0x015F, + /* 6 */ 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, 0x0167, 0x0167, 0x0168, 0x0169, 0x016A, 0x016B, 0x016C, 0x016D, 0x016E, 0x016F, + /* 7 */ 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, 0x0176, 0x0177, 0x0178, 0x0179, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E, 0x017F, + /* 8 */ 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188, 0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259, + /* 9 */ 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268, 0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275, + /* A */ 0x01A0, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x01A6, 0x01A8, 0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01AF, + /* B */ 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292, 0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF, + /* C */ 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9, 0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC, 0x01CD, 0x01CE, 0x01CF, + /* D */ 0x01D0, 0x01D1, 0x01D2, 0x01D3, 0x01D4, 0x01D5, 0x01D6, 0x01D7, 0x01D8, 0x01D9, 0x01DA, 0x01DB, 0x01DC, 0x01DD, 0x01DE, 0x01DF, + /* E */ 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E5, 0x01E5, 0x01E6, 0x01E7, 0x01E8, 0x01E9, 0x01EA, 0x01EB, 0x01EC, 0x01ED, 0x01EE, 0x01EF, + /* F */ 0x01F0, 0x01F3, 0x01F3, 0x01F3, 0x01F4, 0x01F5, 0x01F6, 0x01F7, 0x01F8, 0x01F9, 0x01FA, 0x01FB, 0x01FC, 0x01FD, 0x01FE, 0x01FF, + + // Table 3 (for high byte 0x03) + + /* 0 */ 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, 0x0309, 0x030A, 0x030B, 0x030C, 0x030D, 0x030E, 0x030F, + /* 1 */ 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317, 0x0318, 0x0319, 0x031A, 0x031B, 0x031C, 0x031D, 0x031E, 0x031F, + /* 2 */ 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327, 0x0328, 0x0329, 0x032A, 0x032B, 0x032C, 0x032D, 0x032E, 0x032F, + /* 3 */ 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337, 0x0338, 0x0339, 0x033A, 0x033B, 0x033C, 0x033D, 0x033E, 0x033F, + /* 4 */ 0x0340, 0x0341, 0x0342, 0x0343, 0x0344, 0x0345, 0x0346, 0x0347, 0x0348, 0x0349, 0x034A, 0x034B, 0x034C, 0x034D, 0x034E, 0x034F, + /* 5 */ 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357, 0x0358, 0x0359, 0x035A, 0x035B, 0x035C, 0x035D, 0x035E, 0x035F, + /* 6 */ 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367, 0x0368, 0x0369, 0x036A, 0x036B, 0x036C, 0x036D, 0x036E, 0x036F, + /* 7 */ 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, 0x0377, 0x0378, 0x0379, 0x037A, 0x037B, 0x037C, 0x037D, 0x037E, 0x037F, + /* 8 */ 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386, 0x0387, 0x0388, 0x0389, 0x038A, 0x038B, 0x038C, 0x038D, 0x038E, 0x038F, + /* 9 */ 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + /* A */ 0x03C0, 0x03C1, 0x03A2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + /* B */ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + /* C */ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x03CF, + /* D */ 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7, 0x03D8, 0x03D9, 0x03DA, 0x03DB, 0x03DC, 0x03DD, 0x03DE, 0x03DF, + /* E */ 0x03E0, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7, 0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF, + /* F */ 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03F4, 0x03F5, 0x03F6, 0x03F7, 0x03F8, 0x03F9, 0x03FA, 0x03FB, 0x03FC, 0x03FD, 0x03FE, 0x03FF, + + // Table 4 (for high byte 0x04) + + /* 0 */ 0x0400, 0x0401, 0x0452, 0x0403, 0x0454, 0x0455, 0x0456, 0x0407, 0x0458, 0x0459, 0x045A, 0x045B, 0x040C, 0x040D, 0x040E, 0x045F, + /* 1 */ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0419, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + /* 2 */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + /* 3 */ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + /* 4 */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + /* 5 */ 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045D, 0x045E, 0x045F, + /* 6 */ 0x0461, 0x0461, 0x0463, 0x0463, 0x0465, 0x0465, 0x0467, 0x0467, 0x0469, 0x0469, 0x046B, 0x046B, 0x046D, 0x046D, 0x046F, 0x046F, + /* 7 */ 0x0471, 0x0471, 0x0473, 0x0473, 0x0475, 0x0475, 0x0476, 0x0477, 0x0479, 0x0479, 0x047B, 0x047B, 0x047D, 0x047D, 0x047F, 0x047F, + /* 8 */ 0x0481, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048A, 0x048B, 0x048C, 0x048D, 0x048E, 0x048F, + /* 9 */ 0x0491, 0x0491, 0x0493, 0x0493, 0x0495, 0x0495, 0x0497, 0x0497, 0x0499, 0x0499, 0x049B, 0x049B, 0x049D, 0x049D, 0x049F, 0x049F, + /* A */ 0x04A1, 0x04A1, 0x04A3, 0x04A3, 0x04A5, 0x04A5, 0x04A7, 0x04A7, 0x04A9, 0x04A9, 0x04AB, 0x04AB, 0x04AD, 0x04AD, 0x04AF, 0x04AF, + /* B */ 0x04B1, 0x04B1, 0x04B3, 0x04B3, 0x04B5, 0x04B5, 0x04B7, 0x04B7, 0x04B9, 0x04B9, 0x04BB, 0x04BB, 0x04BD, 0x04BD, 0x04BF, 0x04BF, + /* C */ 0x04C0, 0x04C1, 0x04C2, 0x04C4, 0x04C4, 0x04C5, 0x04C6, 0x04C8, 0x04C8, 0x04C9, 0x04CA, 0x04CC, 0x04CC, 0x04CD, 0x04CE, 0x04CF, + /* D */ 0x04D0, 0x04D1, 0x04D2, 0x04D3, 0x04D4, 0x04D5, 0x04D6, 0x04D7, 0x04D8, 0x04D9, 0x04DA, 0x04DB, 0x04DC, 0x04DD, 0x04DE, 0x04DF, + /* E */ 0x04E0, 0x04E1, 0x04E2, 0x04E3, 0x04E4, 0x04E5, 0x04E6, 0x04E7, 0x04E8, 0x04E9, 0x04EA, 0x04EB, 0x04EC, 0x04ED, 0x04EE, 0x04EF, + /* F */ 0x04F0, 0x04F1, 0x04F2, 0x04F3, 0x04F4, 0x04F5, 0x04F6, 0x04F7, 0x04F8, 0x04F9, 0x04FA, 0x04FB, 0x04FC, 0x04FD, 0x04FE, 0x04FF, + + // Table 5 (for high byte 0x05) + + /* 0 */ 0x0500, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x0506, 0x0507, 0x0508, 0x0509, 0x050A, 0x050B, 0x050C, 0x050D, 0x050E, 0x050F, + /* 1 */ 0x0510, 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517, 0x0518, 0x0519, 0x051A, 0x051B, 0x051C, 0x051D, 0x051E, 0x051F, + /* 2 */ 0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527, 0x0528, 0x0529, 0x052A, 0x052B, 0x052C, 0x052D, 0x052E, 0x052F, + /* 3 */ 0x0530, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, 0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F, + /* 4 */ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, 0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F, + /* 5 */ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0557, 0x0558, 0x0559, 0x055A, 0x055B, 0x055C, 0x055D, 0x055E, 0x055F, + /* 6 */ 0x0560, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, 0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F, + /* 7 */ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, 0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F, + /* 8 */ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0587, 0x0588, 0x0589, 0x058A, 0x058B, 0x058C, 0x058D, 0x058E, 0x058F, + /* 9 */ 0x0590, 0x0591, 0x0592, 0x0593, 0x0594, 0x0595, 0x0596, 0x0597, 0x0598, 0x0599, 0x059A, 0x059B, 0x059C, 0x059D, 0x059E, 0x059F, + /* A */ 0x05A0, 0x05A1, 0x05A2, 0x05A3, 0x05A4, 0x05A5, 0x05A6, 0x05A7, 0x05A8, 0x05A9, 0x05AA, 0x05AB, 0x05AC, 0x05AD, 0x05AE, 0x05AF, + /* B */ 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7, 0x05B8, 0x05B9, 0x05BA, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF, + /* C */ 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05C4, 0x05C5, 0x05C6, 0x05C7, 0x05C8, 0x05C9, 0x05CA, 0x05CB, 0x05CC, 0x05CD, 0x05CE, 0x05CF, + /* D */ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + /* E */ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x05EB, 0x05EC, 0x05ED, 0x05EE, 0x05EF, + /* F */ 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x05F5, 0x05F6, 0x05F7, 0x05F8, 0x05F9, 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF, + + // Table 6 (for high byte 0x10) + + /* 0 */ 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1008, 0x1009, 0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F, + /* 1 */ 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017, 0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F, + /* 2 */ 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027, 0x1028, 0x1029, 0x102A, 0x102B, 0x102C, 0x102D, 0x102E, 0x102F, + /* 3 */ 0x1030, 0x1031, 0x1032, 0x1033, 0x1034, 0x1035, 0x1036, 0x1037, 0x1038, 0x1039, 0x103A, 0x103B, 0x103C, 0x103D, 0x103E, 0x103F, + /* 4 */ 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, 0x1048, 0x1049, 0x104A, 0x104B, 0x104C, 0x104D, 0x104E, 0x104F, + /* 5 */ 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057, 0x1058, 0x1059, 0x105A, 0x105B, 0x105C, 0x105D, 0x105E, 0x105F, + /* 6 */ 0x1060, 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067, 0x1068, 0x1069, 0x106A, 0x106B, 0x106C, 0x106D, 0x106E, 0x106F, + /* 7 */ 0x1070, 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, 0x1076, 0x1077, 0x1078, 0x1079, 0x107A, 0x107B, 0x107C, 0x107D, 0x107E, 0x107F, + /* 8 */ 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087, 0x1088, 0x1089, 0x108A, 0x108B, 0x108C, 0x108D, 0x108E, 0x108F, + /* 9 */ 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097, 0x1098, 0x1099, 0x109A, 0x109B, 0x109C, 0x109D, 0x109E, 0x109F, + /* A */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7, 0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF, + /* B */ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7, 0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF, + /* C */ 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10C6, 0x10C7, 0x10C8, 0x10C9, 0x10CA, 0x10CB, 0x10CC, 0x10CD, 0x10CE, 0x10CF, + /* D */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7, 0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF, + /* E */ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7, 0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF, + /* F */ 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10F6, 0x10F7, 0x10F8, 0x10F9, 0x10FA, 0x10FB, 0x10FC, 0x10FD, 0x10FE, 0x10FF, + + // Table 7 (for high byte 0x20) + + /* 0 */ 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x200B, 0x0000, 0x0000, 0x0000, 0x0000, + /* 1 */ 0x2010, 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2016, 0x2017, 0x2018, 0x2019, 0x201A, 0x201B, 0x201C, 0x201D, 0x201E, 0x201F, + /* 2 */ 0x2020, 0x2021, 0x2022, 0x2023, 0x2024, 0x2025, 0x2026, 0x2027, 0x2028, 0x2029, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x202F, + /* 3 */ 0x2030, 0x2031, 0x2032, 0x2033, 0x2034, 0x2035, 0x2036, 0x2037, 0x2038, 0x2039, 0x203A, 0x203B, 0x203C, 0x203D, 0x203E, 0x203F, + /* 4 */ 0x2040, 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046, 0x2047, 0x2048, 0x2049, 0x204A, 0x204B, 0x204C, 0x204D, 0x204E, 0x204F, + /* 5 */ 0x2050, 0x2051, 0x2052, 0x2053, 0x2054, 0x2055, 0x2056, 0x2057, 0x2058, 0x2059, 0x205A, 0x205B, 0x205C, 0x205D, 0x205E, 0x205F, + /* 6 */ 0x2060, 0x2061, 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067, 0x2068, 0x2069, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 7 */ 0x2070, 0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079, 0x207A, 0x207B, 0x207C, 0x207D, 0x207E, 0x207F, + /* 8 */ 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087, 0x2088, 0x2089, 0x208A, 0x208B, 0x208C, 0x208D, 0x208E, 0x208F, + /* 9 */ 0x2090, 0x2091, 0x2092, 0x2093, 0x2094, 0x2095, 0x2096, 0x2097, 0x2098, 0x2099, 0x209A, 0x209B, 0x209C, 0x209D, 0x209E, 0x209F, + /* A */ 0x20A0, 0x20A1, 0x20A2, 0x20A3, 0x20A4, 0x20A5, 0x20A6, 0x20A7, 0x20A8, 0x20A9, 0x20AA, 0x20AB, 0x20AC, 0x20AD, 0x20AE, 0x20AF, + /* B */ 0x20B0, 0x20B1, 0x20B2, 0x20B3, 0x20B4, 0x20B5, 0x20B6, 0x20B7, 0x20B8, 0x20B9, 0x20BA, 0x20BB, 0x20BC, 0x20BD, 0x20BE, 0x20BF, + /* C */ 0x20C0, 0x20C1, 0x20C2, 0x20C3, 0x20C4, 0x20C5, 0x20C6, 0x20C7, 0x20C8, 0x20C9, 0x20CA, 0x20CB, 0x20CC, 0x20CD, 0x20CE, 0x20CF, + /* D */ 0x20D0, 0x20D1, 0x20D2, 0x20D3, 0x20D4, 0x20D5, 0x20D6, 0x20D7, 0x20D8, 0x20D9, 0x20DA, 0x20DB, 0x20DC, 0x20DD, 0x20DE, 0x20DF, + /* E */ 0x20E0, 0x20E1, 0x20E2, 0x20E3, 0x20E4, 0x20E5, 0x20E6, 0x20E7, 0x20E8, 0x20E9, 0x20EA, 0x20EB, 0x20EC, 0x20ED, 0x20EE, 0x20EF, + /* F */ 0x20F0, 0x20F1, 0x20F2, 0x20F3, 0x20F4, 0x20F5, 0x20F6, 0x20F7, 0x20F8, 0x20F9, 0x20FA, 0x20FB, 0x20FC, 0x20FD, 0x20FE, 0x20FF, + + // Table 8 (for high byte 0x21) + + /* 0 */ 0x2100, 0x2101, 0x2102, 0x2103, 0x2104, 0x2105, 0x2106, 0x2107, 0x2108, 0x2109, 0x210A, 0x210B, 0x210C, 0x210D, 0x210E, 0x210F, + /* 1 */ 0x2110, 0x2111, 0x2112, 0x2113, 0x2114, 0x2115, 0x2116, 0x2117, 0x2118, 0x2119, 0x211A, 0x211B, 0x211C, 0x211D, 0x211E, 0x211F, + /* 2 */ 0x2120, 0x2121, 0x2122, 0x2123, 0x2124, 0x2125, 0x2126, 0x2127, 0x2128, 0x2129, 0x212A, 0x212B, 0x212C, 0x212D, 0x212E, 0x212F, + /* 3 */ 0x2130, 0x2131, 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137, 0x2138, 0x2139, 0x213A, 0x213B, 0x213C, 0x213D, 0x213E, 0x213F, + /* 4 */ 0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2145, 0x2146, 0x2147, 0x2148, 0x2149, 0x214A, 0x214B, 0x214C, 0x214D, 0x214E, 0x214F, + /* 5 */ 0x2150, 0x2151, 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215A, 0x215B, 0x215C, 0x215D, 0x215E, 0x215F, + /* 6 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, + /* 7 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, + /* 8 */ 0x2180, 0x2181, 0x2182, 0x2183, 0x2184, 0x2185, 0x2186, 0x2187, 0x2188, 0x2189, 0x218A, 0x218B, 0x218C, 0x218D, 0x218E, 0x218F, + /* 9 */ 0x2190, 0x2191, 0x2192, 0x2193, 0x2194, 0x2195, 0x2196, 0x2197, 0x2198, 0x2199, 0x219A, 0x219B, 0x219C, 0x219D, 0x219E, 0x219F, + /* A */ 0x21A0, 0x21A1, 0x21A2, 0x21A3, 0x21A4, 0x21A5, 0x21A6, 0x21A7, 0x21A8, 0x21A9, 0x21AA, 0x21AB, 0x21AC, 0x21AD, 0x21AE, 0x21AF, + /* B */ 0x21B0, 0x21B1, 0x21B2, 0x21B3, 0x21B4, 0x21B5, 0x21B6, 0x21B7, 0x21B8, 0x21B9, 0x21BA, 0x21BB, 0x21BC, 0x21BD, 0x21BE, 0x21BF, + /* C */ 0x21C0, 0x21C1, 0x21C2, 0x21C3, 0x21C4, 0x21C5, 0x21C6, 0x21C7, 0x21C8, 0x21C9, 0x21CA, 0x21CB, 0x21CC, 0x21CD, 0x21CE, 0x21CF, + /* D */ 0x21D0, 0x21D1, 0x21D2, 0x21D3, 0x21D4, 0x21D5, 0x21D6, 0x21D7, 0x21D8, 0x21D9, 0x21DA, 0x21DB, 0x21DC, 0x21DD, 0x21DE, 0x21DF, + /* E */ 0x21E0, 0x21E1, 0x21E2, 0x21E3, 0x21E4, 0x21E5, 0x21E6, 0x21E7, 0x21E8, 0x21E9, 0x21EA, 0x21EB, 0x21EC, 0x21ED, 0x21EE, 0x21EF, + /* F */ 0x21F0, 0x21F1, 0x21F2, 0x21F3, 0x21F4, 0x21F5, 0x21F6, 0x21F7, 0x21F8, 0x21F9, 0x21FA, 0x21FB, 0x21FC, 0x21FD, 0x21FE, 0x21FF, + + // Table 9 (for high byte 0xFE) + + /* 0 */ 0xFE00, 0xFE01, 0xFE02, 0xFE03, 0xFE04, 0xFE05, 0xFE06, 0xFE07, 0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFE0E, 0xFE0F, + /* 1 */ 0xFE10, 0xFE11, 0xFE12, 0xFE13, 0xFE14, 0xFE15, 0xFE16, 0xFE17, 0xFE18, 0xFE19, 0xFE1A, 0xFE1B, 0xFE1C, 0xFE1D, 0xFE1E, 0xFE1F, + /* 2 */ 0xFE20, 0xFE21, 0xFE22, 0xFE23, 0xFE24, 0xFE25, 0xFE26, 0xFE27, 0xFE28, 0xFE29, 0xFE2A, 0xFE2B, 0xFE2C, 0xFE2D, 0xFE2E, 0xFE2F, + /* 3 */ 0xFE30, 0xFE31, 0xFE32, 0xFE33, 0xFE34, 0xFE35, 0xFE36, 0xFE37, 0xFE38, 0xFE39, 0xFE3A, 0xFE3B, 0xFE3C, 0xFE3D, 0xFE3E, 0xFE3F, + /* 4 */ 0xFE40, 0xFE41, 0xFE42, 0xFE43, 0xFE44, 0xFE45, 0xFE46, 0xFE47, 0xFE48, 0xFE49, 0xFE4A, 0xFE4B, 0xFE4C, 0xFE4D, 0xFE4E, 0xFE4F, + /* 5 */ 0xFE50, 0xFE51, 0xFE52, 0xFE53, 0xFE54, 0xFE55, 0xFE56, 0xFE57, 0xFE58, 0xFE59, 0xFE5A, 0xFE5B, 0xFE5C, 0xFE5D, 0xFE5E, 0xFE5F, + /* 6 */ 0xFE60, 0xFE61, 0xFE62, 0xFE63, 0xFE64, 0xFE65, 0xFE66, 0xFE67, 0xFE68, 0xFE69, 0xFE6A, 0xFE6B, 0xFE6C, 0xFE6D, 0xFE6E, 0xFE6F, + /* 7 */ 0xFE70, 0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE75, 0xFE76, 0xFE77, 0xFE78, 0xFE79, 0xFE7A, 0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F, + /* 8 */ 0xFE80, 0xFE81, 0xFE82, 0xFE83, 0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C, 0xFE8D, 0xFE8E, 0xFE8F, + /* 9 */ 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95, 0xFE96, 0xFE97, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E, 0xFE9F, + /* A */ 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7, 0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF, + /* B */ 0xFEB0, 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF, + /* C */ 0xFEC0, 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9, 0xFECA, 0xFECB, 0xFECC, 0xFECD, 0xFECE, 0xFECF, + /* D */ 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4, 0xFED5, 0xFED6, 0xFED7, 0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD, 0xFEDE, 0xFEDF, + /* E */ 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6, 0xFEE7, 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF, + /* F */ 0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8, 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0xFEFD, 0xFEFE, 0x0000, + + // Table 10 (for high byte 0xFF) + + /* 0 */ 0xFF00, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, 0xFF06, 0xFF07, 0xFF08, 0xFF09, 0xFF0A, 0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E, 0xFF0F, + /* 1 */ 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, 0xFF18, 0xFF19, 0xFF1A, 0xFF1B, 0xFF1C, 0xFF1D, 0xFF1E, 0xFF1F, + /* 2 */ 0xFF20, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, + /* 3 */ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0xFF3B, 0xFF3C, 0xFF3D, 0xFF3E, 0xFF3F, + /* 4 */ 0xFF40, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, + /* 5 */ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0xFF5B, 0xFF5C, 0xFF5D, 0xFF5E, 0xFF5F, + /* 6 */ 0xFF60, 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67, 0xFF68, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F, + /* 7 */ 0xFF70, 0xFF71, 0xFF72, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77, 0xFF78, 0xFF79, 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F, + /* 8 */ 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87, 0xFF88, 0xFF89, 0xFF8A, 0xFF8B, 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F, + /* 9 */ 0xFF90, 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97, 0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F, + /* A */ 0xFFA0, 0xFFA1, 0xFFA2, 0xFFA3, 0xFFA4, 0xFFA5, 0xFFA6, 0xFFA7, 0xFFA8, 0xFFA9, 0xFFAA, 0xFFAB, 0xFFAC, 0xFFAD, 0xFFAE, 0xFFAF, + /* B */ 0xFFB0, 0xFFB1, 0xFFB2, 0xFFB3, 0xFFB4, 0xFFB5, 0xFFB6, 0xFFB7, 0xFFB8, 0xFFB9, 0xFFBA, 0xFFBB, 0xFFBC, 0xFFBD, 0xFFBE, 0xFFBF, + /* C */ 0xFFC0, 0xFFC1, 0xFFC2, 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC6, 0xFFC7, 0xFFC8, 0xFFC9, 0xFFCA, 0xFFCB, 0xFFCC, 0xFFCD, 0xFFCE, 0xFFCF, + /* D */ 0xFFD0, 0xFFD1, 0xFFD2, 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6, 0xFFD7, 0xFFD8, 0xFFD9, 0xFFDA, 0xFFDB, 0xFFDC, 0xFFDD, 0xFFDE, 0xFFDF, + /* E */ 0xFFE0, 0xFFE1, 0xFFE2, 0xFFE3, 0xFFE4, 0xFFE5, 0xFFE6, 0xFFE7, 0xFFE8, 0xFFE9, 0xFFEA, 0xFFEB, 0xFFEC, 0xFFED, 0xFFEE, 0xFFEF, + /* F */ 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7, 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF, +}; + +/* RelString case folding table */ + +unsigned short gCompareTable[] = { + + /* 0 */ 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, 0x0F00, + /* 1 */ 0x1000, 0x1100, 0x1200, 0x1300, 0x1400, 0x1500, 0x1600, 0x1700, 0x1800, 0x1900, 0x1A00, 0x1B00, 0x1C00, 0x1D00, 0x1E00, 0x1F00, + /* 2 */ 0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x2600, 0x2700, 0x2800, 0x2900, 0x2A00, 0x2B00, 0x2C00, 0x2D00, 0x2E00, 0x2F00, + /* 3 */ 0x3000, 0x3100, 0x3200, 0x3300, 0x3400, 0x3500, 0x3600, 0x3700, 0x3800, 0x3900, 0x3A00, 0x3B00, 0x3C00, 0x3D00, 0x3E00, 0x3F00, + /* 4 */ 0x4000, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700, 0x4800, 0x4900, 0x4A00, 0x4B00, 0x4C00, 0x4D00, 0x4E00, 0x4F00, + /* 5 */ 0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x5500, 0x5600, 0x5700, 0x5800, 0x5900, 0x5A00, 0x5B00, 0x5C00, 0x5D00, 0x5E00, 0x5F00, + + // 0x60 maps to 'a' + // range 0x61 to 0x7a ('a' to 'z') map to upper case + + /* 6 */ 0x4180, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700, 0x4800, 0x4900, 0x4A00, 0x4B00, 0x4C00, 0x4D00, 0x4E00, 0x4F00, + /* 7 */ 0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x5500, 0x5600, 0x5700, 0x5800, 0x5900, 0x5A00, 0x7B00, 0x7C00, 0x7D00, 0x7E00, 0x7F00, + + // range 0x80 to 0xd8 gets mapped... + + /* 8 */ 0x4108, 0x410C, 0x4310, 0x4502, 0x4E0A, 0x4F08, 0x5508, 0x4182, 0x4104, 0x4186, 0x4108, 0x410A, 0x410C, 0x4310, 0x4502, 0x4584, + /* 9 */ 0x4586, 0x4588, 0x4982, 0x4984, 0x4986, 0x4988, 0x4E0A, 0x4F82, 0x4F84, 0x4F86, 0x4F08, 0x4F0A, 0x5582, 0x5584, 0x5586, 0x5508, + /* A */ 0xA000, 0xA100, 0xA200, 0xA300, 0xA400, 0xA500, 0xA600, 0x5382, 0xA800, 0xA900, 0xAA00, 0xAB00, 0xAC00, 0xAD00, 0x4114, 0x4F0E, + /* B */ 0xB000, 0xB100, 0xB200, 0xB300, 0xB400, 0xB500, 0xB600, 0xB700, 0xB800, 0xB900, 0xBA00, 0x4192, 0x4F92, 0xBD00, 0x4114, 0x4F0E, + /* C */ 0xC000, 0xC100, 0xC200, 0xC300, 0xC400, 0xC500, 0xC600, 0x2206, 0x2208, 0xC900, 0x2000, 0x4104, 0x410A, 0x4F0A, 0x4F14, 0x4F14, + /* D */ 0xD000, 0xD100, 0x2202, 0x2204, 0x2702, 0x2704, 0xD600, 0xD700, 0x5988, 0xD900, 0xDA00, 0xDB00, 0xDC00, 0xDD00, 0xDE00, 0xDF00, + + /* E */ 0xE000, 0xE100, 0xE200, 0xE300, 0xE400, 0xE500, 0xE600, 0xE700, 0xE800, 0xE900, 0xEA00, 0xEB00, 0xEC00, 0xED00, 0xEE00, 0xEF00, + /* F */ 0xF000, 0xF100, 0xF200, 0xF300, 0xF400, 0xF500, 0xF600, 0xF700, 0xF800, 0xF900, 0xFA00, 0xFB00, 0xFC00, 0xFD00, 0xFE00, 0xFF00, + +}; +#else /* ! UNCOMPRESSED */ + +enum { + kTypeLiteral = 0, + kTypeAscending = 1, + kTypeAscending256 = 2 +}; + +struct compressed_block { + unsigned char type; + unsigned char count; + unsigned short data; +}; + +unsigned short *gLowerCaseTable; + +struct compressed_block gLowerCaseTableCompressed[] = { + {0x0, 0x1, 0x100}, + {0x0, 0x1, 0x200}, + {0x0, 0x1, 0x0}, + {0x0, 0x1, 0x300}, + {0x0, 0x1, 0x400}, + {0x0, 0x1, 0x500}, + {0x0, 0xa, 0x0}, + {0x0, 0x1, 0x600}, + {0x0, 0xf, 0x0}, + {0x0, 0x1, 0x700}, + {0x0, 0x1, 0x800}, + {0x0, 0xdc, 0x0}, + {0x0, 0x1, 0x900}, + {0x0, 0x1, 0xa00}, + {0x0, 0x1, 0xffff}, + {0x1, 0x40, 0x1}, + {0x1, 0x1a, 0x61}, + {0x1, 0x6b, 0x5b}, + {0x0, 0x1, 0xe6}, + {0x1, 0x9, 0xc7}, + {0x0, 0x1, 0xf0}, + {0x1, 0x7, 0xd1}, + {0x0, 0x1, 0xf8}, + {0x1, 0x5, 0xd9}, + {0x0, 0x1, 0xfe}, + {0x1, 0x31, 0xdf}, + {0x0, 0x2, 0x111}, + {0x1, 0x14, 0x112}, + {0x0, 0x2, 0x127}, + {0x1, 0xa, 0x128}, + {0x0, 0x2, 0x133}, + {0x1, 0xb, 0x134}, + {0x0, 0x2, 0x140}, + {0x0, 0x2, 0x142}, + {0x1, 0x7, 0x143}, + {0x0, 0x2, 0x14b}, + {0x1, 0x6, 0x14c}, + {0x0, 0x2, 0x153}, + {0x1, 0x12, 0x154}, + {0x0, 0x2, 0x167}, + {0x1, 0x19, 0x168}, + {0x0, 0x1, 0x253}, + {0x0, 0x2, 0x183}, + {0x0, 0x2, 0x185}, + {0x0, 0x1, 0x254}, + {0x0, 0x2, 0x188}, + {0x1, 0x2, 0x256}, + {0x0, 0x2, 0x18c}, + {0x0, 0x1, 0x18d}, + {0x0, 0x1, 0x1dd}, + {0x0, 0x1, 0x259}, + {0x0, 0x1, 0x25b}, + {0x0, 0x2, 0x192}, + {0x0, 0x1, 0x260}, + {0x0, 0x1, 0x263}, + {0x0, 0x1, 0x195}, + {0x0, 0x1, 0x269}, + {0x0, 0x1, 0x268}, + {0x0, 0x2, 0x199}, + {0x1, 0x2, 0x19a}, + {0x0, 0x1, 0x26f}, + {0x0, 0x1, 0x272}, + {0x0, 0x1, 0x19e}, + {0x0, 0x1, 0x275}, + {0x1, 0x2, 0x1a0}, + {0x0, 0x2, 0x1a3}, + {0x0, 0x2, 0x1a5}, + {0x0, 0x1, 0x1a6}, + {0x0, 0x2, 0x1a8}, + {0x0, 0x1, 0x283}, + {0x1, 0x2, 0x1aa}, + {0x0, 0x2, 0x1ad}, + {0x0, 0x1, 0x288}, + {0x1, 0x2, 0x1af}, + {0x1, 0x2, 0x28a}, + {0x0, 0x2, 0x1b4}, + {0x0, 0x2, 0x1b6}, + {0x0, 0x1, 0x292}, + {0x0, 0x2, 0x1b9}, + {0x1, 0x2, 0x1ba}, + {0x0, 0x2, 0x1bd}, + {0x1, 0x6, 0x1be}, + {0x0, 0x3, 0x1c6}, + {0x0, 0x3, 0x1c9}, + {0x0, 0x3, 0x1cc}, + {0x1, 0x17, 0x1cd}, + {0x0, 0x2, 0x1e5}, + {0x1, 0xb, 0x1e6}, + {0x0, 0x3, 0x1f3}, + {0x1, 0xc, 0x1f4}, + {0x1, 0x91, 0x300}, + {0x1, 0x11, 0x3b1}, + {0x0, 0x1, 0x3a2}, + {0x1, 0x7, 0x3c3}, + {0x1, 0x38, 0x3aa}, + {0x0, 0x2, 0x3e3}, + {0x0, 0x2, 0x3e5}, + {0x0, 0x2, 0x3e7}, + {0x0, 0x2, 0x3e9}, + {0x0, 0x2, 0x3eb}, + {0x0, 0x2, 0x3ed}, + {0x0, 0x2, 0x3ef}, + {0x1, 0x12, 0x3f0}, + {0x0, 0x1, 0x452}, + {0x0, 0x1, 0x403}, + {0x1, 0x3, 0x454}, + {0x0, 0x1, 0x407}, + {0x1, 0x4, 0x458}, + {0x1, 0x3, 0x40c}, + {0x0, 0x1, 0x45f}, + {0x1, 0x9, 0x430}, + {0x0, 0x1, 0x419}, + {0x1, 0x16, 0x43a}, + {0x1, 0x30, 0x430}, + {0x0, 0x2, 0x461}, + {0x0, 0x2, 0x463}, + {0x0, 0x2, 0x465}, + {0x0, 0x2, 0x467}, + {0x0, 0x2, 0x469}, + {0x0, 0x2, 0x46b}, + {0x0, 0x2, 0x46d}, + {0x0, 0x2, 0x46f}, + {0x0, 0x2, 0x471}, + {0x0, 0x2, 0x473}, + {0x0, 0x2, 0x475}, + {0x1, 0x2, 0x476}, + {0x0, 0x2, 0x479}, + {0x0, 0x2, 0x47b}, + {0x0, 0x2, 0x47d}, + {0x0, 0x2, 0x47f}, + {0x0, 0x2, 0x481}, + {0x1, 0xe, 0x482}, + {0x0, 0x2, 0x491}, + {0x0, 0x2, 0x493}, + {0x0, 0x2, 0x495}, + {0x0, 0x2, 0x497}, + {0x0, 0x2, 0x499}, + {0x0, 0x2, 0x49b}, + {0x0, 0x2, 0x49d}, + {0x0, 0x2, 0x49f}, + {0x0, 0x2, 0x4a1}, + {0x0, 0x2, 0x4a3}, + {0x0, 0x2, 0x4a5}, + {0x0, 0x2, 0x4a7}, + {0x0, 0x2, 0x4a9}, + {0x0, 0x2, 0x4ab}, + {0x0, 0x2, 0x4ad}, + {0x0, 0x2, 0x4af}, + {0x0, 0x2, 0x4b1}, + {0x0, 0x2, 0x4b3}, + {0x0, 0x2, 0x4b5}, + {0x0, 0x2, 0x4b7}, + {0x0, 0x2, 0x4b9}, + {0x0, 0x2, 0x4bb}, + {0x0, 0x2, 0x4bd}, + {0x0, 0x2, 0x4bf}, + {0x1, 0x3, 0x4c0}, + {0x0, 0x2, 0x4c4}, + {0x1, 0x2, 0x4c5}, + {0x0, 0x2, 0x4c8}, + {0x1, 0x2, 0x4c9}, + {0x0, 0x2, 0x4cc}, + {0x1, 0x64, 0x4cd}, + {0x1, 0x26, 0x561}, + {0x1, 0xa9, 0x557}, + {0x1, 0xa0, 0x1000}, + {0x1, 0x26, 0x10d0}, + {0x1, 0x3a, 0x10c6}, + {0x1, 0xc, 0x2000}, + {0x0, 0x4, 0x0}, + {0x1, 0x1a, 0x2010}, + {0x0, 0x5, 0x0}, + {0x1, 0x3b, 0x202f}, + {0x0, 0x6, 0x0}, + {0x1, 0xf0, 0x2070}, + {0x1, 0x10, 0x2170}, + {0x1, 0x90, 0x2170}, + {0x1, 0xff, 0xfe00}, + {0x0, 0x1, 0x0}, + {0x1, 0x21, 0xff00}, + {0x1, 0x1a, 0xff41}, + {0x1, 0xc5, 0xff3b}, +}; +// Please update count if you add/remove entries but also please just let +// the compiler calculate it so you don't get it wrong. +//#define kLowerCaseTableNBlocks 182 +#define kLowerCaseTableNBlocks (sizeof(gLowerCaseTableCompressed)/sizeof(*gLowerCaseTableCompressed)) +// WARNING: The expanded size MUST be updated if you change the table and +// cannot be calculated at compile time. +#define kLowerCaseTableDataSize 5632 /* size of uncompressed structure in bytes */ + +unsigned short *gCompareTable; + +struct compressed_block gCompareTableCompressed[] = { + {0x2, 0x60, 0x0}, + {0x0, 0x1, 0x4180}, + {0x2, 0x1a, 0x4100}, + {0x2, 0x5, 0x7b00}, + {0x0, 0x1, 0x4108}, + {0x0, 0x1, 0x410c}, + {0x0, 0x1, 0x4310}, + {0x0, 0x1, 0x4502}, + {0x0, 0x1, 0x4e0a}, + {0x0, 0x1, 0x4f08}, + {0x0, 0x1, 0x5508}, + {0x0, 0x1, 0x4182}, + {0x0, 0x1, 0x4104}, + {0x0, 0x1, 0x4186}, + {0x0, 0x1, 0x4108}, + {0x0, 0x1, 0x410a}, + {0x0, 0x1, 0x410c}, + {0x0, 0x1, 0x4310}, + {0x0, 0x1, 0x4502}, + {0x0, 0x1, 0x4584}, + {0x0, 0x1, 0x4586}, + {0x0, 0x1, 0x4588}, + {0x0, 0x1, 0x4982}, + {0x0, 0x1, 0x4984}, + {0x0, 0x1, 0x4986}, + {0x0, 0x1, 0x4988}, + {0x0, 0x1, 0x4e0a}, + {0x0, 0x1, 0x4f82}, + {0x0, 0x1, 0x4f84}, + {0x0, 0x1, 0x4f86}, + {0x0, 0x1, 0x4f08}, + {0x0, 0x1, 0x4f0a}, + {0x0, 0x1, 0x5582}, + {0x0, 0x1, 0x5584}, + {0x0, 0x1, 0x5586}, + {0x0, 0x1, 0x5508}, + {0x2, 0x7, 0xa000}, + {0x0, 0x1, 0x5382}, + {0x2, 0x6, 0xa800}, + {0x0, 0x1, 0x4114}, + {0x0, 0x1, 0x4f0e}, + {0x2, 0xb, 0xb000}, + {0x0, 0x1, 0x4192}, + {0x0, 0x1, 0x4f92}, + {0x0, 0x1, 0xbd00}, + {0x0, 0x1, 0x4114}, + {0x0, 0x1, 0x4f0e}, + {0x2, 0x7, 0xc000}, + {0x0, 0x1, 0x2206}, + {0x0, 0x1, 0x2208}, + {0x0, 0x1, 0xc900}, + {0x0, 0x1, 0x2000}, + {0x0, 0x1, 0x4104}, + {0x0, 0x1, 0x410a}, + {0x0, 0x1, 0x4f0a}, + {0x0, 0x2, 0x4f14}, + {0x2, 0x2, 0xd000}, + {0x0, 0x1, 0x2202}, + {0x0, 0x1, 0x2204}, + {0x0, 0x1, 0x2702}, + {0x0, 0x1, 0x2704}, + {0x2, 0x2, 0xd600}, + {0x0, 0x1, 0x5988}, + {0x2, 0x27, 0xd900}, +}; +// Please update count if you add/remove entries but also please just let +// the compiler calculate it so you don't get it wrong. +//#define kCompareTableNBlocks 64 +#define kCompareTableNBlocks (sizeof(gCompareTableCompressed)/sizeof(*gCompareTableCompressed)) +// WARNING: The expanded size MUST be updated if you change the table and +// cannot be calculated at compile time. +#define kCompareTableDataSize 512 /* size of uncompressed structure in bytes */ + +#endif /* UNCOMPRESSED */ Index: branches/slice/trunkM/i386/libsaio/vbe.c =================================================================== --- branches/slice/trunkM/i386/libsaio/vbe.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/vbe.c (revision 1171) @@ -0,0 +1,310 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright 1993 NeXT, Inc. + * All rights reserved. + */ + +#include "libsaio.h" +#include "vbe.h" + +/* + * Various inline routines for video I/O + */ +static inline void +outi (int port, int index, int val) +{ + outw (port, (val << 8) | index); +} + +static inline void +outib (int port, int index, int val) +{ + outb (port, index); + outb (port + 1, val); +} + +static inline int +ini (int port, int index) +{ + outb (port, index); + return inb (port + 1); +} + +static inline void +rmwi (int port, int index, int clear, int set) +{ + outb (port, index); + outb (port + 1, (inb (port + 1) & ~clear) | set); +} + +/* + * Globals + */ +static biosBuf_t bb; + +int getVBEInfo( void * infoBlock ) +{ + bb.intno = 0x10; + bb.eax.rr = funcGetControllerInfo; + bb.es = SEG( infoBlock ); + bb.edi.rr = OFF( infoBlock ); + bios( &bb ); + return(bb.eax.r.h); +} + +int getVBEModeInfo( int mode, void * minfo_p ) +{ + bb.intno = 0x10; + bb.eax.rr = funcGetModeInfo; + bb.ecx.rr = mode; + bb.es = SEG(minfo_p); + bb.edi.rr = OFF(minfo_p); + bios(&bb); + return(bb.eax.r.h); +} + +int getVBEDACFormat(unsigned char *format) +{ + bb.intno = 0x10; + bb.eax.rr = funcGetSetPaletteFormat; + bb.ebx.r.l = subfuncGet; + bios(&bb); + *format = bb.ebx.r.h; + return(bb.eax.r.h); +} + +int setVBEDACFormat(unsigned char format) +{ + bb.intno = 0x10; + bb.eax.rr = funcGetSetPaletteFormat; + bb.ebx.r.l = subfuncSet; + bb.ebx.r.h = format; + bios(&bb); + return(bb.eax.r.h); +} + +/* + * Default GTF parameter values. + */ +#define kCellGranularity 8.0 // character cell granularity +#define kMinVSyncPlusBP 550.0 // min VSync + BP interval (us) +#define kMinFrontPorch 1.0 // minimum front porch in lines(V)/cells(H) +#define kVSyncLines 3.0 // width of VSync in lines +#define kHSyncWidth 8.0 // HSync as a percent of total line width +#define kC 30.0 // C = (C'-J) * (K/256) + J +#define kM 300.0 // M = K/256 * M' + +int Round(double f) +{ + return (int)(f + 0.5); +} + +/* + * from http://www.azillionmonkeys.com/qed/sqroot.html + */ + +double Sqrt( double y ) +{ + double x, z, tempf; + unsigned long *tfptr = ((unsigned long *)&tempf) + 1; + + tempf = y; + *tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */ + x = tempf; + z = y*0.5; /* hoist out the “/2” */ + x = (1.5*x) - (x*x)*(x*z); /* iteration formula */ + x = (1.5*x) - (x*x)*(x*z); + x = (1.5*x) - (x*x)*(x*z); + x = (1.5*x) - (x*x)*(x*z); + x = (1.5*x) - (x*x)*(x*z); + return x*y; +} + +int generateCRTCTiming( unsigned short width, + unsigned short height, + unsigned long paramValue, + int paramType, + VBECRTCInfoBlock * timing ) +{ + double h_period_est, h_freq, h_period, h_total_pixels, h_sync_pixels; + double h_active_pixels, h_ideal_duty_cycle, h_blank_pixels, pixel_freq = 0; + double v_sync_plus_bp = 0, v_total_lines = 0, v_field_rate_est, v_frame_rate = 0; + const double h_pixels = (double) width; + const double v_lines = (double) height; + + enum { + left_margin_pixels = 0, + right_margin_pixels = 0, + top_margin_lines = 0, + bot_margin_lines = 0, + interlace = 0 + }; + + // Total number of active pixels in image and both margins + h_active_pixels = h_pixels + left_margin_pixels + right_margin_pixels; + + if (paramType == kCRTCParamPixelClock) + { + // Pixel clock provided in MHz + pixel_freq = (double) paramValue / 1000000; + + // Ideal horizontal period from the blanking duty cycle equation + h_period = ((kC - 100) + (Sqrt(((100 - kC) * (100 - kC)) + (0.4 * kM * + (h_active_pixels + right_margin_pixels + left_margin_pixels) / + pixel_freq)))) / 2.0 / kM * 1000; + } + else /* kCRTCParamRefreshRate */ + { + double v_field_rate_in = (double) paramValue; + + // Estimate the horizontal period + h_period_est = ((1 / v_field_rate_in) - kMinVSyncPlusBP / 1000000) / + (v_lines + (2 * top_margin_lines) + kMinFrontPorch + interlace) * + 1000000; + + // Number of lines in Vsync + back porch + v_sync_plus_bp = Round(kMinVSyncPlusBP / h_period_est); + + // Total number of lines in Vetical field period + v_total_lines = v_lines + top_margin_lines + bot_margin_lines + + v_sync_plus_bp + interlace + kMinFrontPorch; + + // Estimate the vertical field frequency + v_field_rate_est = 1 / h_period_est / v_total_lines * 1000000; + + // Find the actual horizontal period + h_period = h_period_est / (v_field_rate_in / v_field_rate_est); + + // Find the vertical frame rate (no interlace) + v_frame_rate = 1 / h_period / v_total_lines * 1000000; + } + + // Ideal blanking duty cycle from the blanking duty cycle equation + h_ideal_duty_cycle = kC - (kM * h_period / 1000); + + // Number of pixels in the blanking time to the nearest double character cell + h_blank_pixels = Round(h_active_pixels * h_ideal_duty_cycle / + (100 - h_ideal_duty_cycle) / (2 * kCellGranularity)) * + (2 * kCellGranularity); + + // Total number of horizontal pixels + h_total_pixels = h_active_pixels + h_blank_pixels; + + if (paramType == kCRTCParamPixelClock) + { + // Horizontal frequency + h_freq = pixel_freq / h_total_pixels * 1000; + + // Number of lines in V sync + back porch + v_sync_plus_bp = Round(kMinVSyncPlusBP * h_freq / 1000); + + // Total number of lines in vertical field period + v_total_lines = v_lines + top_margin_lines + bot_margin_lines + + interlace + v_sync_plus_bp + kMinFrontPorch; + + // Vertical frame frequency + v_frame_rate = Round(h_freq / v_total_lines * 1000); + } + else + { + // Find pixel clock frequency + pixel_freq = Round(h_total_pixels / h_period); + } + + h_sync_pixels = Round(h_total_pixels * kHSyncWidth / 100 / kCellGranularity) * + kCellGranularity; + + timing->HTotal = h_total_pixels; + timing->HSyncStart = h_active_pixels + (h_blank_pixels / 2) - h_sync_pixels; + timing->HSyncEnd = timing->HSyncStart + h_sync_pixels; + timing->VTotal = v_total_lines; + timing->VSyncStart = v_total_lines - v_sync_plus_bp; + timing->VSyncEnd = timing->VSyncStart + kVSyncLines; + timing->Flags = kCRTCNegativeHorizontalSync; + timing->PixelClock = pixel_freq * 1000000; + timing->RefreshRate = v_frame_rate * 100; + + return 0; +} + +int setVBEMode(unsigned short mode, const VBECRTCInfoBlock * timing) +{ + bb.intno = 0x10; + bb.eax.rr = funcSetMode; + bb.ebx.rr = mode; + if (timing) { + bb.es = SEG(timing); + bb.edi.rr = OFF(timing); + } + bios(&bb); + return(bb.eax.r.h); +} + +int setVBEPalette(void *palette) +{ + bb.intno = 0x10; + bb.eax.rr = funcGetSetPaletteData; + bb.ebx.r.l = subfuncSet; + bb.ecx.rr = 256; + bb.edx.rr = 0; + bb.es = SEG(palette); + bb.edi.rr = OFF(palette); + bios(&bb); + return(bb.eax.r.h); +} + +int getVBEPalette(void *palette) +{ + bb.intno = 0x10; + bb.eax.rr = funcGetSetPaletteData; + bb.ebx.r.l = subfuncGet; + bb.ecx.rr = 256; + bb.edx.rr = 0; + bb.es = SEG(palette); + bb.edi.rr = OFF(palette); + bios(&bb); + return(bb.eax.r.h); +} + +int getVBECurrentMode(unsigned short *mode) +{ + bb.intno = 0x10; + bb.eax.rr = funcGetCurrentMode; + bios(&bb); + *mode = bb.ebx.rr; + return(bb.eax.r.h); +} + +int getVBEPixelClock(unsigned short mode, unsigned long * pixelClock) +{ + bb.intno = 0x10; + bb.eax.rr = funcGetSetPixelClock; + bb.ebx.r.l = 0; + bb.ecx.rx = *pixelClock; + bb.edx.rr = mode; + bios(&bb); + *pixelClock = bb.ecx.rx; + return(bb.eax.r.h); +} Index: branches/slice/trunkM/i386/libsaio/bootstruct.h =================================================================== --- branches/slice/trunkM/i386/libsaio/bootstruct.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/bootstruct.h (revision 1171) @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 2002-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __BOOTSTRUCT_H +#define __BOOTSTRUCT_H + +#include "bootargs.h" +#include "saio_types.h" +#include "bios.h" +#include "device_tree.h" + +/*! + Kernel boot args global also used by booter for its own data. + */ +extern boot_args *bootArgs; +extern boot_args_pre_lion *bootArgsPreLion; +extern Node *gMemoryMapNode; + +#define VGA_TEXT_MODE 0 +//defined in /usr/../boot.h + +//#define GRAPHICS_MODE 1 +//#define FB_TEXT_MODE 2 + + + +/* + * Maximum number of boot drivers that can be loaded. + */ +#define NDRIVERS 500 + +#define CONFIG_SIZE (40 * 4096) + +/* + * Max size for config data array, in bytes. + */ +#define IO_CONFIG_DATA_SIZE 163840 + +#define kMemoryMapCountMax 40 + +/* + * PCI bus information. + */ +typedef struct _PCI_bus_info_t { + union { + struct { + unsigned char configMethod1 :1; + unsigned char configMethod2 :1; + unsigned char :2; + unsigned char specialCycle1 :1; + unsigned char specialCycle2 :1; + } s; + unsigned char d; + } u_bus; + unsigned char maxBusNum; + unsigned char majorVersion; + unsigned char minorVersion; + unsigned char BIOSPresent; +} PCI_bus_info_t; + +typedef struct { + unsigned long address; // address where driver was loaded + unsigned long size; // number of bytes + unsigned long type; // driver type +} driver_config_t; + +/* + * INT15, E820h - Query System Address Map. + * + * Documented in ACPI Specification Rev 2.0, + * Chapter 15 (System Address Map Interfaces). + */ + +/* + * ACPI defined memory range types. + */ +enum { + kMemoryRangeUsable = 1, // RAM usable by the OS. + kMemoryRangeReserved = 2, // Reserved. (Do not use) + kMemoryRangeACPI = 3, // ACPI tables. Can be reclaimed. + kMemoryRangeNVS = 4, // ACPI NVS memory. (Do not use) + + /* Undefined types should be treated as kMemoryRangeReserved */ +}; + +/*! + PrivateBootInfo has fields used by the booter that used to be part of + KernelBootArgs_t *bootArgs. When the switch was made to EFI the structure + completely changed to boot_args *bootArgs. This (new to boot-132) structure + contains the fields the kernel no longer cares about but the booter still + uses internally. Some fields (e.g. the video information) remain interesting + to the kernel and are thus located in bootArgs although with different field names. + */ +typedef struct PrivateBootInfo { + int convmem; // conventional memory + int extmem; // extended memory +#if 0 + int numBootDrivers; // number of drivers loaded +#endif + char bootFile[128]; // kernel file name + + unsigned long memoryMapCount; + MemoryRange memoryMap[kMemoryMapCountMax]; + + PCI_bus_info_t pciInfo; + +#if 0 + driver_config_t driverConfig[NDRIVERS]; +#endif + char * configEnd; // pointer to end of config files + char config[CONFIG_SIZE]; + + config_file_t bootConfig; // com.apple.Boot.plist + config_file_t chameleonConfig; // org.chameleon.Boot.plist which can override bootConfig keys + config_file_t themeConfig; // theme.plist + config_file_t smbiosConfig; // smbios.plist + config_file_t helperConfig; // boot helper partition's boot.plist + config_file_t ramdiskConfig; // RAMDisk.plist + + bool memDetect; +} PrivateBootInfo_t; + +extern PrivateBootInfo_t *bootInfo; + +#endif /* __BOOTSTRUCT_H */ Index: branches/slice/trunkM/i386/libsaio/device_tree.c =================================================================== --- branches/slice/trunkM/i386/libsaio/device_tree.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/device_tree.c (revision 1171) @@ -0,0 +1,540 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All Rights Reserved. + */ + +#if 1 +/* + + Structures for a Flattened Device Tree + */ + +#define kPropNameLength 32 + +typedef struct DeviceTreeNodeProperty { + char name[kPropNameLength]; // NUL terminated property name + unsigned long length; // Length (bytes) of folloing prop value + // unsigned long value[1]; // Variable length value of property + // Padded to a multiple of a longword? +} DeviceTreeNodeProperty; + +typedef struct OpaqueDTEntry { + unsigned long nProperties; // Number of props[] elements (0 => end) + unsigned long nChildren; // Number of children[] elements + // DeviceTreeNodeProperty props[];// array size == nProperties + // DeviceTreeNode children[]; // array size == nChildren +} DeviceTreeNode; + +typedef char DTPropertyNameBuf[32]; +/* Entry Name Definitions (Entry Names are C-Strings)*/ +enum { + kDTMaxEntryNameLength = 31 /* Max length of a C-String Entry Name (terminator not included) */ +}; + +/* length of DTEntryNameBuf = kDTMaxEntryNameLength +1*/ +typedef char DTEntryNameBuf[32]; +#endif + +#include "libsaio.h" +#include "device_tree.h" + +#if DEBUG +#define DPRINTF(args...) printf(args) +void +DT__PrintTree(Node *node); +#else +#define DPRINTF(args...) +#endif + + +#define RoundToLong(x) (((x) + 3) & ~3) + +static struct _DTSizeInfo { + uint32_t numNodes; + uint32_t numProperties; + uint32_t totalPropertySize; +} DTInfo; + +#define kAllocSize 4096 + +static Node *rootNode; + +static Node *freeNodes, *allocedNodes; +static Property *freeProperties, *allocedProperties; + +Property * +DT__AddProperty(Node *node, const char *name, uint32_t length, void *value) +{ + Property *prop; + + DPRINTF("DT__AddProperty([Node '%s'], '%s', %d, 0x%x)\n", DT__GetName(node), name, length, value); + if (freeProperties == NULL) { + void *buf = malloc(kAllocSize); + int i; + + DPRINTF("Allocating more free properties\n"); + if (buf == 0) return 0; + bzero(buf, kAllocSize); + // Use the first property to record the allocated buffer + // for later freeing. + prop = (Property *)buf; + prop->next = allocedProperties; + allocedProperties = prop; + prop->value = buf; + prop++; + for (i=1; i<(kAllocSize / sizeof(Property)); i++) { + prop->next = freeProperties; + freeProperties = prop; + prop++; + } + } + prop = freeProperties; + freeProperties = prop->next; + + prop->name = name; + prop->length = length; + prop->value = value; + + // Always add to end of list + if (node->properties == 0) { + node->properties = prop; + } else { + node->last_prop->next = prop; + } + node->last_prop = prop; + prop->next = 0; + + DPRINTF("Done [0x%x]\n", prop); + + DTInfo.numProperties++; + DTInfo.totalPropertySize += RoundToLong(length); + + return prop; +} + +Node * +DT__AddChild(Node *parent, const char *name) +{ + Node *node; + + if (freeNodes == NULL) { + void *buf = malloc(kAllocSize); + int i; + + DPRINTF("Allocating more free nodes\n"); + if (buf == 0) return 0; + bzero(buf, kAllocSize); + node = (Node *)buf; + // Use the first node to record the allocated buffer + // for later freeing. + node->next = allocedNodes; + allocedNodes = node; + node->children = (Node *)buf; + node++; + for (i=1; i<(kAllocSize / sizeof(Node)); i++) { + node->next = freeNodes; + freeNodes = node; + node++; + } + } + DPRINTF("DT__AddChild(0x%x, '%s')\n", parent, name); + node = freeNodes; + freeNodes = node->next; + DPRINTF("Got free node 0x%x\n", node); + DPRINTF("prop = 0x%x, children = 0x%x, next = 0x%x\n", node->properties, node->children, node->next); + + if (parent == NULL) { + rootNode = node; + node->next = 0; + } else { + node->next = parent->children; + parent->children = node; + } + DTInfo.numNodes++; + DT__AddProperty(node, "name", strlen(name) + 1, (void *) name); + return node; +} + +void +DT__FreeProperty(Property *prop) +{ + prop->next = freeProperties; + freeProperties = prop; +} +void +DT__FreeNode(Node *node) +{ + node->next = freeNodes; + freeNodes = node; +} + +void +DT__Initialize(void) +{ + DPRINTF("DT__Initialize\n"); + + freeNodes = 0; + allocedNodes = 0; + freeProperties = 0; + allocedProperties = 0; + + DTInfo.numNodes = 0; + DTInfo.numProperties = 0; + DTInfo.totalPropertySize = 0; + + rootNode = DT__AddChild(NULL, "/"); + DPRINTF("DT__Initialize done\n"); +} + +/* + * Free up memory used by in-memory representation + * of device tree. + */ +void +DT__Finalize(void) +{ + Node *node; + Property *prop; + + DPRINTF("DT__Finalize\n"); + for (prop = allocedProperties; prop != NULL; prop = prop->next) { + free(prop->value); + } + allocedProperties = NULL; + freeProperties = NULL; + + for (node = allocedNodes; node != NULL; node = node->next) { + free((void *)node->children); + } + allocedNodes = NULL; + freeNodes = NULL; + rootNode = NULL; + + // XXX leaks any created strings + + DTInfo.numNodes = 0; + DTInfo.numProperties = 0; + DTInfo.totalPropertySize = 0; +} + +static void * +FlattenNodes(Node *node, void *buffer) +{ + Property *prop; + DeviceTreeNode *flatNode; + DeviceTreeNodeProperty *flatProp; + int count; + + if (node == 0) return buffer; + + flatNode = (DeviceTreeNode *)buffer; + buffer += sizeof(DeviceTreeNode); + + for (count = 0, prop = node->properties; prop != 0; count++, prop = prop->next) { + flatProp = (DeviceTreeNodeProperty *)buffer; + strcpy(flatProp->name, prop->name); + flatProp->length = prop->length; + buffer += sizeof(DeviceTreeNodeProperty); + bcopy(prop->value, buffer, prop->length); + buffer += RoundToLong(prop->length); + } + flatNode->nProperties = count; + + for (count = 0, node = node->children; node != 0; count++, node = node->next) { + buffer = FlattenNodes(node, buffer); + } + flatNode->nChildren = count; + + return buffer; +} + +/* + * Flatten the in-memory representation of the device tree + * into a binary DT block. + * To get the buffer size needed, call with result = 0. + * To have a buffer allocated for you, call with *result = 0. + * To use your own buffer, call with *result = &buffer. + */ + +void +DT__FlattenDeviceTree(void **buffer_p, uint32_t *length) +{ + uint32_t totalSize; + void *buf; + + DPRINTF("DT__FlattenDeviceTree(0x%x, 0x%x)\n", buffer_p, length); +#if DEBUG + if (buffer_p) DT__PrintTree(rootNode); +#endif + + totalSize = DTInfo.numNodes * sizeof(DeviceTreeNode) + + DTInfo.numProperties * sizeof(DeviceTreeNodeProperty) + + DTInfo.totalPropertySize; + + DPRINTF("Total size 0x%x\n", totalSize); + if (buffer_p != 0) { + if (totalSize == 0) { + buf = 0; + } else { + if (*buffer_p == 0) { + buf = malloc(totalSize); + } else { + buf = *buffer_p; + } + bzero(buf, totalSize); + + FlattenNodes(rootNode, buf); + } + *buffer_p = buf; + } + if (length) + *length = totalSize; +} + +char * +DT__GetName(Node *node) +{ + Property *prop; + + //DPRINTF("DT__GetName(0x%x)\n", node); + //DPRINTF("Node properties = 0x%x\n", node->properties); + for (prop = node->properties; prop; prop = prop->next) { + //DPRINTF("Prop '%s'\n", prop->name); + if (strcmp(prop->name, "name") == 0) { + return prop->value; + } + } + //DPRINTF("DT__GetName returns 0\n"); + return "(null)"; +} + +Node * +DT__FindNode(const char *path, bool createIfMissing) +{ + Node *node, *child; + DTPropertyNameBuf nameBuf; + char *bp; + int i; + + DPRINTF("DT__FindNode('%s', %d)\n", path, createIfMissing); + + // Start at root + node = rootNode; + DPRINTF("root = 0x%x\n", rootNode); + + while (node) { + // Skip leading slash + while (*path == '/') path++; + + for (i=0, bp = nameBuf; ++i < kDTMaxEntryNameLength && *path && *path != '/'; bp++, path++) *bp = *path; + *bp = '\0'; + + if (nameBuf[0] == '\0') { + // last path entry + break; + } + DPRINTF("Node '%s'\n", nameBuf); + + for (child = node->children; child != 0; child = child->next) { + DPRINTF("Child 0x%x\n", child); + if (strcmp(DT__GetName(child), nameBuf) == 0) { + break; + } + } + if (child == 0 && createIfMissing) { + DPRINTF("Creating node\n"); + char *str = malloc(strlen(nameBuf) + 1); + // XXX this will leak + strcpy(str, nameBuf); + + child = DT__AddChild(node, str); + } + node = child; + } + return node; +} + +#if DEBUG + +void +DT__PrintNode(Node *node, int level) +{ + char spaces[10], *cp = spaces; + Property *prop; + + if (level > 9) level = 9; + while (level--) *cp++ = ' '; + *cp = '\0'; + + printf("%s===Node===\n", spaces); + for (prop = node->properties; prop; prop = prop->next) { + char c = *((char *)prop->value); + if (prop->length < 64 && ( + strcmp(prop->name, "name") == 0 || + (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || c == '_')) { + printf("%s Property '%s' [%d] = '%s'\n", spaces, prop->name, prop->length, prop->value); + } else { + printf("%s Property '%s' [%d] = (data)\n", spaces, prop->name, prop->length); + } + } + printf("%s==========\n", spaces); +} + +static void +_PrintTree(Node *node, int level) +{ + DT__PrintNode(node, level); + level++; + for (node = node->children; node; node = node->next) + _PrintTree(node, level); +} + +void +DT__PrintTree(Node *node) +{ + if (node == 0) node = rootNode; + _PrintTree(node, 0); +} + +void +DT__PrintFlattenedNode(DTEntry entry, int level) +{ + char spaces[10], *cp = spaces; + DTPropertyIterator propIter; + char *name; + void *prop; + int propSize; + + if (level > 9) level = 9; + while (level--) *cp++ = ' '; + *cp = '\0'; + + printf("%s===Entry %p===\n", spaces, entry); + if (kSuccess != DTCreatePropertyIterator(entry, &propIter)) { + printf("Couldn't create property iterator\n"); + return; + } + while( kSuccess == DTIterateProperties( propIter, &name)) { + if( kSuccess != DTGetProperty( entry, name, &prop, &propSize )) + continue; + printf("%s Property %s = %s\n", spaces, name, prop); + } + DTDisposePropertyIterator(propIter); + + printf("%s==========\n", spaces); +} + +static void +_PrintFlattenedTree(DTEntry entry, int level) +{ + DTEntryIterator entryIter; + + PrintFlattenedNode(entry, level); + + if (kSuccess != DTCreateEntryIterator(entry, &entryIter)) { + printf("Couldn't create entry iterator\n"); + return; + } + level++; + while (kSuccess == DTIterateEntries( entryIter, &entry )) { + _PrintFlattenedTree(entry, level); + } + DTDisposeEntryIterator(entryIter); +} + +void +DT__PrintFlattenedTree(DTEntry entry) +{ + _PrintFlattenedTree(entry, 0); +} + + +int +main(int argc, char **argv) +{ + DTEntry dtEntry; + DTPropertyIterator propIter; + DTEntryIterator entryIter; + void *prop; + int propSize; + char *name; + void *flatTree; + uint32_t flatSize; + + Node *node; + + node = AddChild(NULL, "device-tree"); + AddProperty(node, "potato", 4, "foo"); + AddProperty(node, "chemistry", 4, "bar"); + AddProperty(node, "physics", 4, "baz"); + + node = AddChild(node, "dev"); + AddProperty(node, "one", 4, "one"); + AddProperty(node, "two", 4, "two"); + AddProperty(node, "three", 6, "three"); + + node = AddChild(rootNode, "foo"); + AddProperty(node, "aaa", 4, "aab"); + AddProperty(node, "bbb", 4, "bbc"); + AddProperty(node, "cccc", 6, "ccccd"); + + node = FindNode("/this/is/a/test", 1); + AddProperty(node, "dddd", 12, "abcdefghijk"); + + printf("In-memory tree:\n\n"); + + PrintTree(rootNode); + + FlattenDeviceTree(&flatTree, &flatSize); + + printf("Flat tree = %p, size %d\n", flatTree, flatSize); + + dtEntry = (DTEntry)flatTree; + + printf("\n\nPrinting flat tree\n\n"); + + DTInit(dtEntry); + + PrintFlattenedTree((DTEntry)flatTree); +#if 0 + printf("=== Entry %p ===\n", dtEntry); + if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter)) { + printf("Couldn't create property iterator\n"); + return 1; + } + while( kSuccess == DTIterateProperties( propIter, &name)) { + if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize )) + continue; + printf(" Property %s = %s\n", name, prop); + } + DTDisposePropertyIterator(propIter); + printf("========\n"); + + if (kSuccess != DTCreateEntryIterator(dtEntry, &entryIter)) { + printf("Couldn't create entry iterator\n"); + return 1; + } + while (kSuccess == DTIterateEntries( entryIter, &dtEntry )) { + printf("=== Entry %p ===\n", dtEntry); + + if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter)) { + printf("Couldn't create property iterator\n"); + return 1; + } + while( kSuccess == DTIterateProperties( propIter, &name)) { + if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize )) + continue; + printf(" Property %s = %s\n", name, prop); + } + DTDisposePropertyIterator(propIter); + printf("========\n"); + } + DTDisposeEntryIterator(entryIter); +#endif + + return 0; +} + +#endif + Index: branches/slice/trunkM/i386/libsaio/hfs.c =================================================================== --- branches/slice/trunkM/i386/libsaio/hfs.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/hfs.c (revision 1171) @@ -0,0 +1,1064 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 2.0 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * hfs.c - File System Module for HFS and HFS+. + * + * Copyright (c) 1999-2002 Apple Computer, Inc. + * + * DRI: Josh de Cesare + */ + +#include +#include + +#include "hfs.h" + +#define kBlockSize (0x200) + +#define kMDBBaseOffset (2 * kBlockSize) + +#define kBTreeCatalog (0) +#define kBTreeExtents (1) + +#ifdef __i386__ + +static CICell gCurrentIH; +static long long gAllocationOffset; +static long gIsHFSPlus; +static long gCaseSensitive; +static long gBlockSize; +static long gCacheBlockSize; +static char *gBTreeHeaderBuffer; +static BTHeaderRec *gBTHeaders[2]; +static char *gHFSMdbVib; +static HFSMasterDirectoryBlock *gHFSMDB; +static char *gHFSPlusHeader; +static HFSPlusVolumeHeader *gHFSPlus; +static char *gLinkTemp; +static long long gVolID; +static char *gTempStr; + +#else /* !__i386__ */ + +static CICell gCurrentIH; +static long long gAllocationOffset; +static long gIsHFSPlus; +static long gBlockSize; +static long gCaseSensitive; +static long gCacheBlockSize; +static char gBTreeHeaderBuffer[512]; +static BTHeaderRec *gBTHeaders[2]; +static char gHFSMdbVib[kBlockSize]; +static HFSMasterDirectoryBlock *gHFSMDB =(HFSMasterDirectoryBlock*)gHFSMdbVib; +static char gHFSPlusHeader[kBlockSize]; +static HFSPlusVolumeHeader *gHFSPlus =(HFSPlusVolumeHeader*)gHFSPlusHeader; +static char gLinkTemp[64]; +static long long gVolID; + +#endif /* !__i386__ */ + +static long ReadFile(void *file, uint64_t *length, void *base, uint64_t offset); +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 long *dirIndex); + +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 long *dirIndex); +static long ReadExtentsEntry(long fileID, long startBlock, void *entry); + +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); + +static long ReadExtent(char *extent, uint64_t extentSize, long extentFile, + uint64_t offset, uint64_t size, void *buffer, long cache); + +static long GetExtentStart(void *extents, long index); +static long GetExtentSize(void *extents, long index); + +static long CompareHFSCatalogKeys(void *key, void *testKey); +static long CompareHFSPlusCatalogKeys(void *key, void *testKey); +static long CompareHFSExtentsKeys(void *key, void *testKey); +static long CompareHFSPlusExtentsKeys(void *key, void *testKey); + +extern long FastRelString(u_int8_t *str1, u_int8_t *str2); +extern long BinaryUnicodeCompare(u_int16_t *uniStr1, u_int32_t len1, + u_int16_t *uniStr2, u_int32_t len2); + + +static void SwapFinderInfo(FndrFileInfo *dst, FndrFileInfo *src) +{ + dst->fdType = SWAP_BE32(src->fdType); + dst->fdCreator = SWAP_BE32(src->fdCreator); + dst->fdFlags = SWAP_BE16(src->fdFlags); + // Don't bother with location +} + +void HFSFree(CICell ih) +{ + if(gCurrentIH == ih) + gCurrentIH = 0; + free(ih); +} + +bool HFSProbe (const void *buf) +{ + const HFSMasterDirectoryBlock *mdb; + const HFSPlusVolumeHeader *header; + mdb=(const HFSMasterDirectoryBlock *)(((const char*)buf)+kMDBBaseOffset); + header=(const HFSPlusVolumeHeader *)(((const char*)buf)+kMDBBaseOffset); + + if ( SWAP_BE16(mdb->drSigWord) == kHFSSigWord ) + return true; + if (SWAP_BE16(header->signature) != kHFSPlusSigWord && + SWAP_BE16(header->signature) != kHFSXSigWord) + return false; + return true; +} + +long HFSInitPartition(CICell ih) +{ + long extentSize, extentFile, nodeSize; + void *extent; + + if (ih == gCurrentIH) { +#ifdef __i386__ + CacheInit(ih, gCacheBlockSize); +#endif + return 0; + } + +#ifdef __i386__ + if (!gTempStr) gTempStr = (char *)malloc(4096); + if (!gLinkTemp) gLinkTemp = (char *)malloc(64); + if (!gBTreeHeaderBuffer) gBTreeHeaderBuffer = (char *)malloc(512); + if (!gHFSMdbVib) { + gHFSMdbVib = (char *)malloc(kBlockSize); + gHFSMDB = (HFSMasterDirectoryBlock *)gHFSMdbVib; + } + if (!gHFSPlusHeader) { + gHFSPlusHeader = (char *)malloc(kBlockSize); + gHFSPlus = (HFSPlusVolumeHeader *)gHFSPlusHeader; + } + if (!gTempStr || !gLinkTemp || !gBTreeHeaderBuffer || + !gHFSMdbVib || !gHFSPlusHeader) return -1; +#endif /* __i386__ */ + + gAllocationOffset = 0; + gIsHFSPlus = 0; + gCaseSensitive = 0; + gBTHeaders[0] = 0; + gBTHeaders[1] = 0; + + // Look for the HFS MDB + Seek(ih, kMDBBaseOffset); + Read(ih, (long)gHFSMdbVib, kBlockSize); + + if ( SWAP_BE16(gHFSMDB->drSigWord) == kHFSSigWord ) { + gAllocationOffset = SWAP_BE16(gHFSMDB->drAlBlSt) * kBlockSize; + + // See if it is HFSPlus + if (SWAP_BE16(gHFSMDB->drEmbedSigWord) != kHFSPlusSigWord) { + // Normal HFS; + gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSMDB->drAlBlkSiz); + CacheInit(ih, gCacheBlockSize); + gCurrentIH = ih; + + // grab the 64 bit volume ID + bcopy(&gHFSMDB->drFndrInfo[6], &gVolID, 8); + + // Get the Catalog BTree node size. + extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec; + extentSize = SWAP_BE32(gHFSMDB->drCTFlSize); + extentFile = kHFSCatalogFileID; + ReadExtent(extent, extentSize, extentFile, 0, 256, + gBTreeHeaderBuffer + kBTreeCatalog * 256, 0); + + nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 + + sizeof(BTNodeDescriptor)))->nodeSize); + + // If the BTree node size is larger than the block size, reset the cache. + if (nodeSize > gBlockSize) { + gCacheBlockSize = nodeSize; + CacheInit(ih, gCacheBlockSize); + } + + return 0; + } + + // Calculate the offset to the embeded HFSPlus volume. + gAllocationOffset += (long long)SWAP_BE16(gHFSMDB->drEmbedExtent.startBlock) * + SWAP_BE32(gHFSMDB->drAlBlkSiz); + } + + // Look for the HFSPlus Header + Seek(ih, gAllocationOffset + kMDBBaseOffset); + Read(ih, (long)gHFSPlusHeader, kBlockSize); + + // Not a HFS+ or HFSX volume. + if (SWAP_BE16(gHFSPlus->signature) != kHFSPlusSigWord && + SWAP_BE16(gHFSPlus->signature) != kHFSXSigWord) { + verbose("HFS signature was not present.\n"); + gCurrentIH = 0; + return -1; + } + + gIsHFSPlus = 1; + gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSPlus->blockSize); + CacheInit(ih, gCacheBlockSize); + gCurrentIH = ih; + + ih->modTime = SWAP_BE32(gHFSPlus->modifyDate) - 2082844800; + + // grab the 64 bit volume ID + bcopy(&gHFSPlus->finderInfo[24], &gVolID, 8); + + // Get the Catalog BTree node size. + extent = &gHFSPlus->catalogFile.extents; + extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize); + extentFile = kHFSCatalogFileID; + + ReadExtent(extent, extentSize, extentFile, 0, 256, + gBTreeHeaderBuffer + kBTreeCatalog * 256, 0); + + nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 + + sizeof(BTNodeDescriptor)))->nodeSize); + + // If the BTree node size is larger than the block size, reset the cache. + if (nodeSize > gBlockSize) { + gCacheBlockSize = nodeSize; + CacheInit(ih, gCacheBlockSize); + } + + return 0; +} + +long HFSLoadFile(CICell ih, char * filePath) +{ + return HFSReadFile(ih, filePath, (void *)gFSLoadAddress, 0, 0); +} + +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] == '/') { + if (filePath[1] == '/') { + if (gIsHFSPlus) dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]); + else dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]); + if (dirID == 0) { + return -1; + } + filePath++; + } + filePath++; + } + + result = ResolvePathToCatalogEntry(filePath, &flags, entry, dirID, 0); + if ((result == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) { + return -1; + } + +#if UNUSED + // Not yet for Intel. System.config/Default.table will fail this check. + // Check file owner and permissions. + if (flags & (kOwnerNotRoot | kPermGroupWrite | kPermOtherWrite)) return -1; +#endif + + result = ReadFile(entry, &length, base, offset); + if (result == -1) { + return -1; + } + + 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 long * dirIndex, char ** name, + long * flags, long * time, + FinderInfo * finderInfo, long * infoValid) +{ + char entry[512]; + long dirID, dirFlags; + + if (HFSInitPartition(ih) == -1) return -1; + + if (*dirIndex == -1) return -1; + + dirID = kHFSRootFolderID; + // Skip a lead '\'. Start in the system folder if there are two. + if (dirPath[0] == '/') { + if (dirPath[1] == '/') { + if (gIsHFSPlus) dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]); + else dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]); + if (dirID == 0) return -1; + dirPath++; + } + dirPath++; + } + + if (*dirIndex == 0) { + ResolvePathToCatalogEntry(dirPath, &dirFlags, entry, dirID, dirIndex); + if (*dirIndex == 0) *dirIndex = -1; + if ((dirFlags & kFileTypeMask) != kFileTypeUnknown) return -1; + } + + GetCatalogEntry(dirIndex, name, flags, time, finderInfo, infoValid); + if (*dirIndex == 0) *dirIndex = -1; + if ((*flags & kFileTypeMask) == kFileTypeUnknown) return -1; + + return 0; +} + +void +HFSGetDescription(CICell ih, char *str, long strMaxLen) +{ + + UInt16 nodeSize; + UInt32 firstLeafNode; + long long dirIndex; + char *name; + long flags, time; + + if (HFSInitPartition(ih) == -1) { return; } + + /* Fill some crucial data structures by side effect. */ + dirIndex = 0; + HFSGetDirEntry(ih, "/", &dirIndex, &name, &flags, &time, 0, 0); + + /* Now we can loook up the volume name node. */ + nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize); + firstLeafNode = SWAP_BE32(gBTHeaders[kBTreeCatalog]->firstLeafNode); + + dirIndex = (long long) firstLeafNode * nodeSize; + + GetCatalogEntry(&dirIndex, &name, &flags, &time, 0, 0); + + strncpy(str, name, strMaxLen); + str[strMaxLen] = '\0'; +} + + +long +HFSGetFileBlock(CICell ih, char *filePath, unsigned long long *firstBlock) +{ + char entry[512]; + long dirID, result, flags; + void *extents; + HFSCatalogFile *hfsFile = (void *)entry; + HFSPlusCatalogFile *hfsPlusFile = (void *)entry; + + if (HFSInitPartition(ih) == -1) return -1; + + dirID = kHFSRootFolderID; + // Skip a lead '\'. Start in the system folder if there are two. + if (filePath[0] == '/') { + if (filePath[1] == '/') { + if (gIsHFSPlus) dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]); + else dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]); + if (dirID == 0) { + return -1; + } + filePath++; + } + filePath++; + } + + result = ResolvePathToCatalogEntry(filePath, &flags, entry, dirID, 0); + if ((result == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) { + printf("HFS: Resolve path %s failed\n", filePath); + return -1; + } + + if (gIsHFSPlus) { + extents = &hfsPlusFile->dataFork.extents; + } else { + extents = &hfsFile->dataExtents; + } + +#if DEBUG + printf("extent start 0x%x\n", (unsigned long)GetExtentStart(extents, 0)); + printf("block size 0x%x\n", (unsigned long)gBlockSize); + printf("Allocation offset 0x%x\n", (unsigned long)gAllocationOffset); +#endif + *firstBlock = ((unsigned long long)GetExtentStart(extents, 0) * (unsigned long long) gBlockSize + gAllocationOffset) / 512ULL; + return 0; +} + +long HFSGetUUID(CICell ih, char *uuidStr) +{ + if (HFSInitPartition(ih) == -1) return -1; + if (gVolID == 0LL) return -1; + + return CreateUUIDString((uint8_t*)(&gVolID), sizeof(gVolID), uuidStr); +} + +// Private Functions + +static long ReadFile(void * file, uint64_t * length, void * base, uint64_t offset) +{ + void *extents; + long fileID; + uint64_t fileLength; + HFSCatalogFile *hfsFile = file; + HFSPlusCatalogFile *hfsPlusFile = file; + + if (gIsHFSPlus) { + fileID = SWAP_BE32(hfsPlusFile->fileID); + fileLength = (uint64_t)SWAP_BE64(hfsPlusFile->dataFork.logicalSize); + extents = &hfsPlusFile->dataFork.extents; + } else { + fileID = SWAP_BE32(hfsFile->fileID); + fileLength = SWAP_BE32(hfsFile->dataLogicalSize); + extents = &hfsFile->dataExtents; + } + + if (offset > fileLength) { + printf("Offset is too large.\n"); + return -1; + } + + if ((*length == 0) || ((offset + *length) > fileLength)) { + *length = fileLength - offset; + } + +/* if (*length > kLoadSize) { + printf("File is too large.\n"); + return -1; + }*/ + + *length = ReadExtent((char *)extents, fileLength, fileID, + offset, *length, (char *)base, 0); + + return 0; +} + +static long GetCatalogEntryInfo(void * entry, long * flags, long * time, + FinderInfo * finderInfo, long * infoValid) +{ + long tmpTime = 0; + long valid = 0; + + // Get information about the file. + + switch ( SWAP_BE16(*(short *)entry) ) + { + case kHFSFolderRecord : + *flags = kFileTypeDirectory; + tmpTime = SWAP_BE32(((HFSCatalogFolder *)entry)->modifyDate); + break; + + case kHFSPlusFolderRecord : + *flags = kFileTypeDirectory | + (SWAP_BE16(((HFSPlusCatalogFolder *)entry)->bsdInfo.fileMode) & kPermMask); + if (SWAP_BE32(((HFSPlusCatalogFolder *)entry)->bsdInfo.ownerID) != 0) + *flags |= kOwnerNotRoot; + tmpTime = SWAP_BE32(((HFSPlusCatalogFolder *)entry)->contentModDate); + break; + + case kHFSFileRecord : + *flags = kFileTypeFlat; + tmpTime = SWAP_BE32(((HFSCatalogFile *)entry)->modifyDate); + if (finderInfo) { + SwapFinderInfo((FndrFileInfo *)finderInfo, &((HFSCatalogFile *)entry)->userInfo); + valid = 1; + } + break; + + case kHFSPlusFileRecord : + *flags = kFileTypeFlat | + (SWAP_BE16(((HFSPlusCatalogFile *)entry)->bsdInfo.fileMode) & kPermMask); + if (SWAP_BE32(((HFSPlusCatalogFile *)entry)->bsdInfo.ownerID) != 0) + *flags |= kOwnerNotRoot; + tmpTime = SWAP_BE32(((HFSPlusCatalogFile *)entry)->contentModDate); + if (finderInfo) { + SwapFinderInfo((FndrFileInfo *)finderInfo, &((HFSPlusCatalogFile *)entry)->userInfo); + valid = 1; + } + break; + + case kHFSFileThreadRecord : + case kHFSPlusFileThreadRecord : + case kHFSFolderThreadRecord : + case kHFSPlusFolderThreadRecord : + *flags = kFileTypeUnknown; + tmpTime = 0; + break; + } + + if (time != 0) { + // Convert base time from 1904 to 1970. + *time = tmpTime - 2082844800; + } + if (infoValid) *infoValid = valid; + + return 0; +} + +static long ResolvePathToCatalogEntry(char * filePath, long * flags, + void * entry, long dirID, long long * dirIndex) +{ + char *restPath; + long result, cnt, subFolderID = 0; + long long tmpDirIndex; + HFSPlusCatalogFile *hfsPlusFile; + + // Copy the file name to gTempStr + cnt = 0; + while ((filePath[cnt] != '/') && (filePath[cnt] != '\0')) cnt++; + strlcpy(gTempStr, filePath, cnt+1); + + // Move restPath to the right place. + if (filePath[cnt] != '\0') cnt++; + restPath = filePath + cnt; + + // gTempStr is a name in the current Dir. + // restPath is the rest of the path if any. + + result = ReadCatalogEntry(gTempStr, dirID, entry, dirIndex); + if (result == -1) { + return -1; + } + + GetCatalogEntryInfo(entry, flags, 0, 0, 0); + + if ((*flags & kFileTypeMask) == kFileTypeDirectory) { + if (gIsHFSPlus) + subFolderID = SWAP_BE32(((HFSPlusCatalogFolder *)entry)->folderID); + else + subFolderID = SWAP_BE32(((HFSCatalogFolder *)entry)->folderID); + } + + if ((*flags & kFileTypeMask) == kFileTypeDirectory) + result = ResolvePathToCatalogEntry(restPath, flags, entry, + subFolderID, dirIndex); + + if (gIsHFSPlus && ((*flags & kFileTypeMask) == kFileTypeFlat)) { + hfsPlusFile = (HFSPlusCatalogFile *)entry; + if ((SWAP_BE32(hfsPlusFile->userInfo.fdType) == kHardLinkFileType) && + (SWAP_BE32(hfsPlusFile->userInfo.fdCreator) == kHFSPlusCreator)) { + sprintf(gLinkTemp, "%s/%s%ld", HFSPLUSMETADATAFOLDER, + HFS_INODE_PREFIX, SWAP_BE32(hfsPlusFile->bsdInfo.special.iNodeNum)); + result = ResolvePathToCatalogEntry(gLinkTemp, flags, entry, + kHFSRootFolderID, &tmpDirIndex); + } + } + + return result; +} + +static long GetCatalogEntry(long long * dirIndex, char ** name, + long * flags, long * time, + FinderInfo * finderInfo, long * infoValid) +{ + long extentSize, nodeSize, curNode, index; + void *extent; + char *nodeBuf, *testKey, *entry; + BTNodeDescriptor *node; + + if (gIsHFSPlus) { + extent = &gHFSPlus->catalogFile.extents; + extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize); + } else { + extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec; + extentSize = SWAP_BE32(gHFSMDB->drCTFlSize); + } + + nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize); + nodeBuf = (char *)malloc(nodeSize); + node = (BTNodeDescriptor *)nodeBuf; + + 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); + GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &entry); + + GetCatalogEntryInfo(entry, flags, time, finderInfo, infoValid); + + // Get the file name. + if (gIsHFSPlus) { + utf_encodestr(((HFSPlusCatalogKey *)testKey)->nodeName.unicode, + SWAP_BE16(((HFSPlusCatalogKey *)testKey)->nodeName.length), + (u_int8_t *)gTempStr, 256, OSBigEndian); + } else { + strncpy(gTempStr, + (const char *)&((HFSCatalogKey *)testKey)->nodeName[1], + ((HFSCatalogKey *)testKey)->nodeName[0]); + gTempStr[((HFSCatalogKey *)testKey)->nodeName[0]] = '\0'; + } + *name = gTempStr; + + // Update dirIndex. + index++; + if (index == SWAP_BE16(node->numRecords)) { + index = 0; + curNode = SWAP_BE32(node->fLink); + } + *dirIndex = (long long) curNode * nodeSize + index; + + free(nodeBuf); + + return 0; +} + +static long ReadCatalogEntry(char * fileName, long dirID, + void * entry, long long * dirIndex) +{ + long length; + char key[sizeof(HFSPlusCatalogKey)]; + HFSCatalogKey *hfsKey = (HFSCatalogKey *)key; + HFSPlusCatalogKey *hfsPlusKey = (HFSPlusCatalogKey *)key; + + // Make the catalog key. + if ( gIsHFSPlus ) + { + hfsPlusKey->parentID = SWAP_BE32(dirID); + length = strlen(fileName); + if (length > 255) length = 255; + utf_decodestr((u_int8_t *)fileName, hfsPlusKey->nodeName.unicode, + &(hfsPlusKey->nodeName.length), 512, OSBigEndian); + } else { + hfsKey->parentID = SWAP_BE32(dirID); + length = strlen(fileName); + if (length > 31) length = 31; + hfsKey->nodeName[0] = length; + strncpy((char *)(hfsKey->nodeName + 1), fileName, length); + } + + return ReadBTreeEntry(kBTreeCatalog, &key, entry, dirIndex); +} + +static long ReadExtentsEntry(long fileID, long startBlock, void * entry) +{ + char key[sizeof(HFSPlusExtentKey)]; + HFSExtentKey *hfsKey = (HFSExtentKey *)key; + HFSPlusExtentKey *hfsPlusKey = (HFSPlusExtentKey *)key; + + // Make the extents key. + if (gIsHFSPlus) { + hfsPlusKey->forkType = 0; + hfsPlusKey->fileID = SWAP_BE32(fileID); + hfsPlusKey->startBlock = SWAP_BE32(startBlock); + } else { + hfsKey->forkType = 0; + hfsKey->fileID = SWAP_BE32(fileID); + hfsKey->startBlock = SWAP_BE16(startBlock); + } + + return ReadBTreeEntry(kBTreeExtents, &key, entry, 0); +} + +static long ReadBTreeEntry(long btree, void * key, char * entry, long long * dirIndex) +{ + long extentSize; + void *extent; + short extentFile; + char *nodeBuf; + BTNodeDescriptor *node; + long nodeSize, result = 0, entrySize = 0; + long curNode, index = 0, lowerBound, upperBound; + char *testKey, *recordData; + + // Figure out which tree is being looked at. + if (btree == kBTreeCatalog) { + if (gIsHFSPlus) { + extent = &gHFSPlus->catalogFile.extents; + extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize); + } else { + extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec; + extentSize = SWAP_BE32(gHFSMDB->drCTFlSize); + } + extentFile = kHFSCatalogFileID; + } else { + if (gIsHFSPlus) { + extent = &gHFSPlus->extentsFile.extents; + extentSize = SWAP_BE64(gHFSPlus->extentsFile.logicalSize); + } else { + extent = (HFSExtentDescriptor *)&gHFSMDB->drXTExtRec; + extentSize = SWAP_BE32(gHFSMDB->drXTFlSize); + } + extentFile = kHFSExtentsFileID; + } + + // Read the BTree Header if needed. + if (gBTHeaders[btree] == 0) { + ReadExtent(extent, extentSize, extentFile, 0, 256, + gBTreeHeaderBuffer + btree * 256, 0); + gBTHeaders[btree] = (BTHeaderRec *)(gBTreeHeaderBuffer + btree * 256 + + sizeof(BTNodeDescriptor)); + if ((gIsHFSPlus && btree == kBTreeCatalog) && + (gBTHeaders[btree]->keyCompareType == kHFSBinaryCompare)) { + gCaseSensitive = 1; + } + } + + curNode = SWAP_BE32(gBTHeaders[btree]->rootNode); + nodeSize = SWAP_BE16(gBTHeaders[btree]->nodeSize); + nodeBuf = (char *)malloc(nodeSize); + node = (BTNodeDescriptor *)nodeBuf; + + while (1) { + // Read the current node. + ReadExtent(extent, extentSize, extentFile, + (long long) curNode * nodeSize, nodeSize, nodeBuf, 1); + + // Find the matching key. + lowerBound = 0; + upperBound = SWAP_BE16(node->numRecords) - 1; + while (lowerBound <= upperBound) { + index = (lowerBound + upperBound) / 2; + + GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData); + + if (gIsHFSPlus) { + if (btree == kBTreeCatalog) { + result = CompareHFSPlusCatalogKeys(key, testKey); + } else { + result = CompareHFSPlusExtentsKeys(key, testKey); + } + } else { + if (btree == kBTreeCatalog) { + result = CompareHFSCatalogKeys(key, testKey); + } else { + result = CompareHFSExtentsKeys(key, testKey); + } + } + + if (result < 0) upperBound = index - 1; // search < trial + else if (result > 0) lowerBound = index + 1; // search > trial + else break; // search = trial + } + + if (result < 0) { + index = upperBound; + GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData); + } + + // Found the closest key... Recurse on it if this is an index node. + if (node->kind == kBTIndexNode) { + curNode = SWAP_BE32( *((long *)recordData) ); + } else break; + } + + // Return error if the file was not found. + if (result != 0) { free(nodeBuf); return -1; } + + if (btree == kBTreeCatalog) { + switch (SWAP_BE16(*(short *)recordData)) { + case kHFSFolderRecord : entrySize = 70; break; + case kHFSFileRecord : entrySize = 102; break; + case kHFSFolderThreadRecord : entrySize = 46; break; + case kHFSFileThreadRecord : entrySize = 46; break; + case kHFSPlusFolderRecord : entrySize = 88; break; + case kHFSPlusFileRecord : entrySize = 248; break; + case kHFSPlusFolderThreadRecord : entrySize = 264; break; + case kHFSPlusFileThreadRecord : entrySize = 264; break; + } + } else { + if (gIsHFSPlus) entrySize = sizeof(HFSPlusExtentRecord); + else entrySize = sizeof(HFSExtentRecord); + } + + bcopy(recordData, entry, entrySize); + + // Update dirIndex. + if (dirIndex != 0) { + index++; + if (index == SWAP_BE16(node->numRecords)) { + index = 0; + curNode = SWAP_BE32(node->fLink); + } + *dirIndex = (long long) curNode * nodeSize + index; + } + + free(nodeBuf); + + return 0; +} + +static void GetBTreeRecord(long index, char * nodeBuffer, long nodeSize, + char ** key, char ** data) +{ + long keySize; + long recordOffset; + + recordOffset = SWAP_BE16(*((short *)(nodeBuffer + (nodeSize - 2 * index - 2)))); + *key = nodeBuffer + recordOffset; + if (gIsHFSPlus) { + keySize = SWAP_BE16(*(short *)*key); + *data = *key + 2 + keySize; + } else { + keySize = **key; + *data = *key + 2 + keySize - (keySize & 1); + } +} + +static long ReadExtent(char * extent, uint64_t extentSize, + long extentFile, uint64_t offset, uint64_t size, + void * buffer, long cache) +{ + uint64_t lastOffset; + long long blockNumber, countedBlocks = 0; + long long nextExtent = 0, sizeRead = 0, readSize; + long long nextExtentBlock, currentExtentBlock = 0; + long long readOffset; + long long extentDensity, sizeofExtent, currentExtentSize; + char *currentExtent, *extentBuffer = 0, *bufferPos = buffer; + + if (offset >= extentSize) return 0; + + if (gIsHFSPlus) { + extentDensity = kHFSPlusExtentDensity; + sizeofExtent = sizeof(HFSPlusExtentDescriptor); + } else { + extentDensity = kHFSExtentDensity; + sizeofExtent = sizeof(HFSExtentDescriptor); + } + + lastOffset = offset + size; + while (offset < lastOffset) { + blockNumber = offset / gBlockSize; + + // Find the extent for the offset. + for (; ; nextExtent++) { + if (nextExtent < extentDensity) { + if ((countedBlocks+GetExtentSize(extent, nextExtent)-1)= blockNumber) { + currentExtent = extentBuffer + sizeofExtent * (nextExtent % extentDensity); + break; + } + + countedBlocks += currentExtentSize; + } + + readOffset = ((blockNumber - countedBlocks) * gBlockSize) + + (offset % gBlockSize); + + // MacWen: fix overflow in multiplication by forcing 64bit multiplication + readSize = (long long)GetExtentSize(currentExtent, 0) * gBlockSize - readOffset; + if (readSize > (size - sizeRead)) readSize = size - sizeRead; + + readOffset += (long long)GetExtentStart(currentExtent, 0) * gBlockSize; + + CacheRead(gCurrentIH, bufferPos, gAllocationOffset + readOffset, + readSize, cache); + + sizeRead += readSize; + offset += readSize; + bufferPos += readSize; + } + + if (extentBuffer) free(extentBuffer); + + return sizeRead; +} + +static long GetExtentStart(void * extents, long index) +{ + long start; + HFSExtentDescriptor *hfsExtents = extents; + HFSPlusExtentDescriptor *hfsPlusExtents = extents; + + if (gIsHFSPlus) start = SWAP_BE32(hfsPlusExtents[index].startBlock); + else start = SWAP_BE16(hfsExtents[index].startBlock); + + return start; +} + +static long GetExtentSize(void * extents, long index) +{ + long size; + HFSExtentDescriptor *hfsExtents = extents; + HFSPlusExtentDescriptor *hfsPlusExtents = extents; + + if (gIsHFSPlus) size = SWAP_BE32(hfsPlusExtents[index].blockCount); + else size = SWAP_BE16(hfsExtents[index].blockCount); + + return size; +} + +static long CompareHFSCatalogKeys(void * key, void * testKey) +{ + HFSCatalogKey *searchKey, *trialKey; + long result, searchParentID, trialParentID; + + searchKey = key; + trialKey = testKey; + + searchParentID = SWAP_BE32(searchKey->parentID); + trialParentID = SWAP_BE32(trialKey->parentID); + + // parent dirID is unsigned + if (searchParentID > trialParentID) result = 1; + else if (searchParentID < trialParentID) result = -1; + else { + // parent dirID's are equal, compare names + result = FastRelString(searchKey->nodeName, trialKey->nodeName); + } + + return result; +} + +static long CompareHFSPlusCatalogKeys(void * key, void * testKey) +{ + HFSPlusCatalogKey *searchKey, *trialKey; + long result, searchParentID, trialParentID; + + searchKey = key; + trialKey = testKey; + + searchParentID = SWAP_BE32(searchKey->parentID); + trialParentID = SWAP_BE32(trialKey->parentID); + + // parent dirID is unsigned + if (searchParentID > trialParentID) result = 1; + else if (searchParentID < trialParentID) result = -1; + else { + // parent dirID's are equal, compare names + if ((searchKey->nodeName.length == 0) || (trialKey->nodeName.length == 0)) + result = searchKey->nodeName.length - trialKey->nodeName.length; + else + if (gCaseSensitive) { + result = BinaryUnicodeCompare(&searchKey->nodeName.unicode[0], + SWAP_BE16(searchKey->nodeName.length), + &trialKey->nodeName.unicode[0], + SWAP_BE16(trialKey->nodeName.length)); + } else { + result = FastUnicodeCompare(&searchKey->nodeName.unicode[0], + SWAP_BE16(searchKey->nodeName.length), + &trialKey->nodeName.unicode[0], + SWAP_BE16(trialKey->nodeName.length), OSBigEndian); + } + } + + return result; +} + +static long CompareHFSExtentsKeys(void * key, void * testKey) +{ + HFSExtentKey *searchKey, *trialKey; + long result; + + searchKey = key; + trialKey = testKey; + + // assume searchKey < trialKey + result = -1; + + if (searchKey->fileID == trialKey->fileID) { + // FileNum's are equal; compare fork types + if (searchKey->forkType == trialKey->forkType) { + // Fork types are equal; compare allocation block number + if (searchKey->startBlock == trialKey->startBlock) { + // Everything is equal + result = 0; + } else { + // Allocation block numbers differ; determine sign + if (SWAP_BE16(searchKey->startBlock) > SWAP_BE16(trialKey->startBlock)) + result = 1; + } + } else { + // Fork types differ; determine sign + if (searchKey->forkType > trialKey->forkType) result = 1; + } + } else { + // FileNums differ; determine sign + if (SWAP_BE32(searchKey->fileID) > SWAP_BE32(trialKey->fileID)) + result = 1; + } + + return result; +} + +static long CompareHFSPlusExtentsKeys(void * key, void * testKey) +{ + HFSPlusExtentKey *searchKey, *trialKey; + long result; + + searchKey = key; + trialKey = testKey; + + // assume searchKey < trialKey + result = -1; + + if (searchKey->fileID == trialKey->fileID) { + // FileNum's are equal; compare fork types + if (searchKey->forkType == trialKey->forkType) { + // Fork types are equal; compare allocation block number + if (searchKey->startBlock == trialKey->startBlock) { + // Everything is equal + result = 0; + } else { + // Allocation block numbers differ; determine sign + if (SWAP_BE32(searchKey->startBlock) > SWAP_BE32(trialKey->startBlock)) + result = 1; + } + } else { + // Fork types differ; determine sign + if (searchKey->forkType > trialKey->forkType) result = 1; + } + } else { + // FileNums differ; determine sign + if (SWAP_BE32(searchKey->fileID) > SWAP_BE32(trialKey->fileID)) + result = 1; + } + + return result; +} + Index: branches/slice/trunkM/i386/libsaio/ext2fs.h =================================================================== --- branches/slice/trunkM/i386/libsaio/ext2fs.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/ext2fs.h (revision 1171) @@ -0,0 +1,11 @@ +/* + * ext2fs.h + * + * + * Created by mackerintel on 1/26/09. + * Copyright 2009 __MyCompanyName__. All rights reserved. + * + */ + +extern bool EX2Probe (const void *buf); +extern void EX2GetDescription(CICell ih, char *str, long strMaxLen); Index: branches/slice/trunkM/i386/libsaio/vbe.h =================================================================== --- branches/slice/trunkM/i386/libsaio/vbe.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/vbe.h (revision 1171) @@ -0,0 +1,286 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +// Copyright 1997 by Apple Computer, Inc., all rights reserved. +/* Copyright 1996-1997 NeXT Software, Inc. + * + * vesa.h - mode info obtained via int10 + * + * Revision History + * ---------------- + * 30 Jul 1996 Doug Mitchell at NeXT + * Created. + */ + +#ifndef __LIBSAIO_VBE_H +#define __LIBSAIO_VBE_H + +#define MIN_VESA_VERSION 0x200 + +#define SEG(address) \ + ((unsigned short)(((unsigned long)address & 0xffff0000) >> 4)) + +#define OFF(address) \ + ((unsigned short)((unsigned long)address & 0x0000ffff)) + +#define VBEMakeUInt32(x) \ + (((unsigned long)x##_high << 24) | \ + ((unsigned long)x##_2 << 16) | \ + ((unsigned long)x##_1 << 8) | \ + (unsigned long)x##_low) + +#define VBEDecodeFP(t, fp) \ + ((t)(((fp ## _low) | ((fp ## _1 ) << 8)) + \ + (((fp ## _2) << 4) | ((fp ## _high ) << 12)))) + +/* + * Functions + */ +enum { + funcGetControllerInfo = 0x4F00, + funcGetModeInfo = 0x4F01, + funcSetMode = 0x4F02, + funcGetCurrentMode = 0x4F03, + funcSaveRestoreState = 0x4F04, + funcWindowControl = 0x4F05, + funcGetSetScanLineLength = 0x4F06, + funcGetSetDisplayStart = 0x4F07, + funcGetSetPaletteFormat = 0x4F08, + funcGetSetPaletteData = 0x4F09, + funcGetProtModeInterdace = 0x4F0A, + funcGetSetPixelClock = 0x4F0B +}; + +enum { + subfuncSet = 0x00, + subfuncGet = 0x01, + subfuncSetSecondary = 0x02, + subfuncGetSecondary = 0x03 +}; + +/* + * errors. + */ +enum { + errSuccess = 0, + errFuncFailed = 1, + errFuncNotSupported = 2, + errFuncInvalid = 3 +}; + +/* + * Per-controller info, returned in function 4f00. + */ +typedef struct { + unsigned char VESASignature[4]; + unsigned short VESAVersion; + /* + * Avoid packing problem... + */ + unsigned char OEMStringPtr_low; + unsigned char OEMStringPtr_1; + unsigned char OEMStringPtr_2; + unsigned char OEMStringPtr_high; + unsigned char Capabilities_low; + unsigned char Capabilities_1; + unsigned char Capabilities_2; + unsigned char Capabilities_high; + unsigned char VideoModePtr_low; + unsigned char VideoModePtr_1; + unsigned char VideoModePtr_2; + unsigned char VideoModePtr_high; + unsigned short TotalMemory; + unsigned char Reserved[236]; + unsigned char OEMData[256]; +} VBEInfoBlock; + +/* + * Capabilites + */ +enum { + capDACWidthIsSwitchableBit = (1 << 0), /* 1 = yes; 0 = no */ + capControllerIsNotVGACompatableBit = (1 << 1), /* 1 = no; 0 = yes */ + capOldRAMDAC = (1 << 2) /* 1 = yes; 0 = no */ +}; + +/* + * Per-mode info, returned in function 4f02. + */ +typedef struct { + unsigned short ModeAttributes; + unsigned char WinAAttributes; + unsigned char WinBAttributes; + unsigned short WinGranularity; + unsigned short WinSize; + unsigned short WinASegment; + unsigned short WinABegment; + void * WinFuncPtr; + unsigned short BytesPerScanline; + unsigned short XResolution; + unsigned short YResolution; + unsigned char XCharSize; + unsigned char YCharSize; + unsigned char NumberOfPlanes; + unsigned char BitsPerPixel; + unsigned char NumberOfBanks; + unsigned char MemoryModel; + unsigned char BankSize; + unsigned char NumberOfImagePages; + unsigned char Reserved; + unsigned char RedMaskSize; + unsigned char RedFieldPosition; + unsigned char GreenMaskSize; + unsigned char GreenFieldPosition; + unsigned char BlueMaskSize; + unsigned char BlueFieldPosition; + unsigned char RsvdMaskSize; + unsigned char RsvdFieldPosition; + unsigned char DirectColorModeInfo; + unsigned char PhysBasePtr_low; + unsigned char PhysBasePtr_1; + unsigned char PhysBasePtr_2; + unsigned char PhysBasePtr_high; + void * OffScreenMemOffset; + unsigned short OffScreenMemSize; + unsigned char Reserved1[206]; +} VBEModeInfoBlock; + +/* + * ModeAttributes bits + */ +enum { + maModeIsSupportedBit = (1 << 0), /* mode is supported */ + maExtendedInfoAvailableBit = (1 << 1), /* extended info available */ + maOutputFuncSupportedBit = (1 << 2), /* output functions supported */ + maColorModeBit = (1 << 3), /* 1 = color; 0 = mono */ + maGraphicsModeBit = (1 << 4), /* 1 = graphics; 0 = text */ + maModeIsNotVGACompatableBit = (1 << 5), /* 1 = not compat; 0 = compat */ + maVGAMemoryModeNotAvailBit = (1 << 6), /* 1 = not avail; 0 = avail */ + maLinearFrameBufferAvailBit = (1 << 7) /* 1 = avail; 0 = not avail */ +}; + +/* + * Modes + */ +enum { + mode640x400x256 = 0x100, + mode640x480x256 = 0x101, + mode800x600x16 = 0x102, + mode800x600x256 = 0x103, + mode1024x768x16 = 0x104, + mode1024x768x256 = 0x105, + mode1280x1024x16 = 0x106, + mode1280x1024x256 = 0x107, + mode80Cx60R = 0x108, + mode132Cx25R = 0x109, + mode132Cx43R = 0x10A, + mode132Cx50R = 0x10B, + mode132Cx60R = 0x10C, + mode320x200x555 = 0x10D, + mode320x200x565 = 0x10E, + mode320x200x888 = 0x10F, + mode640x480x555 = 0x110, + mode640x480x565 = 0x111, + mode640x480x888 = 0x112, + mode800x600x555 = 0x113, + mode800x600x565 = 0x114, + mode800x600x888 = 0x115, + mode1024x768x555 = 0x116, + mode1024x768x565 = 0x117, + mode1024x768x888 = 0x118, + mode1280x1024x555 = 0x119, + mode1280x1024x565 = 0x11A, + mode1280x1024x888 = 0x11B, + modeSpecial = 0x81FF, + modeEndOfList = 0xFFFF +}; + +/* + * Get/Set VBE Mode parameters + */ +enum { + kCustomRefreshRateBit = (1 << 11), + kLinearFrameBufferBit = (1 << 14), + kPreserveMemoryBit = (1 << 15) +}; + +/* + * CRTC information block passed to function 4F02 + * to override default refresh rate. + */ +#pragma pack(1) + +typedef struct { + unsigned short HTotal; + unsigned short HSyncStart; + unsigned short HSyncEnd; + unsigned short VTotal; + unsigned short VSyncStart; + unsigned short VSyncEnd; + unsigned char Flags; + unsigned long PixelClock; /* in Hz */ + unsigned short RefreshRate; /* units of 0.01 Hz */ + unsigned char Reserved[40]; +} VBECRTCInfoBlock; + +#pragma pack() + +/* + * Defined flags for 'Flags' field in VBECRTCInfoBlock. + */ +enum { + kCRTCDoubleScannedMode = (1 << 0), + kCRTCInterlacedMode = (1 << 1), + kCRTCNegativeHorizontalSync = (1 << 2), + kCRTCNegativeVerticalSync = (1 << 3) +}; + +/* + * The type of paramter passed to generateCRTCTimings(). + */ +enum { + kCRTCParamRefreshRate, + kCRTCParamPixelClock +}; + +/* + * Palette + */ +typedef unsigned long VBEPalette[256]; + +extern int getVBEInfo(void *vinfo_p); +extern int getVBEModeInfo(int mode, void *minfo_p); +extern int getVBEDACFormat(unsigned char *format); +extern int setVBEDACFormat(unsigned char format); +extern int setVBEPalette(void *palette); +extern int getVBEPalette(void *palette); +extern int setVBEMode(unsigned short mode, const VBECRTCInfoBlock *timing); +extern int getVBECurrentMode(unsigned short *mode); +extern int getVBEPixelClock(unsigned short mode, unsigned long *pixelClock); +extern int generateCRTCTiming(unsigned short width, + unsigned short height, + unsigned long paramValue, + int paramType, + VBECRTCInfoBlock * timing); + +#endif /* !__LIBSAIO_VBE_H */ Index: branches/slice/trunkM/i386/libsaio/acpi_patcher.c =================================================================== --- branches/slice/trunkM/i386/libsaio/acpi_patcher.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/acpi_patcher.c (revision 1171) @@ -0,0 +1,1314 @@ +/* + * Copyright 2008 mackerintel + * 2010 mojodojo, slice + */ + +#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" +#include "smbios_getters.h" + +#ifndef DEBUG_ACPI +#define DEBUG_ACPI 0 +#endif + +#if DEBUG_ACPI==2 +#define DBG(x...) {printf(x); sleep(1);} +#elif DEBUG_ACPI==3 +#define DBG(x...) verbose(x) +#elif DEBUG_ACPI==1 +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif + +bool fix_restart; +uint64_t acpi10_p; +uint64_t acpi20_p; + +int rsdplength; +void *new_dsdt=NULL; + +extern char* gSMBIOSBoardModel; + +// 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; +} + +char st[20]; +char * FourChar(char * s) +{ + int i; + for(i=0; i<4;i++){ + st[i] = (isalpha(s[i])?s[i]:'.'); + } + // strncpy(st, s, 4); + st[4] = '\0'; + return st; +} + + +/* 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 = -1; + 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)) + { + verbose("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); + verbose("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]; +uint32_t acpi_cpu_p_blk = 0; + +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; + DBG("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; + + if (acpi_cpu_count == 0) + acpi_cpu_p_blk = dsdt[i] | (dsdt[i+1] << 8); + + 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 resource_template_register_fixedhw[] = + { + 0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F, + 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x79, 0x00 + }; + + char resource_template_register_systemio[] = + { + 0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x01, + 0x08, 0x00, 0x00, 0x15, 0x04, 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 = false; + bool c3_enabled = false; + bool c4_enabled = false; + bool cst_using_sustemio = false; + + getBoolForKey(kEnableC2State, &c2_enabled, &bootInfo->chameleonConfig); + getBoolForKey(kEnableC3State, &c3_enabled, &bootInfo->chameleonConfig); + getBoolForKey(kEnableC4State, &c4_enabled, &bootInfo->chameleonConfig); + getBoolForKey(kCSTUsingSystemIO, &cst_using_sustemio, &bootInfo->chameleonConfig); + + c2_enabled = c2_enabled | (fadt->C2_Latency < 100); + c3_enabled = c3_enabled | (fadt->C3_Latency < 1000); + + 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); + if (cst_using_sustemio) + { + // C1 + resource_template_register_fixedhw[8] = 0x00; + resource_template_register_fixedhw[9] = 0x00; + resource_template_register_fixedhw[18] = 0x00; + aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw)); + aml_add_byte(tmpl, 0x01); // C1 + aml_add_word(tmpl, 0x0001); // Latency + aml_add_dword(tmpl, 0x000003e8); // Power + + uint8_t p_blk_lo, p_blk_hi; + + if (c2_enabled) // C2 + { + p_blk_lo = acpi_cpu_p_blk + 4; + p_blk_hi = (acpi_cpu_p_blk + 4) >> 8; + + tmpl = aml_add_package(pack); + resource_template_register_systemio[11] = p_blk_lo; // C2 + resource_template_register_systemio[12] = p_blk_hi; // C2 + aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio)); + aml_add_byte(tmpl, 0x02); // C2 + aml_add_word(tmpl, 0x0040); // Latency + aml_add_dword(tmpl, 0x000001f4); // Power + } + + if (c4_enabled) // C4 + { + p_blk_lo = acpi_cpu_p_blk + 5; + p_blk_hi = (acpi_cpu_p_blk + 5) >> 8; + + tmpl = aml_add_package(pack); + resource_template_register_systemio[11] = p_blk_lo; // C4 + resource_template_register_systemio[12] = p_blk_hi; // C4 + aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio)); + aml_add_byte(tmpl, 0x04); // C4 + aml_add_word(tmpl, 0x0080); // Latency + aml_add_dword(tmpl, 0x000000C8); // Power + } + else if (c3_enabled) // C3 + { + p_blk_lo = acpi_cpu_p_blk + 5; + p_blk_hi = (acpi_cpu_p_blk + 5) >> 8; + + tmpl = aml_add_package(pack); + resource_template_register_systemio[11] = p_blk_lo; // C3 + resource_template_register_systemio[12] = p_blk_hi; // C3 + aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio)); + aml_add_byte(tmpl, 0x03); // C3 + aml_add_word(tmpl, 0x0060); // Latency + aml_add_dword(tmpl, 0x0000015e); // Power + } + + } + else + { + // C1 + resource_template_register_fixedhw[11] = 0x00; // C1 + aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw)); + aml_add_byte(tmpl, 0x01); // C1 + aml_add_word(tmpl, 0x0001); // Latency + aml_add_dword(tmpl, 0x000003e8); // Power + + resource_template_register_fixedhw[18] = 0x03; + + if (c2_enabled) // C2 + { + tmpl = aml_add_package(pack); + resource_template_register_fixedhw[11] = 0x10; // C2 + aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw)); + aml_add_byte(tmpl, 0x02); // C2 + aml_add_word(tmpl, 0x0040); // Latency + aml_add_dword(tmpl, 0x000001f4); // Power + } + + if (c4_enabled) // C4 + { + tmpl = aml_add_package(pack); + resource_template_register_fixedhw[11] = 0x30; // C4 + aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw)); + aml_add_byte(tmpl, 0x04); // C4 + aml_add_word(tmpl, 0x0080); // Latency + aml_add_dword(tmpl, 0x000000C8); // Power + } + else if (c3_enabled) + { + tmpl = aml_add_package(pack); + resource_template_register_fixedhw[11] = 0x20; // C3 + aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw)); + aml_add_byte(tmpl, 0x03); // C3 + aml_add_word(tmpl, 0x0060); // Latency + aml_add_dword(tmpl, 0x0000015e); // 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.._ */ + }; +// cpuid_update_generic_info(); + 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 CPU_MODEL_PENTIUM_M: // ??? + case CPU_MODEL_YONAH: // Intel Mobile Core Solo, Duo + case CPU_MODEL_MEROM: // Intel Mobile Core 2 Solo, Duo, Xeon 30xx, Xeon 51xx, Xeon X53xx, Xeon E53xx, Xeon X32xx + case CPU_MODEL_PENRYN: // Intel Core 2 Solo, Duo, Quad, Extreme, Xeon X54xx, Xeon X33xx + 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 = 0; + } + 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: // Intel Core i5, i7, Xeon X34xx LGA1156 (45nm) + case CPU_MODEL_DALES: + case CPU_MODEL_DALES_32NM: // Intel Core i3, i5 LGA1156 (32nm) + case CPU_MODEL_NEHALEM: // Intel Core i7, Xeon W35xx, Xeon X55xx, Xeon E55xx LGA1366 (45nm) + case CPU_MODEL_NEHALEM_EX: // Intel Xeon X75xx, Xeon X65xx, Xeon E75xx, Xeon E65x + case CPU_MODEL_WESTMERE: // Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core + case CPU_MODEL_WESTMERE_EX: // Intel Xeon E7 + case CPU_MODEL_SANDY: // Intel Core i3, i5, i7 LGA1155 (32nm) + case CPU_MODEL_SANDY_XEON: // Intel Xeon E3 + { + maximum.Control = rdmsr64(MSR_IA32_PERF_STATUS) & 0xff; // Seems it always contains maximum multiplier value (with turbo, that's we need)... + minimum.Control = (rdmsr64(MSR_PLATFORM_INFO) >> 40) & 0xff; + + verbose("P-States: min 0x%x, max 0x%x\n", minimum.Control, maximum.Control); + + // Sanity check + if (maximum.Control < minimum.Control) + { + DBG("Insane control values!"); + p_states_count = 0; + } + else + { + uint8_t i; + p_states_count = 0; + + for (i = maximum.Control; i >= minimum.Control; i--) + { + p_states[p_states_count].Control = i; + p_states[p_states_count].CID = p_states[p_states_count].Control << 1; + p_states[p_states_count].Frequency = (Platform->CPU.FSBFrequency / 1000000) * i; + p_states_count++; + } + } + + break; + } + default: + verbose ("Unsupported CPU (0x%X): P-States not generated !!!\n", Platform->CPU.Family); + 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 = NULL; + 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->chameleonConfig); + } else { + DBG ("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 (fadt_mod && Platform->Type) { + fadt_mod->PM_Profile = Platform->Type; + } else if(fadt) + Platform->Type = fadt->PM_Profile; + else + Platform->Type = 1; + + //User override default value + if ( (value=getStringForKey(kSystemType, &bootInfo->chameleonConfig))!=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 + DBG("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 + msglog("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); + + DBG("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 ? */ + //Slice (uint64_t) + acpi10_p = (uint64_t)(uint32_t)getAddressOfAcpiTable(); + acpi20_p = (uint64_t)(uint32_t)getAddressOfAcpi20Table(); + addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI"); + if(acpi20_p) addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20"); + else { + DBG("no ACPI 2\n"); + } + return 1; +} + +static struct acpi_2_xsdt* createNewXSDTfromRSDT(struct acpi_2_rsdt * rsdt) +{ + struct acpi_2_xsdt *xsdt; + int xsdt_entries_num, i; + uint32_t xsdt_len; + if (!rsdt) { + return NULL; + } + //Create XSDT in addition to RSDT as a 64bit copy + if((rsdt->Length<0) || (rsdt->Length>1000)){ + DBG(" incorrect RSDT length: %08lx\n", rsdt->Length); +#if DEBUG_DSDT + getc(); +#endif + return NULL; + } + xsdt_entries_num = (rsdt->Length - sizeof(struct acpi_2_rsdt)) >> 2; + xsdt_len = sizeof(struct acpi_2_rsdt) + (xsdt_entries_num << 3); + xsdt = (struct acpi_2_xsdt*)AllocateKernelMemory(xsdt_len); + bcopy(rsdt, xsdt, sizeof(struct acpi_2_rsdt)); + //Change signature from RSDT to XSDT + strncpy(xsdt->Signature, FourChar("XSDT"), 4); + //Now copy address table + uint64_t *table1 = (uint64_t *)(xsdt+1); + uint32_t *table2 = (uint32_t *)(rsdt+1); + if ((xsdt_entries_num>0) && (xsdt_entries_num<20)) { + for(i=0; iLength = xsdt_len; + //Correct checksums + xsdt->Checksum=0; + xsdt->Checksum=256-checksum8(xsdt,xsdt_len); + return xsdt; +} + +static struct acpi_2_rsdp* createNewACPI20(struct acpi_2_rsdp * old_rsdp) +{ + if(!old_rsdp) return NULL; + //Slice I want to copy acpi10 table to create ACPI20 + // uint64_t *xsdt_entries; + if(*(uint64_t *)old_rsdp != ACPI_SIGNATURE_UINT64_LE){ + DBG(" wrong signature %08lx\n", (*(uint64_t *)old_rsdp)); + return NULL; + } + DBG(" old_rsdp = %08lx\n", (uint32_t)old_rsdp); + // if(((int)old_rsdp->Length < 0) || ((int)old_rsdp->Length > 84)) + // return NULL; + //No! ACPI10_rsdp_length=20 and no such field old_rsdp->Length + + struct acpi_2_rsdp * rsdp=(struct acpi_2_rsdp *) AllocateKernelMemory(36); + DBG(" new_rsdp = %08lx\n", (uint32_t)rsdp); + bzero(rsdp, 36); + bcopy(old_rsdp, rsdp, 20); + strncpy(rsdp->OEMID, "Apple ", 6); + rsdp->Revision = 2; + rsdp->Length = 36; + struct acpi_2_rsdt *rsdt = (struct acpi_2_rsdt *)(rsdp->RsdtAddress); //copied from old +// dumpRSDT(rsdt, 0); + rsdp->XsdtAddress = (uint64_t)(uint32_t)createNewXSDTfromRSDT(rsdt); +// dumpRSDT((struct acpi_2_rsdt *)(uint32_t)(rsdp->XsdtAddress), 0); + rsdp->Checksum=0; + rsdp->Checksum=256-checksum8(rsdp,20); + rsdp->ExtendedChecksum=0; + rsdp->ExtendedChecksum=256-checksum8(rsdp,36); + return rsdp; +} + + +/* 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, old_dsdt_len = 0; + struct acpi_2_rsdp *rsdp, *rsdp_mod, *rsdp1 = 0; + struct acpi_2_rsdt *rsdt, *rsdt_mod = 0; + struct acpi_2_rsdt *xsdt; //, *xsdt_mod = 0; + char* old_dsdt = 0; + + // Try using the file specified with the DSDT option + if (getValueForKey(kDSDT, &filename, &len, &bootInfo->chameleonConfig)) + { + 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->chameleonConfig); + getBoolForKey(kGeneratePStates, &generate_pstates, &bootInfo->chameleonConfig); + getBoolForKey(kGenerateCStates, &generate_cstates, &bootInfo->chameleonConfig); + + { + 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++) { +// int rsdplength; + //Here version=0 for ACPI 1.0 and version=1 for ACPI 2.0 + // Find original rsdp + rsdp=(struct acpi_2_rsdp *)(version?getAddressOfAcpi20Table():getAddressOfAcpiTable()); + //Slice + if (!rsdp) + { + if (version){ + DBG("No ACPI version 2 found. Creating...\n"); + rsdp=createNewACPI20(rsdp1); + if(!rsdp){ + addConfigurationTable(&gEfiAcpi20TableGuid, NULL, "ACPI_20"); + continue; + } + } else { + DBG("No ACPI version 1 found. Ignoring\n"); + addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI"); + continue; + } + } + if(!version) rsdp1 = rsdp; //save to create new. + 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); + xsdt=(struct acpi_2_rsdt *)(uint32_t)(rsdp->XsdtAddress); + DBG("RSDT @%x, Length %d\n",rsdt, rsdt->Length); + + //if we have RSDT table + 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;iOEMID, "Apple ", 6); + strncpy(t->OEMTableId, MacModel, 8); + t->OEMRevision = ModelRev; + t->Checksum=0; + t->Checksum=256-checksum8(t,t->Length); + + } + if (tableSign(table, "FACP")) + { + struct acpi_2_fadt *fadt, *fadt_mod; + fadt=(struct acpi_2_fadt *)rsdt_entries[i]; + + DBG("FADT found @%x, Length %d\n",fadt, fadt->Length); + + if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000) + { + printf("FADT incorrect. Not modified\n"); + continue; + } + + if(version && fix_restart){ //ACPI 2.0 + fadt_mod = patch_fadt(fadt, new_dsdt); + rsdt_entries[i-dropoffset]=(uint32_t)fadt_mod; + } else { + if (fadt && Platform->Type) + fadt->PM_Profile = Platform->Type; //For ACPI1.0 the only patch + fadt_mod = fadt; + rsdt_entries[i-dropoffset]=(uint32_t)fadt; + } + DBG("FADT_mod table sign: %s\n", fadt_mod->Signature); + //Slice + //Now I want to replace DSDT in place + // it is only way to patch DSDT on some platform + old_dsdt = (char *)fadt->DSDT; + if(!old_dsdt || !tableSign(old_dsdt, "DSDT")){ + if(fadt_mod->Length > 140) old_dsdt = (char *)(uint32_t)fadt_mod->X_DSDT; + if(!old_dsdt || !tableSign(old_dsdt, "DSDT")) old_dsdt = (char *)new_dsdt; + } + DBG("New DSDT @%x, X_DSDT %x after FADT patch\n",fadt_mod->DSDT,fadt_mod->X_DSDT); + + if(tableSign(old_dsdt, "DSDT")) + old_dsdt_len = ((struct acpi_2_rsdt *)old_dsdt)->Length; + int new_dsdt_len = ((struct acpi_2_rsdt *)new_dsdt)->Length; + if(new_dsdt_len > old_dsdt_len) { + old_dsdt = (char *)new_dsdt; + DBG(" New DSDT is longer then old\n"); + len = 0; + } + else len = new_dsdt_len; + + + // 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; + } + }//for rsdt entries + DBG("\n"); + //Slice - Correct header to MacModel & Vendor, correct chechsum + strncpy(rsdt_mod->OEMID, "Apple ", 6); + strncpy(rsdt_mod->OEMTableId, MacModel, 8); + rsdt_mod->OEMRevision = ModelRev; + + // 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; + verbose("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 Sign=%c%c%c%c\n", (uint32_t)(rsdp->XsdtAddress>>32), + (uint32_t)rsdp->XsdtAddress, xsdt->Length, xsdt[0], xsdt[1], xsdt[2], xsdt[3]); + 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) + { + DBG("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 \n", 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 \n", 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 + */ + //Slice - it is possible only for ACPI20 + if (version) { + if(rsdp->RsdtAddress){ + rsdp_mod->XsdtAddress = + (uint64_t)(uint32_t)createNewXSDTfromRSDT((struct acpi_2_rsdt*)rsdp->RsdtAddress); + continue; + } + else + DBG(" no sample to create XSDT, dropping\n"); + } + + rsdp_mod->XsdtAddress=0xffffffffffffffffLL; + DBG("XSDT not found or XSDT incorrect\n"); + } + } + //Slice - correct DSDT in place + if(len && old_dsdt && new_dsdt && (old_dsdt != new_dsdt)){ + DBG("old_dsdt=%08x new_dsdt=%08x new_len=%d\n", (unsigned int)old_dsdt, (unsigned int)new_dsdt, len); + bcopy(new_dsdt, old_dsdt, len); + } + + // 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 ? */ + //Slice because rsdp_mod is a pointer (32bit in i386) to a structure uint64_t* + acpi20_p = (uint64_t)(uint32_t)rsdp_mod; + addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20"); + } + else + { + /* XXX aserebln why uint32 cast if pointer is uint64 ? */ + acpi10_p = (uint64_t)(uint32_t)rsdp_mod; + addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI"); + } + } +#if DEBUG_ACPI + printf("Press a key to continue... (DEBUG_ACPI)\n"); + getchar(); +#endif + return 1; +} Index: branches/slice/trunkM/i386/libsaio/device_tree.h =================================================================== --- branches/slice/trunkM/i386/libsaio/device_tree.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/device_tree.h (revision 1171) @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All Rights Reserved. + */ + +#ifndef __DEVICE_TREE_H +#define __DEVICE_TREE_H + +#include +#include + +typedef struct _Property { + const char * name; + uint32_t length; + void * value; + + struct _Property * next; +} Property; + +typedef struct _Node { + struct _Property * properties; + struct _Property * last_prop; + + struct _Node * children; + + struct _Node * next; +} Node; + + +extern Property * +DT__AddProperty(Node *node, const char *name, uint32_t length, void *value); + +extern Node * +DT__AddChild(Node *parent, const char *name); + +Node * +DT__FindNode(const char *path, bool createIfMissing); + +extern void +DT__FreeProperty(Property *prop); + +extern void +DT__FreeNode(Node *node); + +extern char * +DT__GetName(Node *node); + +void +DT__Initialize(void); + +/* + * Free up memory used by in-memory representation + * of device tree. + */ +extern void +DT__Finalize(void); + +void +DT__FlattenDeviceTree(void **result, uint32_t *length); + + +#endif /* __DEVICE_TREE_H */ Index: branches/slice/trunkM/i386/libsaio/allocate.c =================================================================== --- branches/slice/trunkM/i386/libsaio/allocate.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/allocate.c (revision 1171) @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include "sl.h" +#include "saio_internal.h" +#include "bootstruct.h" +#include "device_tree.h" + +static long gImageLastKernelAddr; + +#define kPageSize 4096 +#define RoundPage(x) ((((unsigned)(x)) + kPageSize - 1) & ~(kPageSize - 1)) + + +long +AllocateMemoryRange(char * rangeName, long start, long length, long type) +{ + char *nameBuf; + uint32_t *buffer; + + nameBuf = malloc(strlen(rangeName) + 1); + if (nameBuf == 0) return -1; + strcpy(nameBuf, rangeName); + + buffer = malloc(2 * sizeof(uint32_t)); + if (buffer == 0) return -1; + + buffer[0] = start; + buffer[1] = length; + + DT__AddProperty(gMemoryMapNode, nameBuf, 2 * sizeof(uint32_t), (char *)buffer); + + return 0; +} + +long +AllocateKernelMemory( long inSize ) +{ + long addr; + + if (gImageLastKernelAddr == 0) { + gImageLastKernelAddr = RoundPage( bootArgs->kaddr + + bootArgs->ksize ); + } + addr = gImageLastKernelAddr; + gImageLastKernelAddr += RoundPage(inSize); + + if ( gImageLastKernelAddr >= (KERNEL_ADDR + KERNEL_LEN) ) { + stop ("AllocateKernelMemory error"); + } + + bootArgs->ksize = gImageLastKernelAddr - bootArgs->kaddr; + + return addr; +} Index: branches/slice/trunkM/i386/libsaio/hfs.h =================================================================== --- branches/slice/trunkM/i386/libsaio/hfs.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/hfs.h (revision 1171) @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 2.0 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +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 long * dirIndex, + char ** name, long * flags, long * time, + FinderInfo * finderInfo, long * infoValid); +extern void HFSGetDescription(CICell ih, char *str, long strMaxLen); +extern long HFSGetFileBlock(CICell ih, char *str, unsigned long long *firstBlock); +extern long HFSGetUUID(CICell ih, char *uuidStr); +extern void HFSFree(CICell ih); +extern bool HFSProbe (const void *buf); Index: branches/slice/trunkM/i386/libsaio/bootargs.h =================================================================== --- branches/slice/trunkM/i386/libsaio/bootargs.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/bootargs.h (revision 1171) @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +#ifndef _PEXPERT_I386_BOOT_H +#define _PEXPERT_I386_BOOT_H + +#include + +/* + * What the booter leaves behind for the kernel. + */ + +/* + * Types of boot driver that may be loaded by the booter. + */ +enum { + kBootDriverTypeInvalid = 0, + kBootDriverTypeKEXT = 1, + kBootDriverTypeMKEXT = 2 +}; + +enum { + kEfiReservedMemoryType = 0, + kEfiLoaderCode = 1, + kEfiLoaderData = 2, + kEfiBootServicesCode = 3, + kEfiBootServicesData = 4, + kEfiRuntimeServicesCode = 5, + kEfiRuntimeServicesData = 6, + kEfiConventionalMemory = 7, + kEfiUnusableMemory = 8, + kEfiACPIReclaimMemory = 9, + kEfiACPIMemoryNVS = 10, + kEfiMemoryMappedIO = 11, + kEfiMemoryMappedIOPortSpace = 12, + kEfiPalCode = 13, + kEfiMaxMemoryType = 14 +}; + +/* + * Memory range descriptor. + */ +typedef struct EfiMemoryRange { + uint32_t Type; + uint32_t Pad; + uint64_t PhysicalStart; + uint64_t VirtualStart; + uint64_t NumberOfPages; + uint64_t Attribute; +} EfiMemoryRange; + +#define BOOT_LINE_LENGTH 1024 +#define BOOT_STRING_LEN BOOT_LINE_LENGTH + +/* + * Video information.. + */ + +struct Boot_Video { + uint32_t v_baseAddr; /* Base address of video memory */ + uint32_t v_display; /* Display Code (if Applicable */ + uint32_t v_rowBytes; /* Number of bytes per pixel row */ + uint32_t v_width; /* Width */ + uint32_t v_height; /* Height */ + uint32_t v_depth; /* Pixel Depth */ +}; + +typedef struct Boot_Video Boot_Video; + +/* Values for v_display */ + +#define GRAPHICS_MODE 1 +#define FB_TEXT_MODE 2 + +/* Boot argument structure - passed into Mach kernel at boot time. + * "Revision" can be incremented for compatible changes + */ +// Lion +#define kBootArgsRevision 0 +#define kBootArgsVersion 2 + +// Snow Leopard and older +#define kBootArgsPreLionRevision 6 +#define kBootArgsPreLionVersion 1 + +/* Snapshot constants of previous revisions that are supported */ + +#define kBootArgsEfiMode32 32 +#define kBootArgsEfiMode64 64 + +typedef struct boot_args { + uint16_t Revision; /* Revision of boot_args structure */ + uint16_t Version; /* Version of boot_args structure */ + + uint8_t efiMode; /* 32 = 32-bit, 64 = 64-bit */ + uint8_t debugMode; /* Bit field with behavior changes */ + uint8_t __reserved1[2]; + + char CommandLine[BOOT_LINE_LENGTH]; /* Passed in command line */ + + uint32_t MemoryMap; /* Physical address of memory map */ + uint32_t MemoryMapSize; + uint32_t MemoryMapDescriptorSize; + uint32_t MemoryMapDescriptorVersion; + + Boot_Video Video; /* Video Information */ + + uint32_t deviceTreeP; /* Physical address of flattened device tree */ + uint32_t deviceTreeLength; /* Length of flattened tree */ + + uint32_t kaddr; /* Physical address of beginning of kernel text */ + uint32_t ksize; /* Size of combined kernel text+data+efi */ + + uint32_t efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */ + uint32_t efiRuntimeServicesPageCount; + uint64_t efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */ + + uint32_t efiSystemTable; /* physical address of system table in runtime area */ + uint32_t __reserved2; + + uint32_t performanceDataStart; /* physical address of log */ + uint32_t performanceDataSize; + + uint32_t keyStoreDataStart; /* physical address of key store data */ + uint32_t keyStoreDataSize; + uint64_t bootMemStart; + uint64_t bootMemSize; + uint64_t PhysicalMemorySize; + uint64_t FSBFrequency; + uint32_t __reserved4[734]; + +} boot_args; + +typedef struct boot_args_pre_lion { + uint16_t Revision; /* Revision of boot_args structure */ + uint16_t Version; /* Version of boot_args structure */ + + char CommandLine[BOOT_LINE_LENGTH]; /* Passed in command line */ + + uint32_t MemoryMap; /* Physical address of memory map */ + uint32_t MemoryMapSize; + uint32_t MemoryMapDescriptorSize; + uint32_t MemoryMapDescriptorVersion; + + Boot_Video Video; /* Video Information */ + + uint32_t deviceTreeP; /* Physical address of flattened device tree */ + uint32_t deviceTreeLength; /* Length of flattened tree */ + + uint32_t kaddr; /* Physical address of beginning of kernel text */ + uint32_t ksize; /* Size of combined kernel text+data+efi */ + + uint32_t efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */ + uint32_t efiRuntimeServicesPageCount; + uint32_t efiSystemTable; /* physical address of system table in runtime area */ + + uint8_t efiMode; /* 32 = 32-bit, 64 = 64-bit */ + uint8_t __reserved1[3]; + uint32_t __reserved2[1]; + uint32_t performanceDataStart; /* physical address of log */ + uint32_t performanceDataSize; + uint64_t efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */ + uint32_t __reserved3[2]; + +} boot_args_pre_lion; + +extern char gMacOSVersion[8]; + +#endif /* _PEXPERT_I386_BOOT_H */ Index: branches/slice/trunkM/i386/libsaio/hfs_compare.c =================================================================== --- branches/slice/trunkM/i386/libsaio/hfs_compare.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/hfs_compare.c (revision 1171) @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 2.0 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * HFSCompare.c - Functions for working with and comparing HFS nams. + * + * Copyright (c) 1999-2000 Apple Computer, Inc. + * + * DRI: Josh de Cesare + */ + +#include +#include "hfs_CaseTables.h" + +#if ! UNCOMPRESSED + +static unsigned short * +UncompressStructure(struct compressed_block *bp, int count, int size) +{ + unsigned short *out = malloc(size); + unsigned short *op = out; + unsigned short data; + int i, j; + + for (i=0; icount) + { + stop("HFS+ Unicode tables are malformed\n"); + } + data = bp->data; + for (j=0; jcount; j++) { + *op++ = data; + if (bp->type == kTypeAscending) data++; + else if (bp->type == kTypeAscending256) data += 256; + } + } + return out; +} + +static void +InitCompareTables(void) +{ + if (gCompareTable == 0) { + gCompareTable = UncompressStructure(gCompareTableCompressed, + kCompareTableNBlocks, kCompareTableDataSize); + gLowerCaseTable = UncompressStructure(gLowerCaseTableCompressed, + kLowerCaseTableNBlocks, kLowerCaseTableDataSize); + } +} + +#endif /* ! UNCOMPRESSED */ + +//_______________________________________________________________________ +// +// Routine: FastRelString +// +// Output: returns -1 if str1 < str2 +// returns 1 if str1 > str2 +// return 0 if equal +// +//_______________________________________________________________________ + +int32_t FastRelString(u_int8_t * str1, u_int8_t * str2) +{ + int32_t bestGuess; + u_int8_t length, length2; + +#if ! UNCOMPRESED + InitCompareTables(); +#endif + + length = *(str1++); + length2 = *(str2++); + + if (length == length2) + bestGuess = 0; + else if (length < length2) + bestGuess = -1; + else + { + bestGuess = 1; + length = length2; + } + + while (length--) + { + u_int32_t aChar, bChar; + + aChar = *(str1++); + bChar = *(str2++); + + if (aChar != bChar) /* If they don't match exacly, do case conversion */ + { + u_int16_t aSortWord, bSortWord; + + aSortWord = gCompareTable[aChar]; + bSortWord = gCompareTable[bChar]; + + if (aSortWord > bSortWord) + return 1; + + if (aSortWord < bSortWord) + return -1; + } + + /* + * If characters match exactly, then go on to next character + * immediately without doing any extra work. + */ + } + + /* if you got to here, then return bestGuess */ + return bestGuess; +} + + +// +// FastUnicodeCompare - Compare two Unicode strings; produce a relative ordering +// +// IF RESULT +// -------------------------- +// str1 < str2 => -1 +// str1 = str2 => 0 +// str1 > str2 => +1 +// +// The lower case table starts with 256 entries (one for each of the upper bytes +// of the original Unicode char). If that entry is zero, then all characters with +// that upper byte are already case folded. If the entry is non-zero, then it is +// the _index_ (not byte offset) of the start of the sub-table for the characters +// with that upper byte. All ignorable characters are folded to the value zero. +// +// In pseudocode: +// +// Let c = source Unicode character +// Let table[] = lower case table +// +// lower = table[highbyte(c)] +// if (lower == 0) +// lower = c +// else +// lower = table[lower+lowbyte(c)] +// +// if (lower == 0) +// ignore this character +// +// To handle ignorable characters, we now need a loop to find the next valid character. +// Also, we can't pre-compute the number of characters to compare; the string length might +// be larger than the number of non-ignorable characters. Further, we must be able to handle +// ignorable characters at any point in the string, including as the first or last characters. +// We use a zero value as a sentinel to detect both end-of-string and ignorable characters. +// Since the File Manager doesn't prevent the NUL character (value zero) as part of a filename, +// the case mapping table is assumed to map u+0000 to some non-zero value (like 0xFFFF, which is +// an invalid Unicode character). +// +// Pseudocode: +// +// while (1) { +// c1 = GetNextValidChar(str1) // returns zero if at end of string +// c2 = GetNextValidChar(str2) +// +// if (c1 != c2) break // found a difference +// +// if (c1 == 0) // reached end of string on both strings at once? +// return 0; // yes, so strings are equal +// } +// +// // When we get here, c1 != c2. So, we just need to determine which one is less. +// if (c1 < c2) +// return -1; +// else +// return 1; +// + +int32_t FastUnicodeCompare( u_int16_t * str1, register u_int32_t length1, + u_int16_t * str2, register u_int32_t length2, int byte_order ) +{ + register u_int16_t c1,c2; + register u_int16_t temp; + +#if ! UNCOMPRESSED + InitCompareTables(); +#endif + + while (1) { + /* Set default values for c1, c2 in case there are no more valid chars */ + c1 = 0; + c2 = 0; + + /* Find next non-ignorable char from str1, or zero if no more */ + while (length1 && c1 == 0) { + if (byte_order == OSBigEndian) + c1 = SWAP_BE16(*(str1++)); + else + c1 = SWAP_LE16(*(str1++)); + --length1; + if ((temp = gLowerCaseTable[c1>>8]) != 0) // is there a subtable for this upper byte? + c1 = gLowerCaseTable[temp + (c1 & 0x00FF)]; // yes, so fold the char + } + + /* Find next non-ignorable char from str2, or zero if no more */ + while (length2 && c2 == 0) { + if (byte_order == OSBigEndian) + c2 = SWAP_BE16(*(str2++)); + else + c2 = SWAP_LE16(*(str2++)); + --length2; + if ((temp = gLowerCaseTable[c2>>8]) != 0) // is there a subtable for this upper byte? + c2 = gLowerCaseTable[temp + (c2 & 0x00FF)]; // yes, so fold the char + } + + if (c1 != c2) /* found a difference, so stop looping */ + break; + + if (c1 == 0) /* did we reach the end of both strings at the same time? */ + return 0; /* yes, so strings are equal */ + } + + if (c1 < c2) + return -1; + else + return 1; +} + + +// +// BinaryUnicodeCompare - Compare two Unicode strings; produce a relative ordering +// Compared using a 16-bit binary comparison (no case folding) +// +int32_t BinaryUnicodeCompare (u_int16_t * str1, u_int32_t length1, + u_int16_t * str2, u_int32_t length2) +{ + register u_int16_t c1, c2; + int32_t bestGuess; + u_int32_t length; + + bestGuess = 0; + + if (length1 < length2) { + length = length1; + --bestGuess; + } else if (length1 > length2) { + length = length2; + ++bestGuess; + } else { + length = length1; + } + + while (length--) { + c1 = *(str1++); + c2 = *(str2++); + + if (c1 > c2) + return (1); + if (c1 < c2) + return (-1); + } + + return (bestGuess); +} + + +/* + * UTF-8 (UCS Transformation Format) + * + * The following subset of UTF-8 is used to encode UCS-2 filenames. It + * requires a maximum of three 3 bytes per UCS-2 character. Only the + * shortest encoding required to represent the significant UCS-2 bits + * is legal. + * + * UTF-8 Multibyte Codes + * + * Bytes Bits UCS-2 Min UCS-2 Max UTF-8 Byte Sequence (binary) + * ------------------------------------------------------------------- + * 1 7 0x0000 0x007F 0xxxxxxx + * 2 11 0x0080 0x07FF 110xxxxx 10xxxxxx + * 3 16 0x0800 0xFFFF 1110xxxx 10xxxxxx 10xxxxxx + * ------------------------------------------------------------------- + */ + + +/* + * utf_encodestr - Encodes the UCS-2 (Unicode) string at ucsp into a + * null terminated UTF-8 string at utf8p. + * + * ucslen is the number of UCS-2 input characters (not bytes) + * bufsize is the size of the output buffer in bytes + */ +void +utf_encodestr( const u_int16_t * ucsp, int ucslen, + u_int8_t * utf8p, u_int32_t bufsize, int byte_order ) +{ + u_int8_t *bufend; + u_int16_t ucs_ch; + + bufend = utf8p + bufsize; + + while (ucslen-- > 0) { + if (byte_order == OSBigEndian) + ucs_ch = SWAP_BE16(*ucsp++); + else + ucs_ch = SWAP_LE16(*ucsp++); + + if (ucs_ch < 0x0080) { + if (utf8p >= bufend) + break; + if (ucs_ch == '\0') + continue; /* skip over embedded NULLs */ + *utf8p++ = ucs_ch; + + } else if (ucs_ch < 0x800) { + if ((utf8p + 1) >= bufend) + break; + *utf8p++ = (ucs_ch >> 6) | 0xc0; + *utf8p++ = (ucs_ch & 0x3f) | 0x80; + + } else { + if ((utf8p + 2) >= bufend) + break; + *utf8p++ = (ucs_ch >> 12) | 0xe0; + *utf8p++ = ((ucs_ch >> 6) & 0x3f) | 0x80; + *utf8p++ = ((ucs_ch) & 0x3f) | 0x80; + } + } + + *utf8p = '\0'; +} + + +/* + * utf_decodestr - Decodes the null terminated UTF-8 string at + * utf8p into a UCS-2 (Unicode) string at ucsp. + * + * ucslen is the number of UCS-2 output characters (not bytes) + * bufsize is the size of the output buffer in bytes + */ +void utf_decodestr(const u_int8_t * utf8p, u_int16_t * ucsp, u_int16_t * ucslen, u_int32_t bufsize, int byte_order) +{ + u_int16_t *bufstart; + u_int16_t *bufend; + u_int16_t ucs_ch; + u_int8_t byte; + + bufstart = ucsp; + bufend = (u_int16_t *)((u_int8_t *)ucsp + bufsize); + + while ((byte = *utf8p++) != '\0') { + if (ucsp >= bufend) + break; + + /* check for ascii */ + if (byte < 0x80) { + ucs_ch = byte; + + if (byte_order == OSBigEndian) + *ucsp++ = SWAP_BE16(ucs_ch); + else + *ucsp++ = SWAP_LE16(ucs_ch); + + continue; + } + + switch (byte & 0xf0) { + /* 2 byte sequence*/ + case 0xc0: + case 0xd0: + /* extract bits 6 - 10 from first byte */ + ucs_ch = (byte & 0x1F) << 6; + break; + /* 3 byte sequence*/ + case 0xe0: + /* extract bits 12 - 15 from first byte */ + ucs_ch = (byte & 0x0F) << 6; + + /* extract bits 6 - 11 from second byte */ + if (((byte = *utf8p++) & 0xc0) != 0x80) + goto stop; + + ucs_ch += (byte & 0x3F); + ucs_ch <<= 6; + break; + default: + goto stop; + } + + /* extract bits 0 - 5 from final byte */ + if (((byte = *utf8p++) & 0xc0) != 0x80) + goto stop; + ucs_ch += (byte & 0x3F); + + if (byte_order == OSBigEndian) + *ucsp++ = SWAP_BE16(ucs_ch); + else + *ucsp++ = SWAP_LE16(ucs_ch); + } +stop: + if (byte_order == OSBigEndian) + *ucslen = SWAP_BE16(ucsp - bufstart); + else + *ucslen = SWAP_LE16(ucsp - bufstart); +} Index: branches/slice/trunkM/i386/libsaio/spd.c =================================================================== --- branches/slice/trunkM/i386/libsaio/spd.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/spd.c (revision 1171) @@ -0,0 +1,413 @@ +/* + * spd.c - serial presence detect memory information + * + * Originally restored from pcefi10.5 + * Dynamic mem detection original impl. by Rekursor + * System profiler fix and other fixes by Mozodojo. + */ + +#include "libsaio.h" +#include "pci.h" +#include "platform.h" +#include "spd.h" +#include "cpu.h" +#include "saio_internal.h" +#include "bootstruct.h" +#include "memvendors.h" + +#ifndef DEBUG_SPD +#define DEBUG_SPD 0 +#endif + +#if DEBUG_SPD +#define DBG(x...) printf(x) +#else +#define DBG(x...) msglog(x) +#endif + +static const char *spd_memory_types[] = +{ + "RAM", /* 00h Undefined */ + "FPM", /* 01h FPM */ + "EDO", /* 02h EDO */ + "", /* 03h PIPELINE NIBBLE */ + "SDRAM", /* 04h SDRAM */ + "", /* 05h MULTIPLEXED ROM */ + "DDR SGRAM", /* 06h SGRAM DDR */ + "DDR SDRAM", /* 07h SDRAM DDR */ + "DDR2 SDRAM", /* 08h SDRAM DDR 2 */ + "", /* 09h Undefined */ + "", /* 0Ah Undefined */ + "DDR3 SDRAM" /* 0Bh SDRAM DDR 3 */ +}; + +#define UNKNOWN_MEM_TYPE 2 +static uint8_t spd_mem_to_smbios[] = +{ + UNKNOWN_MEM_TYPE, /* 00h Undefined */ + UNKNOWN_MEM_TYPE, /* 01h FPM */ + UNKNOWN_MEM_TYPE, /* 02h EDO */ + UNKNOWN_MEM_TYPE, /* 03h PIPELINE NIBBLE */ + SMB_MEM_TYPE_SDRAM, /* 04h SDRAM */ + SMB_MEM_TYPE_ROM, /* 05h MULTIPLEXED ROM */ + SMB_MEM_TYPE_SGRAM, /* 06h SGRAM DDR */ + SMB_MEM_TYPE_DDR, /* 07h SDRAM DDR */ + SMB_MEM_TYPE_DDR2, /* 08h SDRAM DDR 2 */ + UNKNOWN_MEM_TYPE, /* 09h Undefined */ + UNKNOWN_MEM_TYPE, /* 0Ah Undefined */ + SMB_MEM_TYPE_DDR3 /* 0Bh SDRAM DDR 3 */ +}; +#define SPD_TO_SMBIOS_SIZE (sizeof(spd_mem_to_smbios)/sizeof(uint8_t)) + +#define rdtsc(low,high) \ +__asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) + +#define SMBHSTSTS 0 +#define SMBHSTCNT 2 +#define SMBHSTCMD 3 +#define SMBHSTADD 4 +#define SMBHSTDAT 5 +#define SBMBLKDAT 7 + +/** Read one byte from the intel i2c, used for reading SPD on intel chipsets only. */ +unsigned char smb_read_byte_intel(uint32_t base, uint8_t adr, uint8_t cmd) +{ + int l1, h1, l2, h2; + unsigned long long t; + + outb(base + SMBHSTSTS, 0x1f); // reset SMBus Controller + outb(base + SMBHSTDAT, 0xff); + + rdtsc(l1, h1); + while ( inb(base + SMBHSTSTS) & 0x01) // wait until read + { + rdtsc(l2, h2); + t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform->CPU.TSCFrequency / 100); + if (t > 5) + return 0xFF; // break + } + + outb(base + SMBHSTCMD, cmd); + outb(base + SMBHSTADD, (adr << 1) | 0x01 ); + outb(base + SMBHSTCNT, 0x48 ); + + rdtsc(l1, h1); + + while (!( inb(base + SMBHSTSTS) & 0x02)) // wait til command finished + { + rdtsc(l2, h2); + 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, uint32_t base, int slot_num) +{ + uint8_t bank = 0; + uint8_t code = 0; + int i = 0; + uint8_t * spd = (uint8_t *) slot->spd; + + if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) { // DDR3 + 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[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[64]; + bank = 0; + } + for (i=0; i < VEN_MAP_SIZE; i++) + if (bank==vendorMap[i].bank && code==vendorMap[i].code) + return vendorMap[i].name; + } + /* OK there is no vendor id here lets try to match the partnum if it exists */ + if (strstr(slot->PartNo,"GU332") == slot->PartNo) // Unifosa fingerprint + return "Unifosa"; + return "NoName"; +} + +/** Get Default Memory Module Speed (no overclocking handled) */ +int getDDRspeedMhz(const char * spd) +{ + if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) { + switch(spd[12]) { + case 0x0f: + return 1066; + case 0x0c: + return 1333; + case 0x0a: + return 1600; + case 0x14: + default: + return 800; + } + } + else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) { + switch(spd[9]) { + case 0x50: + return 400; + case 0x3d: + return 533; + case 0x30: + return 667; + case 0x25: + default: + return 800; + } + } + return 800; // default freq for unknown types +} + +#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]; + + 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 + { + 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)); + } + + return strdup(asciiSerial); +} + +/** Get DDR3 or DDR2 Part Number, always return a valid ptr */ +const char * getDDRPartNum(char* spd, uint32_t base, int slot) +{ + static char asciiPartNo[32]; + int i, start=0, index = 0; + + 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); +} + +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, speed; + uint8_t spd_size, spd_type; + uint32_t base, mmio, hostc; +// bool dump = false; + RamSlotInfo_t* slot; + + uint16_t cmd = pci_config_read16(smbus_dev->dev.addr, 0x04); + DBG("SMBus CmdReg: 0x%x\n", cmd); + pci_config_write16(smbus_dev->dev.addr, 0x04, cmd | 1); + + mmio = pci_config_read32(smbus_dev->dev.addr, 0x10);// & ~0x0f; + base = pci_config_read16(smbus_dev->dev.addr, 0x20) & 0xFFFE; + hostc = pci_config_read8(smbus_dev->dev.addr, 0x40); + verbose("Scanning SMBus [%04x:%04x], mmio: 0x%x, ioport: 0x%x, hostc: 0x%x\n", + smbus_dev->vendor_id, smbus_dev->device_id, mmio, base, hostc); + +//Azi: no use for this! +// getBoolForKey("DumpSPD", &dump, &bootInfo->chameleonConfig); + // needed at least for laptops + bool fullBanks = Platform->DMI.MemoryModules == Platform->DMI.CntMemorySlots; + + char spdbuf[MAX_SPD_SIZE]; + // Search MAX_RAM_SLOTS slots + for (i = 0; i < MAX_RAM_SLOTS; i++){ + slot = &Platform->RAM.DIMM[i]; + spd_size = smb_read_byte_intel(base, 0x50 + i, 0); + DBG("SPD[0] (size): %d @0x%x\n", spd_size, 0x50 + i); + // Check spd is present + if (spd_size && (spd_size != 0xff)) + { + + 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); + init_spd(slot->spd, base, i); + + switch (slot->spd[SPD_MEMORY_TYPE]) { + case SPD_MEMORY_TYPE_SDRAM_DDR2: + + slot->ModuleSize = ((1 << (slot->spd[SPD_NUM_ROWS] & 0x0f) + (slot->spd[SPD_NUM_COLUMNS] & 0x0f) - 17) * + ((slot->spd[SPD_NUM_DIMM_BANKS] & 0x7) + 1) * slot->spd[SPD_NUM_BANKS_PER_SDRAM]); + break; + + case SPD_MEMORY_TYPE_SDRAM_DDR3: + + slot->ModuleSize = ((slot->spd[4] & 0x0f) + 28 ) + ((slot->spd[8] & 0x7) + 3 ); + slot->ModuleSize -= (slot->spd[7] & 0x7) + 25; + slot->ModuleSize = ((1 << slot->ModuleSize) * (((slot->spd[7] >> 3) & 0x1f) + 1)); + + break; + } + + 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 = getDDRPartNum(slot->spd, base, i); + slot->Vendor = getVendorName(slot, base, i); + slot->SerialNo = getDDRSerial(slot->spd); + + // determine spd speed + speed = getDDRspeedMhz(slot->spd); + 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, + spd_memory_types[spd_type], + slot->Frequency, + slot->Vendor, + slot->PartNo, + slot->SerialNo); + + + } + + // laptops sometimes show slot 0 and 2 with slot 1 empty when only 2 slots are presents so: + Platform->DMI.DIMM[i]= + i>0 && Platform->RAM.DIMM[1].InUse==false && fullBanks && Platform->DMI.CntMemorySlots == 2 ? + mapping[i] : i; // for laptops case, mapping setup would need to be more generic than this + + + + slot->spd = NULL; + + } // for +} + +static struct smbus_controllers_t smbus_controllers[] = { + + {0x8086, 0x269B, "ESB2", read_smb_intel }, + {0x8086, 0x25A4, "6300ESB", read_smb_intel }, + {0x8086, 0x24C3, "ICH4", read_smb_intel }, + {0x8086, 0x24D3, "ICH5", read_smb_intel }, + {0x8086, 0x266A, "ICH6", read_smb_intel }, + {0x8086, 0x27DA, "ICH7", read_smb_intel }, + {0x8086, 0x283E, "ICH8", read_smb_intel }, + {0x8086, 0x2930, "ICH9", read_smb_intel }, + {0x8086, 0x3A30, "ICH10R", read_smb_intel }, + {0x8086, 0x3A60, "ICH10B", read_smb_intel }, + {0x8086, 0x3B30, "5 Series", read_smb_intel }, + {0x8086, 0x1C22, "6 Series", read_smb_intel }, + {0x8086, 0x5032, "EP80579", read_smb_intel } + +}; + +// initial call : pci_dt = root_pci_dev; +// find_and_read_smbus_controller(root_pci_dev); +bool find_and_read_smbus_controller(pci_dt_t* pci_dt) +{ + pci_dt_t *current = pci_dt; + int i; + + while (current) { +#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, + get_pci_dev_path(current)); +#endif + for ( i = 0; i < sizeof(smbus_controllers) / sizeof(smbus_controllers[0]); i++ ) + { + if (current->vendor_id == smbus_controllers[i].vendor && + current->device_id == smbus_controllers[i].device) + { + smbus_controllers[i].read_smb(current); // read smb + return true; + } + } + find_and_read_smbus_controller(current->children); + current = current->next; + } + return false; // not found +} + +void scan_spd(PlatformInfo_t *p) +{ + find_and_read_smbus_controller(root_pci_dev); +} + Index: branches/slice/trunkM/i386/libsaio/libsaio.h =================================================================== --- branches/slice/trunkM/i386/libsaio/libsaio.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/libsaio.h (revision 1171) @@ -0,0 +1,35 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* libsaio.h */ + +#ifndef __LIBSAIO_LIBSAIO_H +#define __LIBSAIO_LIBSAIO_H + +#include "libsa.h" +#include "memory.h" +#include "io_inline.h" +#include "saio_types.h" +#include "saio_internal.h" + +#endif /* !__LIBSAIO_LIBSAIO_H */ Index: branches/slice/trunkM/i386/libsaio/acpi_patcher.h =================================================================== --- branches/slice/trunkM/i386/libsaio/acpi_patcher.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/acpi_patcher.h (revision 1171) @@ -0,0 +1,41 @@ +/* + * Copyright 2008 mackerintel + */ + +#ifndef __LIBSAIO_ACPI_PATCHER_H +#define __LIBSAIO_ACPI_PATCHER_H + +#include "libsaio.h" +//Slice - it's bullshit to define variables in header file +//uint64_t acpi10_p; +//uint64_t acpi20_p; +//uint64_t smbios_p; + +extern void *new_dsdt; +extern uint64_t smbios_p; + +extern int setupAcpi(); + +extern EFI_STATUS addConfigurationTable(); +//extern int search_and_get_acpi_fd(const char *, const char **); + +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/slice/trunkM/i386/libsaio/spd.h =================================================================== --- branches/slice/trunkM/i386/libsaio/spd.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/spd.h (revision 1171) @@ -0,0 +1,160 @@ +/* + * Copyright 2010 AsereBLN. All rights reserved. + * + * spd.h + */ + +#ifndef __LIBSAIO_SPD_H +#define __LIBSAIO_SPD_H + +#include "platform.h" +#include "libsaio.h" + +void scan_spd(PlatformInfo_t *p); + +struct smbus_controllers_t { + uint32_t vendor; + uint32_t device; + char *name; + void (*read_smb)(pci_dt_t *smbus_dev); +}; + + +/* + * Serial Presence Detect (SPD) data stored on SDRAM modules. + * + * Datasheet: + * - Name: PC SDRAM Serial Presence Detect (SPD) Specification + * Revision 1.2A, December, 1997 + * - PDF: http://www.intel.com/design/chipsets/memory/spdsd12a.pdf + * + * Datasheet (alternative): + * - Name: SERIAL PRESENCE DETECT STANDARD, General Standard + * JEDEC Standard No. 21-C + * - PDF: http://www.jedec.org/download/search/4_01_02_00R9.PDF + */ + + +/* Byte numbers. */ +#define SPD_NUM_MANUFACTURER_BYTES 0 /* Number of bytes used by module manufacturer */ +#define SPD_TOTAL_SPD_MEMORY_SIZE 1 /* Total SPD memory size */ +#define SPD_MEMORY_TYPE 2 /* (Fundamental) memory type */ +#define SPD_NUM_ROWS 3 /* Number of row address bits */ +#define SPD_NUM_COLUMNS 4 /* Number of column address bits */ +#define SPD_NUM_DIMM_BANKS 5 /* Number of module rows (banks) */ +#define SPD_MODULE_DATA_WIDTH_LSB 6 /* Module data width (LSB) */ +#define SPD_MODULE_DATA_WIDTH_MSB 7 /* Module data width (MSB) */ +#define SPD_MODULE_VOLTAGE 8 /* Module interface signal levels */ +#define SPD_MIN_CYCLE_TIME_AT_CAS_MAX 9 /* SDRAM cycle time (highest CAS latency), RAS access time (tRAC) */ +#define SPD_ACCESS_TIME_FROM_CLOCK 10 /* SDRAM access time from clock (highest CAS latency), CAS access time (Tac, tCAC) */ +#define SPD_DIMM_CONFIG_TYPE 11 /* Module configuration type */ +#define SPD_REFRESH 12 /* Refresh rate/type */ +#define SPD_PRIMARY_SDRAM_WIDTH 13 /* SDRAM width (primary SDRAM) */ +#define SPD_ERROR_CHECKING_SDRAM_WIDTH 14 /* Error checking SDRAM (data) width */ +#define SPD_MIN_CLOCK_DELAY_B2B_RAND_COLUMN 15 /* SDRAM device attributes, minimum clock delay for back to back random column */ +#define SPD_SUPPORTED_BURST_LENGTHS 16 /* SDRAM device attributes, burst lengths supported */ +#define SPD_NUM_BANKS_PER_SDRAM 17 /* SDRAM device attributes, number of banks on SDRAM device */ +#define SPD_ACCEPTABLE_CAS_LATENCIES 18 /* SDRAM device attributes, CAS latency */ +#define SPD_CS_LATENCY 19 /* SDRAM device attributes, CS latency */ +#define SPD_WE_LATENCY 20 /* SDRAM device attributes, WE latency */ +#define SPD_MODULE_ATTRIBUTES 21 /* SDRAM module attributes */ +#define SPD_DEVICE_ATTRIBUTES_GENERAL 22 /* SDRAM device attributes, general */ +#define SPD_SDRAM_CYCLE_TIME_2ND 23 /* SDRAM cycle time (2nd highest CAS latency) */ +#define SPD_ACCESS_TIME_FROM_CLOCK_2ND 24 /* SDRAM access from clock (2nd highest CAS latency) */ +#define SPD_SDRAM_CYCLE_TIME_3RD 25 /* SDRAM cycle time (3rd highest CAS latency) */ +#define SPD_ACCESS_TIME_FROM_CLOCK_3RD 26 /* SDRAM access from clock (3rd highest CAS latency) */ +#define SPD_MIN_ROW_PRECHARGE_TIME 27 /* Minimum row precharge time (Trp) */ +#define SPD_MIN_ROWACTIVE_TO_ROWACTIVE 28 /* Minimum row active to row active (Trrd) */ +#define SPD_MIN_RAS_TO_CAS_DELAY 29 /* Minimum RAS to CAS delay (Trcd) */ +#define SPD_MIN_ACTIVE_TO_PRECHARGE_DELAY 30 /* Minimum RAS pulse width (Tras) */ +#define SPD_DENSITY_OF_EACH_ROW_ON_MODULE 31 /* Density of each row on module */ +#define SPD_CMD_SIGNAL_INPUT_SETUP_TIME 32 /* Command and address signal input setup time */ +#define SPD_CMD_SIGNAL_INPUT_HOLD_TIME 33 /* Command and address signal input hold time */ +#define SPD_DATA_SIGNAL_INPUT_SETUP_TIME 34 /* Data signal input setup time */ +#define SPD_DATA_SIGNAL_INPUT_HOLD_TIME 35 /* Data signal input hold time */ +#define SPD_WRITE_RECOVERY_TIME 36 /* Write recovery time (tWR) */ +#define SPD_INT_WRITE_TO_READ_DELAY 37 /* Internal write to read command delay (tWTR) */ +#define SPD_INT_READ_TO_PRECHARGE_DELAY 38 /* Internal read to precharge command delay (tRTP) */ +#define SPD_MEM_ANALYSIS_PROBE_PARAMS 39 /* Memory analysis probe characteristics */ +#define SPD_BYTE_41_42_EXTENSION 40 /* Extension of byte 41 (tRC) and byte 42 (tRFC) */ +#define SPD_MIN_ACT_TO_ACT_AUTO_REFRESH 41 /* Minimum active to active auto refresh (tRCmin) */ +#define SPD_MIN_AUTO_REFRESH_TO_ACT 42 /* Minimum auto refresh to active/auto refresh (tRFC) */ +#define SPD_MAX_DEVICE_CYCLE_TIME 43 /* Maximum device cycle time (tCKmax) */ +#define SPD_MAX_DQS_DQ_SKEW 44 /* Maximum skew between DQS and DQ (tDQSQ) */ +#define SPD_MAX_READ_DATAHOLD_SKEW 45 /* Maximum read data-hold skew factor (tQHS) */ +#define SPD_PLL_RELOCK_TIME 46 /* PLL relock time */ +#define SPD_SPD_DATA_REVISION_CODE 62 /* SPD data revision code */ +#define SPD_CHECKSUM_FOR_BYTES_0_TO_62 63 /* Checksum for bytes 0-62 */ +#define SPD_MANUFACTURER_JEDEC_ID_CODE 64 /* Manufacturer's JEDEC ID code, per EIA/JEP106 (bytes 64-71) */ +#define SPD_MANUFACTURING_LOCATION 72 /* Manufacturing location */ +#define SPD_MANUFACTURER_PART_NUMBER 73 /* Manufacturer's part number, in 6-bit ASCII (bytes 73-90) */ +#define SPD_REVISION_CODE 91 /* Revision code (bytes 91-92) */ +#define SPD_MANUFACTURING_DATE 93 /* Manufacturing date (byte 93: year, byte 94: week) */ +#define SPD_ASSEMBLY_SERIAL_NUMBER 95 /* Assembly serial number (bytes 95-98) */ +#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 +#define SPD_tRRD SPD_MIN_ROWACTIVE_TO_ROWACTIVE +#define SPD_tRCD SPD_MIN_RAS_TO_CAS_DELAY +#define SPD_tRAS SPD_MIN_ACTIVE_TO_PRECHARGE_DELAY +#define SPD_BANK_DENSITY SPD_DENSITY_OF_EACH_ROW_ON_MODULE +#define SPD_ADDRESS_CMD_HOLD SPD_CMD_SIGNAL_INPUT_HOLD_TIME +#define SPD_tRC 41 /* SDRAM Device Minimum Active to Active/Auto Refresh Time (tRC) */ +#define SPD_tRFC 42 /* SDRAM Device Minimum Auto Refresh to Active/Auto Refresh (tRFC) */ + + +/* SPD_MEMORY_TYPE values. */ +#define SPD_MEMORY_TYPE_FPM_DRAM 1 +#define SPD_MEMORY_TYPE_EDO 2 +#define SPD_MEMORY_TYPE_PIPELINED_NIBBLE 3 +#define SPD_MEMORY_TYPE_SDRAM 4 +#define SPD_MEMORY_TYPE_MULTIPLEXED_ROM 5 +#define SPD_MEMORY_TYPE_SGRAM_DDR 6 +#define SPD_MEMORY_TYPE_SDRAM_DDR 7 +#define SPD_MEMORY_TYPE_SDRAM_DDR2 8 +#define SPD_MEMORY_TYPE_SDRAM_DDR3 0xb + +/* SPD_MODULE_VOLTAGE values. */ +#define SPD_VOLTAGE_TTL 0 /* 5.0 Volt/TTL */ +#define SPD_VOLTAGE_LVTTL 1 /* LVTTL */ +#define SPD_VOLTAGE_HSTL 2 /* HSTL 1.5 */ +#define SPD_VOLTAGE_SSTL3 3 /* SSTL 3.3 */ +#define SPD_VOLTAGE_SSTL2 4 /* SSTL 2.5 */ + +/* SPD_DIMM_CONFIG_TYPE values. */ +#define ERROR_SCHEME_NONE 0 +#define ERROR_SCHEME_PARITY 1 +#define ERROR_SCHEME_ECC 2 + +/* SPD_ACCEPTABLE_CAS_LATENCIES values. */ +// TODO: Check values. +#define SPD_CAS_LATENCY_1_0 0x01 +#define SPD_CAS_LATENCY_1_5 0x02 +#define SPD_CAS_LATENCY_2_0 0x04 +#define SPD_CAS_LATENCY_2_5 0x08 +#define SPD_CAS_LATENCY_3_0 0x10 +#define SPD_CAS_LATENCY_3_5 0x20 +#define SPD_CAS_LATENCY_4_0 0x40 + +#define SPD_CAS_LATENCY_DDR2_3 (1 << 3) +#define SPD_CAS_LATENCY_DDR2_4 (1 << 4) +#define SPD_CAS_LATENCY_DDR2_5 (1 << 5) +#define SPD_CAS_LATENCY_DDR2_6 (1 << 6) + +/* SPD_SUPPORTED_BURST_LENGTHS values. */ +#define SPD_BURST_LENGTH_1 1 +#define SPD_BURST_LENGTH_2 2 +#define SPD_BURST_LENGTH_4 4 +#define SPD_BURST_LENGTH_8 8 +#define SPD_BURST_LENGTH_PAGE (1 << 7) + +/* SPD_MODULE_ATTRIBUTES values. */ +#define MODULE_BUFFERED 1 +#define MODULE_REGISTERED 2 + +#endif /* !__LIBSAIO_SPD_H */ Index: branches/slice/trunkM/i386/libsaio/Makefile =================================================================== --- branches/slice/trunkM/i386/libsaio/Makefile (revision 0) +++ branches/slice/trunkM/i386/libsaio/Makefile (revision 1171) @@ -0,0 +1,61 @@ +SRCROOT = $(shell pwd)/../../ +OBJROOT = $(SRCROOT)/obj/i386/libsaio +SYMROOT = $(SRCROOT)/sym/i386 +DSTROOT = $(SRCROOT)/dst/i386 +DOCROOT = $(SRCROOT)/doc +IMGROOT = $(SRCROOT)/sym/cache +IMGSKELROOT = $(SRCROOT)/imgskel +CDBOOT = ${IMGROOT}/usr/standalone/i386/cdboot + +DIR = libsaio +include ${SRCROOT}/Make.rules + +UTILDIR = ../util +LIBSADIR = ../libsa +BOOT2DIR = ../boot2 + +DEFINES = -DNOTHING +#DEFINES = -DDEBUG_CPU=1 -DDEBUG_MEM=1 -DDEBUG_SPD=1 -DDEBUG_PCI=1 -DDEBUG_SMBIOS=1 + +CFLAGS := $(CFLAGS) $(RC_CFLAGS) $(MORECPP) -arch i386 \ + -D__ARCHITECTURE__=\"i386\" -DSAIO_INTERNAL_USER \ + -DRCZ_COMPRESSED_FILE_SUPPORT \ + -fno-builtin -static $(OMIT_FRAME_POINTER_CFLAG) \ + -mpreferred-stack-boundary=2 -fno-align-functions -fno-stack-protector \ + -march=pentium4 -msse2 -mfpmath=sse -msoft-float -nostdinc -include $(SRCROOT)/autoconf.h + +CPPFLAGS := $(CPPFLAGS) -nostdinc++ + +INC = -I. -I$(SYMROOT) -I$(LIBSADIR) -I$(BOOT2DIR) -I${SRCROOT}/i386/include + +SAIO_OBJS = table.o asm.o bios.o biosfn.o \ + disk.o sys.o cache.o bootstruct.o \ + stringTable.o load.o pci.o allocate.o misc.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 acpi_patcher.o \ + smbios.o smbios_getters.o smbios_decode.o \ + fake_efi.o ext2fs.o \ + hpet.o dram_controllers.o spd.o usb.o pci_setup.o \ + device_inject.o nvidia.o ati.o gma.o pci_root.o \ + convert.o aml_generator.o console.o + +LIBS = libsaio.a +LIBS := $(addprefix $(SYMROOT)/, $(LIBS)) + +DIRS_NEEDED = $(OBJROOT) $(SYMROOT) + + +all: $(DIRS_NEEDED) $(LIBS) + +$(LIBS): $(addprefix $(OBJROOT)/, $(SAIO_OBJS)) + @echo "\t[RM] $@" + @rm -f $@ + @echo "\t[AR] $(@F)" + @ar q $@ $^ &> /dev/null + @echo "\t[RANLIB] $(@F)" + @ranlib $(SYMROOT)/$(@F) + + +# dependencies +-include $(OBJROOT)/Makedep Index: branches/slice/trunkM/i386/libsaio/bios.h =================================================================== --- branches/slice/trunkM/i386/libsaio/bios.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/bios.h (revision 1171) @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright 1994 NeXT Computer, Inc. + * All rights reserved. + */ + +#ifndef __LIBSAIO_BIOS_H +#define __LIBSAIO_BIOS_H + +#include "bootargs.h" + +typedef union { + unsigned int rx; + unsigned short rr; + struct { + unsigned char l; + unsigned char h; + } r; +} machineRegister_t; + +typedef struct { + unsigned short cf :1; + unsigned short :1; + unsigned short pf :1; + unsigned short :1; + unsigned short af :1; + unsigned short :1; + unsigned short zf :1; + unsigned short sf :1; + unsigned short tf :1; + unsigned short _if :1; + unsigned short df :1; + unsigned short of :1; + unsigned short iopl:2; + unsigned short nt :1; +} machineFlags_t; + +typedef struct { + unsigned int intno; + machineRegister_t eax; + machineRegister_t ebx; + machineRegister_t ecx; + machineRegister_t edx; + machineRegister_t edi; + machineRegister_t esi; + machineRegister_t ebp; + unsigned short cs; + unsigned short ds; + unsigned short es; + machineFlags_t flags; +} biosBuf_t; + +#define EBIOS_FIXED_DISK_ACCESS 0x01 +#define EBIOS_LOCKING_ACCESS 0x02 +#define EBIOS_ENHANCED_DRIVE_INFO 0x04 + +#define BASE_HD_DRIVE 0x80 + +#if 0 +/* + * ACPI defined memory range types. + */ +enum { + kMemoryRangeUsable = 1, // RAM usable by the OS. + kMemoryRangeReserved = 2, // Reserved. (Do not use) + kMemoryRangeACPI = 3, // ACPI tables. Can be reclaimed. + kMemoryRangeNVS = 4, // ACPI NVS memory. (Do not use) + + /* Undefined types should be treated as kMemoryRangeReserved */ +}; +#endif + +/* + * Memory range descriptor. + */ +typedef struct MemoryRange { + unsigned long long base; // 64-bit base address + unsigned long long length; // 64-bit length in bytes + unsigned long type; // type of memory range + unsigned long reserved; +} MemoryRange; + +#endif /* !__LIBSAIO_BIOS_H */ Index: branches/slice/trunkM/i386/libsaio/SMBIOS.h =================================================================== --- branches/slice/trunkM/i386/libsaio/SMBIOS.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/SMBIOS.h (revision 1171) @@ -0,0 +1,478 @@ +/* + * Copyright (c) 1998-2009 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __LIBSAIO_SMBIOS_H +#define __LIBSAIO_SMBIOS_H + +// +// Based on System Management BIOS Reference Specification v2.5 +// + +typedef uint8_t SMBString; +typedef uint8_t SMBByte; +typedef uint16_t SMBWord; +typedef uint32_t SMBDWord; +typedef uint64_t SMBQWord; + + +typedef struct DMIEntryPoint { + SMBByte anchor[5]; + SMBByte checksum; + SMBWord tableLength; + SMBDWord tableAddress; + SMBWord structureCount; + SMBByte bcdRevision; +} __attribute__((packed)) DMIEntryPoint; + +typedef struct SMBEntryPoint { + SMBByte anchor[4]; + SMBByte checksum; + SMBByte entryPointLength; + SMBByte majorVersion; + SMBByte minorVersion; + SMBWord maxStructureSize; + SMBByte entryPointRevision; + SMBByte formattedArea[5]; + DMIEntryPoint dmi; +} __attribute__((packed)) SMBEntryPoint; + +// +// Header common to all SMBIOS structures +// + +typedef struct SMBStructHeader { + SMBByte type; + SMBByte length; + SMBWord handle; +} __attribute__((packed)) SMBStructHeader; + +#define SMB_STRUCT_HEADER SMBStructHeader header; + +typedef struct SMBAnchor +{ + const SMBStructHeader * header; + const uint8_t * next; + const uint8_t * end; +} SMBAnchor; + +#define SMB_ANCHOR_IS_VALID(x) \ + ((x) && ((x)->header) && ((x)->next) && ((x)->end)) + +#define SMB_ANCHOR_RESET(x) \ + bzero(x, sizeof(typedef struct SMBAnchor)); + +// +// SMBIOS structure types. +// + +enum { + kSMBTypeBIOSInformation = 0, + kSMBTypeSystemInformation = 1, + kSMBTypeBaseBoard = 2, + kSMBTypeSystemEnclosure = 3, + kSMBTypeProcessorInformation = 4, + kSMBTypeMemoryModule = 6, + kSMBTypeCacheInformation = 7, + kSMBTypeSystemSlot = 9, + kSMBTypePhysicalMemoryArray = 16, + kSMBTypeMemoryDevice = 17, + kSMBType32BitMemoryErrorInfo = 18, + kSMBType64BitMemoryErrorInfo = 33, + + kSMBTypeEndOfTable = 127, + + /* Apple Specific Structures */ + kSMBTypeFirmwareVolume = 128, + kSMBTypeMemorySPD = 130, + kSMBTypeOemProcessorType = 131, + kSMBTypeOemProcessorBusSpeed = 132 +}; + +// +// BIOS Information (Type 0) //min len 18+num_of_extChars. Max=18h=24 +// +typedef struct SMBBIOSInformation { + SMB_STRUCT_HEADER // Type 0 + SMBString vendor; // BIOS vendor name + SMBString version; // BIOS version + SMBWord startSegment; // BIOS segment start + SMBString releaseDate; // BIOS release date + SMBByte romSize; // (n); 64K * (n+1) bytes + SMBQWord characteristics; // supported BIOS functions + SMBByte extChars[2]; //BIOS Characteristics Extension Bytes +} __attribute__((packed)) SMBBIOSInformation; + +// +// System Information (Type 1) +// + +typedef struct SMBSystemInformation { + // 2.0+ spec (8 bytes) + SMB_STRUCT_HEADER // Type 1 + SMBString manufacturer; + SMBString productName; + SMBString version; + SMBString serialNumber; + // 2.1+ spec (25 bytes) + SMBByte uuid[16]; // can be all 0 or all 1's + SMBByte wakeupReason; // reason for system wakeup + // 2.4+ spec (27 bytes) + SMBString skuNumber; + SMBString family; +} __attribute__((packed)) SMBSystemInformation; + +// +// Base Board (Type 2) +// + +typedef struct SMBBaseBoard { + SMB_STRUCT_HEADER // Type 2 + SMBString manufacturer; + SMBString product; + SMBString version; + SMBString serialNumber; + SMBString assetTagNumber; + SMBByte featureFlags; + SMBString locationInChassis; + SMBWord chassisHandle; + SMBByte boardType; + SMBByte numberOfContainedHandles; + // 0 - 255 contained handles go here but we do not include + // them in our structure. Be careful to use numberOfContainedHandles + // times sizeof(SMBWord) when computing the actual record size, + // if you need it. +} __attribute__((packed)) SMBBaseBoard; + +// Values for boardType in Type 2 records +enum { + kSMBBaseBoardUnknown = 0x01, + kSMBBaseBoardOther = 0x02, + kSMBBaseBoardServerBlade = 0x03, + kSMBBaseBoardConnectivitySwitch = 0x04, + kSMBBaseBoardSystemMgmtModule = 0x05, + kSMBBaseBoardProcessorModule = 0x06, + kSMBBaseBoardIOModule = 0x07, + kSMBBaseBoardMemoryModule = 0x08, + kSMBBaseBoardDaughter = 0x09, + kSMBBaseBoardMotherboard = 0x0A, + kSMBBaseBoardProcessorMemoryModule = 0x0B, + kSMBBaseBoardProcessorIOModule = 0x0C, + kSMBBaseBoardInterconnect = 0x0D, +}; + + +// +// System Enclosure (Type 3) +// + +typedef struct SMBSystemEnclosure { + SMB_STRUCT_HEADER // Type 3 + SMBString manufacturer; + SMBByte type; + SMBString version; + SMBString serialNumber; + SMBString assetTagNumber; + SMBByte bootupState; + SMBByte powerSupplyState; + SMBByte thermalState; + SMBByte securityStatus; + SMBDWord oemDefined; +} __attribute__((packed)) SMBSystemEnclosure; + +// +// Processor Information (Type 4) +// + +typedef struct SMBProcessorInformation { + // 2.0+ spec (26 bytes) + SMB_STRUCT_HEADER // Type 4 + SMBString socketDesignation; + SMBByte processorType; // CPU = 3 + SMBByte processorFamily; // processor family enum + SMBString manufacturer; + SMBQWord processorID; // based on CPUID + SMBString processorVersion; + SMBByte voltage; // bit7 cleared indicate legacy mode + SMBWord externalClock; // external clock in MHz + SMBWord maximumClock; // max internal clock in MHz + SMBWord currentClock; // current internal clock in MHz + SMBByte status; + SMBByte processorUpgrade; // processor upgrade enum + // 2.1+ spec (32 bytes) + SMBWord L1CacheHandle; + SMBWord L2CacheHandle; + SMBWord L3CacheHandle; + // 2.3+ spec (35 bytes) + SMBString serialNumber; + SMBString assetTag; + SMBString partNumber; + // 2.5+ spec (38 bytes) + SMBByte coreCount; + SMBByte coreEnabled; + SMBByte Threads; +} __attribute__((packed)) SMBProcessorInformation; + +#define kSMBProcessorInformationMinSize 26 + +typedef struct SMBMemoryControllerInfo {/* 3.3.6 Memory Controller Information (Type 5) */ + SMB_STRUCT_HEADER + SMBByte errorDetectingMethod; + SMBByte errorCorrectingCapability; + SMBByte supportedInterleave; + SMBByte currentInterleave; + SMBByte maxMemoryModuleSize; + SMBWord supportedSpeeds; + SMBWord supportedMemoryTypes; + SMBByte memoryModuleVoltage; + SMBByte numberOfMemorySlots; +} __attribute__((packed)) SMBMemoryControllerInfo; + +// +// Memory Module Information (Type 6) +// Obsoleted since SMBIOS version 2.1 +// + +typedef struct SMBMemoryModule { + SMB_STRUCT_HEADER // Type 6 + SMBString socketDesignation; + SMBByte bankConnections; + SMBByte currentSpeed; + SMBWord currentMemoryType; + SMBByte installedSize; + SMBByte enabledSize; + SMBByte errorStatus; +} __attribute__((packed)) SMBMemoryModule; + +#define kSMBMemoryModuleSizeNotDeterminable 0x7D +#define kSMBMemoryModuleSizeNotEnabled 0x7E +#define kSMBMemoryModuleSizeNotInstalled 0x7F + +// +// Cache Information (Type 7) +// + +typedef struct SMBCacheInformation { + SMB_STRUCT_HEADER // Type 7 + SMBString socketDesignation; + SMBWord cacheConfiguration; + SMBWord maximumCacheSize; + SMBWord installedSize; + SMBWord supportedSRAMType; + SMBWord currentSRAMType; + SMBByte cacheSpeed; + SMBByte errorCorrectionType; + SMBByte systemCacheType; + SMBByte associativity; +} __attribute__((packed)) SMBCacheInformation; + +typedef struct SMBSystemSlot { + // 2.0+ spec (12 bytes) + SMB_STRUCT_HEADER // Type 9 + SMBString slotDesignation; + SMBByte slotType; + SMBByte slotDataBusWidth; + SMBByte currentUsage; + SMBByte slotLength; + SMBWord slotID; + SMBByte slotCharacteristics1; + // 2.1+ spec (13 bytes) + SMBByte slotCharacteristics2; +} __attribute__((packed)) SMBSystemSlot; + +// +// Physical Memory Array (Type 16) +// + +typedef struct SMBPhysicalMemoryArray { + // 2.1+ spec (15 bytes) + SMB_STRUCT_HEADER // Type 16 + SMBByte physicalLocation; // physical location + SMBByte arrayUse; // the use for the memory array + SMBByte errorCorrection; // error correction/detection method + SMBDWord maximumCapacity; // maximum memory capacity in kilobytes + SMBWord errorHandle; // handle of a previously detected error + SMBWord numMemoryDevices; // number of memory slots or sockets +} __attribute__((packed)) SMBPhysicalMemoryArray; + +// Memory Array - Use +enum { + kSMBMemoryArrayUseOther = 0x01, + kSMBMemoryArrayUseUnknown = 0x02, + kSMBMemoryArrayUseSystemMemory = 0x03, + kSMBMemoryArrayUseVideoMemory = 0x04, + kSMBMemoryArrayUseFlashMemory = 0x05, + kSMBMemoryArrayUseNonVolatileMemory = 0x06, + kSMBMemoryArrayUseCacheMemory = 0x07 +}; + +// Memory Array - Error Correction Types +enum { + kSMBMemoryArrayErrorCorrectionTypeOther = 0x01, + kSMBMemoryArrayErrorCorrectionTypeUnknown = 0x02, + kSMBMemoryArrayErrorCorrectionTypeNone = 0x03, + kSMBMemoryArrayErrorCorrectionTypeParity = 0x04, + kSMBMemoryArrayErrorCorrectionTypeSingleBitECC = 0x05, + kSMBMemoryArrayErrorCorrectionTypeMultiBitECC = 0x06, + kSMBMemoryArrayErrorCorrectionTypeCRC = 0x07 +}; + +// +// Memory Device (Type 17) +// + +typedef struct SMBMemoryDevice { + // 2.1+ spec (21 bytes) + SMB_STRUCT_HEADER // Type 17 + SMBWord arrayHandle; // handle of the parent memory array + SMBWord errorHandle; // handle of a previously detected error + SMBWord totalWidth; // total width in bits; including ECC bits + SMBWord dataWidth; // data width in bits + SMBWord memorySize; // bit15 is scale, 0 = MB, 1 = KB + SMBByte formFactor; // memory device form factor + SMBByte deviceSet; // parent set of identical memory devices + SMBString deviceLocator; // labeled socket; e.g. "SIMM 3" + SMBString bankLocator; // labeled bank; e.g. "Bank 0" or "A" + SMBByte memoryType; // type of memory + SMBWord memoryTypeDetail; // additional detail on memory type + // 2.3+ spec (27 bytes) + SMBWord memorySpeed; // speed of device in MHz (0 for unknown) + SMBString manufacturer; + SMBString serialNumber; + SMBString assetTag; + SMBString partNumber; +} __attribute__((packed)) SMBMemoryDevice; + +// +// Firmware Volume Description (Apple Specific - Type 128) +// + +enum { + FW_REGION_RESERVED = 0, + FW_REGION_RECOVERY = 1, + FW_REGION_MAIN = 2, + FW_REGION_NVRAM = 3, + FW_REGION_CONFIG = 4, + FW_REGION_DIAGVAULT = 5, + + NUM_FLASHMAP_ENTRIES = 8 +}; + +typedef struct FW_REGION_INFO +{ + SMBDWord StartAddress; + SMBDWord EndAddress; +} __attribute__((packed)) FW_REGION_INFO; + +typedef struct SMBFirmwareVolume { + SMB_STRUCT_HEADER // Type 128 + SMBByte RegionCount; + SMBByte Reserved[3]; + SMBDWord FirmwareFeatures; + SMBDWord FirmwareFeaturesMask; + SMBByte RegionType[ NUM_FLASHMAP_ENTRIES ]; + FW_REGION_INFO FlashMap[ NUM_FLASHMAP_ENTRIES ]; +} __attribute__((packed)) SMBFirmwareVolume; + +// +// Memory SPD Data (Apple Specific - Type 130) +// + +typedef struct SMBMemorySPD { + SMB_STRUCT_HEADER // Type 130 + SMBWord Type17Handle; + SMBWord Offset; + SMBWord Size; + SMBWord Data[]; +} __attribute__((packed)) SMBMemorySPD; + +static const char * +SMBMemoryDeviceTypes[] = +{ + "RAM", /* 00h Undefined */ + "RAM", /* 01h Other */ + "RAM", /* 02h Unknown */ + "DRAM", /* 03h DRAM */ + "EDRAM", /* 04h EDRAM */ + "VRAM", /* 05h VRAM */ + "SRAM", /* 06h SRAM */ + "RAM", /* 07h RAM */ + "ROM", /* 08h ROM */ + "FLASH", /* 09h FLASH */ + "EEPROM", /* 0Ah EEPROM */ + "FEPROM", /* 0Bh FEPROM */ + "EPROM", /* 0Ch EPROM */ + "CDRAM", /* 0Dh CDRAM */ + "3DRAM", /* 0Eh 3DRAM */ + "SDRAM", /* 0Fh SDRAM */ + "SGRAM", /* 10h SGRAM */ + "RDRAM", /* 11h RDRAM */ + "DDR SDRAM", /* 12h DDR */ + "DDR2 SDRAM", /* 13h DDR2 */ + "DDR2 FB-DIMM", /* 14h DDR2 FB-DIMM */ + "RAM", /* 15h unused */ + "RAM", /* 16h unused */ + "RAM", /* 17h unused */ + "DDR3", /* 18h DDR3, chosen in [5776134] */ +}; + +static const int +kSMBMemoryDeviceTypeCount = sizeof(SMBMemoryDeviceTypes) / + sizeof(SMBMemoryDeviceTypes[0]); + +// +// OEM Processor Type (Apple Specific - Type 131) +// + +typedef struct SMBOemProcessorType { + SMB_STRUCT_HEADER + SMBWord ProcessorType; +} __attribute__((packed)) SMBOemProcessorType; + +// +// OEM Processor Bus Speed (Apple Specific - Type 132) +// +typedef struct SMBOemProcessorBusSpeed { + SMB_STRUCT_HEADER + SMBWord ProcessorBusSpeed; // MT/s unit +} __attribute__((packed)) SMBOemProcessorBusSpeed; + +//---------------------------------------------------------------------------------------------------------- + +/* From Foundation/Efi/Guid/Smbios/SmBios.h */ +/* Modified to wrap Data4 array init with {} */ +#define EFI_SMBIOS_TABLE_GUID {0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}} + +#define SMBIOS_ORIGINAL 0 +#define SMBIOS_PATCHED 1 + +extern void *getSmbios(int which); +extern void readSMBIOSInfo(SMBEntryPoint *eps); +extern void setupSMBIOSTable(void); + +extern void decodeSMBIOSTable(SMBEntryPoint *eps); +extern char MacModel[8]; +extern unsigned int ModelRev; +extern uint64_t smbios_p; + + + +#endif /* !__LIBSAIO_SMBIOS_H */ Index: branches/slice/trunkM/i386/libsaio/ufs.h =================================================================== --- branches/slice/trunkM/i386/libsaio/ufs.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/ufs.h (revision 1171) @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 2.0 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +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 long * dirIndex, + char ** name, long * flags, long * time, + FinderInfo * finderInfo, long * infoValid); +extern void UFSGetDescription(CICell ih, char *str, long strMaxLen); +extern long UFSGetFileBlock(CICell ih, char *str, unsigned long long *firstBlock); +extern long UFSGetUUID(CICell ih, char *uuidStr); +extern void UFSFree(CICell ih); + Index: branches/slice/trunkM/i386/libsaio/gma.c =================================================================== --- branches/slice/trunkM/i386/libsaio/gma.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/gma.c (revision 1171) @@ -0,0 +1,171 @@ +/* + Original patch by Nawcom + http://forum.voodooprojects.org/index.php/topic,1029.0.html +*/ + +#include "libsa.h" +#include "saio_internal.h" +#include "bootstruct.h" +#include "pci.h" +#include "platform.h" +#include "device_inject.h" +#include "gma.h" + +#ifndef DEBUG_GMA +#define DEBUG_GMA 0 +#endif + +#if DEBUG_GMA +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif + + +uint8_t GMAX3100_vals[22][4] = { + { 0x01,0x00,0x00,0x00 }, + { 0x01,0x00,0x00,0x00 }, + { 0x01,0x00,0x00,0x00 }, + { 0x00,0x00,0x00,0x08 }, + { 0x64,0x00,0x00,0x00 }, + { 0x00,0x00,0x00,0x08 }, + { 0x01,0x00,0x00,0x00 }, + { 0x20,0x00,0x00,0x00 }, + { 0x00,0x00,0x00,0x00 }, + { 0x01,0x00,0x00,0x00 }, + { 0x20,0x03,0x00,0x00 }, + { 0x00,0x00,0x00,0x00 }, + { 0x00,0x00,0x00,0x00 }, + { 0x00,0x00,0x00,0x00 }, + { 0x08,0x52,0x00,0x00 }, + { 0x00,0x00,0x00,0x00 }, + { 0x00,0x00,0x00,0x00 }, + { 0x01,0x00,0x00,0x00 }, + { 0x01,0x00,0x00,0x00 }, + { 0x3B,0x00,0x00,0x00 }, + { 0x00,0x00,0x00,0x00 } +}; + +uint8_t reg_TRUE[] = { 0x01, 0x00, 0x00, 0x00 }; +uint8_t reg_FALSE[] = { 0x00, 0x00, 0x00, 0x00 }; + +static struct gma_gpu_t KnownGPUS[] = { + { 0x00000000, "Unknown" }, + { 0x808627A2, "Mobile GMA950" }, + { 0x808627AE, "Mobile GMA950" }, + { 0x808627A6, "Mobile GMA950" }, + { 0x8086A011, "Mobile GMA3150" }, + { 0x8086A012, "Mobile GMA3150" }, + { 0x80862772, "Desktop GMA950" }, + { 0x80862776, "Desktop GMA950" }, +// { 0x8086A001, "Desktop GMA3150" }, + { 0x8086A001, "Mobile GMA3150" }, + { 0x8086A002, "Desktop GMA3150" }, + { 0x80862A02, "GMAX3100" }, + { 0x80862A03, "GMAX3100" }, + { 0x80862A12, "GMAX3100" }, + { 0x80862A13, "GMAX3100" }, + { 0x80862A42, "GMAX3100" }, + { 0x80862A43, "GMAX3100" }, +}; + +char *get_gma_model(uint32_t id) { + int i = 0; + + for (i = 0; i < (sizeof(KnownGPUS) / sizeof(KnownGPUS[0])); i++) + { + if (KnownGPUS[i].device == id) + return KnownGPUS[i].name; + } + return KnownGPUS[0].name; +} + +bool setup_gma_devprop(pci_dt_t *gma_dev) +{ + char *devicepath; + volatile uint8_t *regs; + uint32_t bar[7]; + char *model; + uint8_t BuiltIn = 0x00; + uint8_t ClassFix[4] = { 0x00, 0x00, 0x03, 0x00 }; + + devicepath = get_pci_dev_path(gma_dev); + + bar[0] = pci_config_read32(gma_dev->dev.addr, 0x10); + regs = (uint8_t *) (bar[0] & ~0x0f); + + model = get_gma_model((gma_dev->vendor_id << 16) | gma_dev->device_id); + + verbose("Intel %s [%04x:%04x] :: %s\n", + model, gma_dev->vendor_id, gma_dev->device_id, devicepath); + + if (!string) + string = devprop_create_string(); + + struct DevPropDevice *device = malloc(sizeof(struct DevPropDevice)); + device = devprop_add_device(string, devicepath); + + if (!device) + { + printf("Failed initializing dev-prop string dev-entry.\n"); + pause(); + return false; + } + + devprop_add_value(device, "model", (uint8_t*)model, (strlen(model) + 1)); + devprop_add_value(device, "device_type", (uint8_t*)"display", 8); + + if ((model == (char *)"Mobile GMA950") + || (model == (char *)"Mobile GMA3150")) + { + devprop_add_value(device, "AAPL,HasPanel", reg_TRUE, 4); + devprop_add_value(device, "built-in", &BuiltIn, 1); + devprop_add_value(device, "class-code", ClassFix, 4); + } + else if ((model == (char *)"Desktop GMA950") + || (model == (char *)"Desktop GMA3150")) + { + BuiltIn = 0x01; + devprop_add_value(device, "built-in", &BuiltIn, 1); + devprop_add_value(device, "class-code", ClassFix, 4); + } + else if (model == (char *)"GMAX3100") + { + devprop_add_value(device, "AAPL,HasPanel", GMAX3100_vals[0], 4); + devprop_add_value(device, "AAPL,SelfRefreshSupported", GMAX3100_vals[1], 4); + devprop_add_value(device, "AAPL,aux-power-connected", GMAX3100_vals[2], 4); + devprop_add_value(device, "AAPL,backlight-control", GMAX3100_vals[3], 4); + devprop_add_value(device, "AAPL00,blackscreen-preferences", GMAX3100_vals[4], 4); + devprop_add_value(device, "AAPL01,BacklightIntensity", GMAX3100_vals[5], 4); + devprop_add_value(device, "AAPL01,blackscreen-preferences", GMAX3100_vals[6], 4); + devprop_add_value(device, "AAPL01,DataJustify", GMAX3100_vals[7], 4); + devprop_add_value(device, "AAPL01,Depth", GMAX3100_vals[8], 4); + devprop_add_value(device, "AAPL01,Dither", GMAX3100_vals[9], 4); + devprop_add_value(device, "AAPL01,DualLink", GMAX3100_vals[10], 4); + devprop_add_value(device, "AAPL01,Height", GMAX3100_vals[11], 4); + devprop_add_value(device, "AAPL01,Interlace", GMAX3100_vals[12], 4); + devprop_add_value(device, "AAPL01,Inverter", GMAX3100_vals[13], 4); + devprop_add_value(device, "AAPL01,InverterCurrent", GMAX3100_vals[14], 4); + devprop_add_value(device, "AAPL01,InverterCurrency", GMAX3100_vals[15], 4); + devprop_add_value(device, "AAPL01,LinkFormat", GMAX3100_vals[16], 4); + devprop_add_value(device, "AAPL01,LinkType", GMAX3100_vals[17], 4); + devprop_add_value(device, "AAPL01,Pipe", GMAX3100_vals[18], 4); + devprop_add_value(device, "AAPL01,PixelFormat", GMAX3100_vals[19], 4); + devprop_add_value(device, "AAPL01,Refresh", GMAX3100_vals[20], 4); + devprop_add_value(device, "AAPL01,Stretch", GMAX3100_vals[21], 4); + devprop_add_value(device, "class-code", ClassFix, 4); + } + + stringdata = malloc(sizeof(uint8_t) * string->length); + if (!stringdata) + { + printf("No stringdata.\n"); + pause(); + return false; + } + + memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length); + stringlength = string->length; + + return true; +} Index: branches/slice/trunkM/i386/libsaio/nbp_cmd.h =================================================================== --- branches/slice/trunkM/i386/libsaio/nbp_cmd.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/nbp_cmd.h (revision 1171) @@ -0,0 +1,85 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __LIBSAIO_NBP_CMD_H +#define __LIBSAIO_NBP_CMD_H + +#include + +/*========================================================================== + * NBP return status codes. + */ +typedef enum { + nbpStatusSuccess = 0, + nbpStatusFailed, + nbpStatusInvalid, +} nbpStatus_t; + +/*========================================================================== + * NBP commands codes. + */ +typedef enum { + nbpCommandTFTPReadFile = 1, + nbpCommandTFTPGetFileSize, + nbpCommandUnloadBaseCode, +} nbpCommandCode_t; + +/*========================================================================== + * NBP commands. + */ +typedef struct { + UInt32 status; /* return code from NBP */ +} nbpCommandHeader_s; + +typedef struct { + UInt32 status; /* return code from NBP */ + UInt8 filename[128]; /* name of file to be downloaded */ + UInt32 bufferSize; /* size of the download buffer */ + UInt32 buffer; /* physical address of the download buffer */ +} nbpCommandTFTPReadFile_s; + +typedef struct { + UInt32 status; /* return code from NBP */ + UInt8 filename[128]; /* name of file to be downloaded */ + UInt32 filesize; /* size of the file specified */ +} nbpCommandTFTPGetFileSize_s; + +typedef struct { + UInt32 status; /* return code from NBP */ + UInt8 sname[64]; /* server name */ + UInt32 CIP; /* client IP address */ + UInt32 SIP; /* server IP address */ + UInt32 GIP; /* gateway IP address */ +} nbpCommandGetNetworkInfo_s; + +/*========================================================================== + * An union of all NBP command structures. + */ +typedef union { + nbpCommandHeader_s header; + nbpCommandTFTPReadFile_s tftpReadFile; + nbpCommandTFTPGetFileSize_s tftpFileSize; +} nbpCommand_u; + +#endif /* !__LIBSAIO_NBP_CMD_H */ Index: branches/slice/trunkM/i386/libsaio/gma.h =================================================================== --- branches/slice/trunkM/i386/libsaio/gma.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/gma.h (revision 1171) @@ -0,0 +1,16 @@ +#ifndef __LIBSAIO_GMA_H +#define __LIBSAIO_GMA_H + +bool setup_gma_devprop(pci_dt_t *gma_dev); + +struct gma_gpu_t { + unsigned device; + char *name; +}; + +#define REG8(reg) ((volatile uint8_t *)regs)[(reg)] +#define REG16(reg) ((volatile uint16_t *)regs)[(reg) >> 1] +#define REG32(reg) ((volatile uint32_t *)regs)[(reg) >> 2] + + +#endif /* !__LIBSAIO_GMA_H */ Index: branches/slice/trunkM/i386/libsaio/bios.s =================================================================== --- branches/slice/trunkM/i386/libsaio/bios.s (revision 0) +++ branches/slice/trunkM/i386/libsaio/bios.s (revision 1171) @@ -0,0 +1,184 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright 1993 NeXT Computer, Inc. + * All rights reserved. + * + * Harness for calling real-mode BIOS functions. + */ + +/* Copyright 2007 David Elliott + 2007-12-30 dfe + - Enhanced code to use specified DS register when doing BIOS interrupt + - Fixed movl %ax,new_es bug which assembler was interpreting as + movl %eax,new_es which was overwriting the next word. + */ +#include +#include "memory.h" + +#define data32 .byte 0x66 +#define addr32 .byte 0x67 + +#define O_INT 0 +#define O_EAX 4 +#define O_EBX 8 +#define O_ECX 12 +#define O_EDX 16 +#define O_EDI 20 +#define O_ESI 24 +#define O_EBP 28 +#define O_CS 32 +#define O_DS 34 +#define O_ES 36 +#define O_FLG 38 + + .section __INIT,__data // turbo - Data that must be in the first segment + +/* Saved registers: + These used to be (and in theory ought to be) located in __DATA,__bss. + The problem is that the larger the binary grows, more of the BSS gets + pushed into the next real-mode segment. Doing it this way we waste 24 + bytes in the binary that our loader (e.g. boot1) must now load. But the + advantage is that we relocate this data to ensure it stays in the first + real-mode segment. Therefore, depending on link order, quite a lot of + new data, and possibly a lot of new executable code can be added to the + binary since with this change the BSS and most of the DATA is now only + accessed from protected mode where real-mode segment limits don't apply. + + With this change, plus the earlier change to respect DS (e.g. use huge + pointers), the binary can grow much larger, currently up to exactly 63.5k + which is the maximum that the first-stage bootsectors can handle. To get + more than that more changes are needed. In that case we would have to + play with Mach-O segments to ensure real-mode code and data got stuffed + well within the first 63.5k. Furthermore, we'd have to adjust the boot + sectors to allow them to span segments. + + Since this change alone only gains us about 4k more than where we're at + now (which is not anything to scoff at) it won't be very long before we + need to start using Mach-O segments to force the linker to locate certain + bits of code and data within the first 63.5k and modify the loaders to + be able to load more than 63.5k. + */ + .align 2 +save_eax: .space 4 + .align 2 +save_edx: .space 4 + .align 1 +save_es: .space 2 + .align 1 +save_flag: .space 2 + .align 2 +new_eax: .space 4 + .align 2 +new_edx: .space 4 + .align 1 +new_es: .space 2 + .align 1 +new_ds: .space 2 + + .section __INIT,__text // turbo - This code must reside within the first segment + + +/*============================================================================ + * Call real-mode BIOS INT functions. + * + */ +LABEL(_bios) + enter $0, $0 + pushal + + movl 8(%ebp), %edx // address of save area + movb O_INT(%edx), %al // save int number + movb %al, do_int+1 + + movl O_EBX(%edx), %ebx + movl O_ECX(%edx), %ecx + movl O_EDI(%edx), %edi + movl O_ESI(%edx), %esi + movl O_EBP(%edx), %ebp + movl %edx, save_edx + movl O_EAX(%edx), %eax + movl %eax, new_eax + movl O_EDX(%edx), %eax + movl %eax, new_edx + movw O_ES(%edx), %ax + movw %ax, new_es + movw O_DS(%edx), %ax + movw %ax, new_ds + + call __prot_to_real + + data32 + addr32 + mov OFFSET16(new_eax), %eax + data32 + addr32 + mov OFFSET16(new_edx), %edx + data32 + addr32 + mov OFFSET16(new_es), %es + + push %ds // Save DS + // Replace DS. WARNING: Don't access data until it's restored! + addr32 + data32 + mov OFFSET16(new_ds), %ds + +do_int: + int $0x00 + pop %ds // Restore DS before we do anything else + + pushf + data32 + addr32 + movl %eax, OFFSET16(save_eax) + popl %eax // actually pop %ax + addr32 + movl %eax, OFFSET16(save_flag) // actually movw + mov %es, %ax + addr32 + movl %eax, OFFSET16(save_es) // actually movw + data32 + call __real_to_prot + + movl %edx, new_edx // save new edx before clobbering + movl save_edx, %edx + movl new_edx, %eax // now move it into buffer + movl %eax, O_EDX(%edx) + movl save_eax, %eax + movl %eax, O_EAX(%edx) + movw save_es, %ax + movw %ax, O_ES(%edx) + movw save_flag, %ax + movw %ax, O_FLG(%edx) + movl %ebx, O_EBX(%edx) + movl %ecx, O_ECX(%edx) + movl %edi, O_EDI(%edx) + movl %esi, O_ESI(%edx) + movl %ebp, O_EBP(%edx) + + popal + leave + + ret Index: branches/slice/trunkM/i386/libsaio/pci_root.c =================================================================== --- branches/slice/trunkM/i386/libsaio/pci_root.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/pci_root.c (revision 1171) @@ -0,0 +1,115 @@ +/* + * Copyright 2009 netkas + */ + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" + +#ifndef DEBUG_PCIROOT +#define DEBUG_PCIROOT 0 +#endif + +#if DEBUG_PCIROOT +#define DBG(x...) verbose(x) +#else +#define DBG(x...) msglog(x) +#endif + +static int rootuid = 10; //value means function wasnt ran yet +#if NOTYET //it present in ACPIPatcher +static unsigned int findrootuid(unsigned char * dsdt, int len) +{ + int i; + for (i=0; i<64 && ichameleonConfig)) { + if (isdigit(val[0])) rootuid = val[0] - '0'; + goto out; + } + /* Chameleon compatibility */ + else if (getValueForKey("PciRoot", &val, &len, &bootInfo->chameleonConfig)) { + if (isdigit(val[0])) rootuid = val[0] - '0'; + goto out; + } + /* PCEFI compatibility */ + else if (getValueForKey("-pci0", &val, &len, &bootInfo->chameleonConfig)) { + rootuid = 0; + goto out; + } + else if (getValueForKey("-pci1", &val, &len, &bootInfo->chameleonConfig)) { + rootuid = 1; + goto out; + } +//Slice - as in Meklort +#if NOTNOW + int fd = search_and_get_acpi_fd("DSDT.aml", &dsdt_filename); + + // Check booting partition + if (fd<0) + { + verbose("No DSDT found, using 0 as uid value.\n"); + rootuid = 0; + goto out; + } + + fsize = file_size(fd); + + if ((new_dsdt = malloc(fsize)) == NULL) { + verbose("[ERROR] alloc DSDT memory failed\n"); + close (fd); + goto out; + } + if (read (fd, new_dsdt, fsize) != fsize) { + verbose("[ERROR] read %s failed\n", dsdt_filename); + close (fd); + goto out; + } + close (fd); + + rootuid = findpciroot(new_dsdt, fsize); + free(new_dsdt); + + // make sure it really works: + if (rootuid == 11) rootuid=0; //usually when _UID isnt present, it means uid is zero + else if (rootuid < 0 || rootuid > 9) + { + verbose("PciRoot uid value wasnt found, using 0, if you want it to be 1, use -PciRootUID flag"); + rootuid = 0; + } +#endif +out: + verbose("Using PCI-Root-UID value: %d\n", rootuid); + return rootuid; +} Index: branches/slice/trunkM/i386/libsaio/aml_generator.c =================================================================== --- branches/slice/trunkM/i386/libsaio/aml_generator.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/aml_generator.c (revision 1171) @@ -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 doesn't support child nodes!\n"); + return false; + case AML_CHUNK_NAME: + if (parent->First) + { + verbose("aml_add_to_parent: name node supports only one child node!\n"); + 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.\n", 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...\n", 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/slice/trunkM/i386/libsaio/pci_root.h =================================================================== --- branches/slice/trunkM/i386/libsaio/pci_root.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/pci_root.h (revision 1171) @@ -0,0 +1,13 @@ +/* + * Copyright 2008 mackerintel + */ + +#ifndef __LIBSAIO_PCI_ROOT_H +#define __LIBSAIO_PCI_ROOT_H + +#include "libsaio.h" + + +extern int getPciRootUID(void); + +#endif /* !__LIBSAIO_DSDT_PATCHER_H */ Index: branches/slice/trunkM/i386/libsaio/aml_generator.h =================================================================== --- branches/slice/trunkM/i386/libsaio/aml_generator.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/aml_generator.h (revision 1171) @@ -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/slice/trunkM/i386/libsaio/memvendors.h =================================================================== --- branches/slice/trunkM/i386/libsaio/memvendors.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/memvendors.h (revision 1171) @@ -0,0 +1,894 @@ +/* + * Memory module vendors as published by JEDEC 106AA + * + * Special thanks to indi, memtest and theking for the table + * + */ +#ifndef __MEMVEN_H +#define __MEMVEN_H + +typedef struct _vidTag { + uint8_t bank; + uint8_t code; + const char* name; +} VenIdName; + +VenIdName vendorMap[] = { + { 0, 0x01, "AMD"}, + { 0, 0x02, "AMI"}, + { 0, 0x83, "Fairchild"}, + { 0, 0x04, "Fujitsu"}, + { 0, 0x85, "GTE"}, + { 0, 0x86, "Harris"}, + { 0, 0x07, "Hitachi"}, + { 0, 0x08, "Inmos"}, + { 0, 0x89, "Intel"}, + { 0, 0x8a, "I.T.T."}, + { 0, 0x0b, "Intersil"}, + { 0, 0x8c, "Monolithic Memories"}, + { 0, 0x0d, "Mostek"}, + { 0, 0x0e, "Freescale (Motorola)"}, + { 0, 0x8f, "National"}, + { 0, 0x10, "NEC"}, + { 0, 0x91, "RCA"}, + { 0, 0x92, "Raytheon"}, + { 0, 0x13, "Conexant (Rockwell)"}, + { 0, 0x94, "Seeq"}, + { 0, 0x15, "NXP (Philips)"}, + { 0, 0x16, "Synertek"}, + { 0, 0x97, "Texas Instruments"}, + { 0, 0x98, "Toshiba"}, + { 0, 0x19, "Xicor"}, + { 0, 0x1a, "Zilog"}, + { 0, 0x9b, "Eurotechnique"}, + { 0, 0x1c, "Mitsubishi"}, + { 0, 0x9d, "Lucent (AT&T)"}, + { 0, 0x9e, "Exel"}, + { 0, 0x1f, "Atmel"}, + { 0, 0x20, "SGS/Thomson"}, + { 0, 0xa1, "Lattice Semi."}, + { 0, 0xa2, "NCR"}, + { 0, 0x23, "Wafer Scale Integration"}, + { 0, 0xa4, "IBM"}, + { 0, 0x25, "Tristar"}, + { 0, 0x26, "Visic"}, + { 0, 0xa7, "Intl. CMOS Technology"}, + { 0, 0xa8, "SSSI"}, + { 0, 0x29, "MicrochipTechnology"}, + { 0, 0x2a, "Ricoh"}, + { 0, 0xab, "VLSI"}, + { 0, 0x2c, "Micron Technology"}, + { 0, 0xad, "Hynix Semiconductor"}, + { 0, 0xae, "OKI Semiconductor"}, + { 0, 0x2f, "ACTEL"}, + { 0, 0xb0, "Sharp"}, + { 0, 0x31, "Catalyst"}, + { 0, 0x32, "Panasonic"}, + { 0, 0xb3, "IDT"}, + { 0, 0x34, "Cypress"}, + { 0, 0xb5, "DEC"}, + { 0, 0xb6, "LSI Logic"}, + { 0, 0x37, "Zarlink (Plessey)"}, + { 0, 0x38, "UTMC"}, + { 0, 0xb9, "Thinking Machine"}, + { 0, 0xba, "Thomson CSF"}, + { 0, 0x3b, "Integrated CMOS (Vertex)"}, + { 0, 0xbc, "Honeywell"}, + { 0, 0x3d, "Tektronix"}, + { 0, 0x3e, "Sun Microsystems"}, + { 0, 0xbf, "SST"}, + { 0, 0x40, "ProMos/Mosel Vitelic"}, + { 0, 0xc1, "Infineon (Siemens)"}, + { 0, 0xc2, "Macronix"}, + { 0, 0x43, "Xerox"}, + { 0, 0xc4, "Plus Logic"}, + { 0, 0x45, "SanDisk"}, + { 0, 0x46, "Elan Circuit Tech."}, + { 0, 0xc7, "European Silicon Str."}, + { 0, 0xc8, "Apple Computer"}, + { 0, 0x49, "Xilinx"}, + { 0, 0x4a, "Compaq"}, + { 0, 0xcb, "Protocol Engines"}, + { 0, 0x4c, "SCI"}, + { 0, 0xcd, "Seiko Instruments"}, + { 0, 0xce, "Samsung"}, + { 0, 0x4f, "I3 Design System"}, + { 0, 0xd0, "Klic"}, + { 0, 0x51, "Crosspoint Solutions"}, + { 0, 0x52, "Alliance Semiconductor"}, + { 0, 0xd3, "Tandem"}, + { 0, 0x54, "Hewlett-Packard"}, + { 0, 0xd5, "Intg. Silicon Solutions"}, + { 0, 0xd6, "Brooktree"}, + { 0, 0x57, "New Media"}, + { 0, 0x58, "MHS Electronic"}, + { 0, 0xd9, "Performance Semi."}, + { 0, 0xda, "Winbond Electronic"}, + { 0, 0x5b, "Kawasaki Steel"}, + { 0, 0xdc, "Bright Micro"}, + { 0, 0x5d, "TECMAR"}, + { 0, 0x5e, "Exar"}, + { 0, 0xdf, "PCMCIA"}, + { 0, 0xe0, "LG Semi (Goldstar)"}, + { 0, 0x61, "Northern Telecom"}, + { 0, 0x62, "Sanyo"}, + { 0, 0xe3, "Array Microsystems"}, + { 0, 0x64, "Crystal Semiconductor"}, + { 0, 0xe5, "Analog Devices"}, + { 0, 0xe6, "PMC-Sierra"}, + { 0, 0x67, "Asparix"}, + { 0, 0x68, "Convex Computer"}, + { 0, 0xe9, "Quality Semiconductor"}, + { 0, 0xea, "Nimbus Technology"}, + { 0, 0x6b, "Transwitch"}, + { 0, 0xec, "Micronas (ITT Intermetall)"}, + { 0, 0x6d, "Cannon"}, + { 0, 0x6e, "Altera"}, + { 0, 0xef, "NEXCOM"}, + { 0, 0x70, "QUALCOMM"}, + { 0, 0xf1, "Sony"}, + { 0, 0xf2, "Cray Research"}, + { 0, 0x73, "AMS(Austria Micro)"}, + { 0, 0xf4, "Vitesse"}, + { 0, 0x75, "Aster Electronics"}, + { 0, 0x76, "Bay Networks (Synoptic)"}, + { 0, 0xf7, "Zentrum/ZMD"}, + { 0, 0xf8, "TRW"}, + { 0, 0x79, "Thesys"}, + { 0, 0x7a, "Solbourne Computer"}, + { 0, 0xfb, "Allied-Signal"}, + { 0, 0x7c, "Dialog"}, + { 0, 0xfd, "Media Vision"}, + { 0, 0xfe, "Numonyx"}, + { 1, 0x01, "Cirrus Logic"}, + { 1, 0x02, "National Instruments"}, + { 1, 0x83, "ILC Data Device"}, + { 1, 0x04, "Alcatel Mietec"}, + { 1, 0x85, "Micro Linear"}, + { 1, 0x86, "Univ. of NC"}, + { 1, 0x07, "JTAG Technologies"}, + { 1, 0x08, "BAE Systems (Loral)"}, + { 1, 0x89, "Nchip"}, + { 1, 0x8a, "Galileo Tech"}, + { 1, 0x0b, "Bestlink Systems"}, + { 1, 0x8c, "Graychip"}, + { 1, 0x0d, "GENNUM"}, + { 1, 0x0e, "VideoLogic"}, + { 1, 0x8f, "Robert Bosch"}, + { 1, 0x10, "Chip Express"}, + { 1, 0x91, "DATARAM"}, + { 1, 0x92, "United Microelectronics Corp."}, + { 1, 0x13, "TCSI"}, + { 1, 0x94, "Smart Modular"}, + { 1, 0x15, "Hughes Aircraft"}, + { 1, 0x16, "Lanstar Semiconductor"}, + { 1, 0x97, "Qlogic"}, + { 1, 0x98, "Kingston"}, + { 1, 0x19, "Music Semi"}, + { 1, 0x1a, "Ericsson Components"}, + { 1, 0x9b, "SpaSE"}, + { 1, 0x1c, "Eon Silicon Devices"}, + { 1, 0x9d, "Programmable Micro Corp"}, + { 1, 0x9e, "DoD"}, + { 1, 0x1f, "Integ. Memories Tech."}, + { 1, 0x20, "Corollary"}, + { 1, 0xa1, "Dallas Semiconductor"}, + { 1, 0xa2, "Omnivision"}, + { 1, 0x23, "EIV(Switzerland)"}, + { 1, 0xa4, "Novatel Wireless"}, + { 1, 0x25, "Zarlink (Mitel)"}, + { 1, 0x26, "Clearpoint"}, + { 1, 0xa7, "Cabletron"}, + { 1, 0xa8, "STEC (Silicon Tech)"}, + { 1, 0x29, "Vanguard"}, + { 1, 0x2a, "Hagiwara Sys-Com"}, + { 1, 0xab, "Vantis"}, + { 1, 0x2c, "Celestica"}, + { 1, 0xad, "Century"}, + { 1, 0xae, "Hal Computers"}, + { 1, 0x2f, "Rohm Company"}, + { 1, 0xb0, "Juniper Networks"}, + { 1, 0x31, "Libit Signal Processing"}, + { 1, 0x32, "Mushkin Enhanced Memory"}, + { 1, 0xb3, "Tundra Semiconductor"}, + { 1, 0x34, "Adaptec"}, + { 1, 0xb5, "LightSpeed Semi."}, + { 1, 0xb6, "ZSP Corp."}, + { 1, 0x37, "AMIC Technology"}, + { 1, 0x38, "Adobe Systems"}, + { 1, 0xb9, "Dynachip"}, + { 1, 0xba, "PNY Electronics"}, + { 1, 0x3b, "Newport Digital"}, + { 1, 0xbc, "MMC Networks"}, + { 1, 0x3d, "T Square"}, + { 1, 0x3e, "Seiko Epson"}, + { 1, 0xbf, "Broadcom"}, + { 1, 0x40, "Viking Components"}, + { 1, 0xc1, "V3 Semiconductor"}, + { 1, 0xc2, "Flextronics (Orbit Semiconductor)"}, + { 1, 0x43, "Suwa Electronics"}, + { 1, 0xc4, "Transmeta"}, + { 1, 0x45, "Micron CMS"}, + { 1, 0x46, "American Computer & Digital Components"}, + { 1, 0xc7, "Enhance 3000"}, + { 1, 0xc8, "Tower Semiconductor"}, + { 1, 0x49, "CPU Design"}, + { 1, 0x4a, "Price Point"}, + { 1, 0xcb, "Maxim Integrated Product"}, + { 1, 0x4c, "Tellabs"}, + { 1, 0xcd, "Centaur Technology"}, + { 1, 0xce, "Unigen"}, + { 1, 0x4f, "Transcend Information"}, + { 1, 0xd0, "Memory Card Technology"}, + { 1, 0x51, "CKD"}, + { 1, 0x52, "Capital Instruments"}, + { 1, 0xd3, "Aica Kogyo"}, + { 1, 0x54, "Linvex Technology"}, + { 1, 0xd5, "MSC Vertriebs"}, + { 1, 0xd6, "AKM Company"}, + { 1, 0x57, "Dynamem"}, + { 1, 0x58, "NERA ASA"}, + { 1, 0xd9, "GSI Technology"}, + { 1, 0xda, "Dane-Elec (C Memory)"}, + { 1, 0x5b, "Acorn Computers"}, + { 1, 0xdc, "Lara Technology"}, + { 1, 0x5d, "Oak Technology"}, + { 1, 0x5e, "Itec Memory"}, + { 1, 0xdf, "Tanisys Technology"}, + { 1, 0xe0, "Truevision"}, + { 1, 0x61, "Wintec Industries"}, + { 1, 0x62, "Super PC Memory"}, + { 1, 0xe3, "MGV Memory"}, + { 1, 0x64, "Galvantech"}, + { 1, 0xe5, "Gadzoox Networks"}, + { 1, 0xe6, "Multi Dimensional Cons."}, + { 1, 0x67, "GateField"}, + { 1, 0x68, "Integrated Memory System"}, + { 1, 0xe9, "Triscend"}, + { 1, 0xea, "XaQti"}, + { 1, 0x6b, "Goldenram"}, + { 1, 0xec, "Clear Logic"}, + { 1, 0x6d, "Cimaron Communications"}, + { 1, 0x6e, "Nippon Steel Semi. Corp."}, + { 1, 0xef, "Advantage Memory"}, + { 1, 0x70, "AMCC"}, + { 1, 0xf1, "LeCroy"}, + { 1, 0xf2, "Yamaha"}, + { 1, 0x73, "Digital Microwave"}, + { 1, 0xf4, "NetLogic Microsystems"}, + { 1, 0x75, "MIMOS Semiconductor"}, + { 1, 0x76, "Advanced Fibre"}, + { 1, 0xf7, "BF Goodrich Data."}, + { 1, 0xf8, "Epigram"}, + { 1, 0x79, "Acbel Polytech"}, + { 1, 0x7a, "Apacer Technology"}, + { 1, 0xfb, "Admor Memory"}, + { 1, 0x7c, "FOXCONN"}, + { 1, 0xfd, "Quadratics Superconductor"}, + { 1, 0xfe, "3COM"}, + { 2, 0x01, "Camintonn"}, + { 2, 0x02, "ISOA"}, + { 2, 0x83, "Agate Semiconductor"}, + { 2, 0x04, "ADMtek"}, + { 2, 0x85, "HYPERTEC"}, + { 2, 0x86, "Adhoc Technologies"}, + { 2, 0x07, "MOSAID Technologies"}, + { 2, 0x08, "Ardent Technologies"}, + { 2, 0x89, "Switchcore"}, + { 2, 0x8a, "Cisco Systems"}, + { 2, 0x0b, "Allayer Technologies"}, + { 2, 0x8c, "WorkX AG (Wichman)"}, + { 2, 0x0d, "Oasis Semiconductor"}, + { 2, 0x0e, "Novanet Semiconductor"}, + { 2, 0x8f, "E-M Solutions"}, + { 2, 0x10, "Power General"}, + { 2, 0x91, "Advanced Hardware Arch."}, + { 2, 0x92, "Inova Semiconductors"}, + { 2, 0x13, "Telocity"}, + { 2, 0x94, "Delkin Devices"}, + { 2, 0x15, "Symagery Microsystems"}, + { 2, 0x16, "C-Port"}, + { 2, 0x97, "SiberCore Technologies"}, + { 2, 0x98, "Southland Microsystems"}, + { 2, 0x19, "Malleable Technologies"}, + { 2, 0x1a, "Kendin Communications"}, + { 2, 0x9b, "Great Technology Microcomputer"}, + { 2, 0x1c, "Sanmina"}, + { 2, 0x9d, "HADCO"}, + { 2, 0x9e, "Corsair"}, + { 2, 0x1f, "Actrans System"}, + { 2, 0x20, "ALPHA Technologies"}, + { 2, 0xa1, "Silicon Laboratories (Cygnal)"}, + { 2, 0xa2, "Artesyn Technologies"}, + { 2, 0x23, "Align Manufacturing"}, + { 2, 0xa4, "Peregrine Semiconductor"}, + { 2, 0x25, "Chameleon Systems"}, + { 2, 0x26, "Aplus Flash Technology"}, + { 2, 0xa7, "MIPS Technologies"}, + { 2, 0xa8, "Chrysalis ITS"}, + { 2, 0x29, "ADTEC"}, + { 2, 0x2a, "Kentron Technologies"}, + { 2, 0xab, "Win Technologies"}, + { 2, 0x2c, "Tachyon Semiconductor (ASIC)"}, + { 2, 0xad, "Extreme Packet Devices"}, + { 2, 0xae, "RF Micro Devices"}, + { 2, 0x2f, "Siemens AG"}, + { 2, 0xb0, "Sarnoff"}, + { 2, 0x31, "Itautec SA"}, + { 2, 0x32, "Radiata"}, + { 2, 0xb3, "Benchmark Elect. (AVEX)"}, + { 2, 0x34, "Legend"}, + { 2, 0xb5, "SpecTek"}, + { 2, 0xb6, "Hi/fn"}, + { 2, 0x37, "Enikia"}, + { 2, 0x38, "SwitchOn Networks"}, + { 2, 0xb9, "AANetcom"}, + { 2, 0xba, "Micro Memory Bank"}, + { 2, 0x3b, "ESS Technology"}, + { 2, 0xbc, "Virata"}, + { 2, 0x3d, "Excess Bandwidth"}, + { 2, 0x3e, "West Bay Semiconductor"}, + { 2, 0xbf, "DSP Group"}, + { 2, 0x40, "Newport Communications"}, + { 2, 0xc1, "Chip2Chip"}, + { 2, 0xc2, "Phobos"}, + { 2, 0x43, "Intellitech"}, + { 2, 0xc4, "Nordic VLSI ASA"}, + { 2, 0x45, "Ishoni Networks"}, + { 2, 0x46, "Silicon Spice"}, + { 2, 0xc7, "Alchemy Semiconductor"}, + { 2, 0xc8, "Agilent Technologies"}, + { 2, 0x49, "Centillium Communications"}, + { 2, 0x4a, "W.L. Gore"}, + { 2, 0xcb, "HanBit Electronics"}, + { 2, 0x4c, "GlobeSpan"}, + { 2, 0xcd, "Element 14"}, + { 2, 0xce, "Pycon"}, + { 2, 0x4f, "Saifun Semiconductors"}, + { 2, 0xd0, "Sibyte,"}, + { 2, 0x51, "MetaLink Technologies"}, + { 2, 0x52, "Feiya Technology"}, + { 2, 0xd3, "I & C Technology"}, + { 2, 0x54, "Shikatronics"}, + { 2, 0xd5, "Elektrobit"}, + { 2, 0xd6, "Megic"}, + { 2, 0x57, "Com-Tier"}, + { 2, 0x58, "Malaysia Micro Solutions"}, + { 2, 0xd9, "Hyperchip"}, + { 2, 0xda, "Gemstone Communications"}, + { 2, 0x5b, "Anadigm (Anadyne)"}, + { 2, 0xdc, "3ParData"}, + { 2, 0x5d, "Mellanox Technologies"}, + { 2, 0x5e, "Tenx Technologies"}, + { 2, 0xdf, "Helix AG"}, + { 2, 0xe0, "Domosys"}, + { 2, 0x61, "Skyup Technology"}, + { 2, 0x62, "HiNT"}, + { 2, 0xe3, "Chiaro"}, + { 2, 0x64, "MDT Technologies"}, + { 2, 0xe5, "Exbit Technology A/S"}, + { 2, 0xe6, "Integrated Technology Express"}, + { 2, 0x67, "AVED Memory"}, + { 2, 0x68, "Legerity"}, + { 2, 0xe9, "Jasmine Networks"}, + { 2, 0xea, "Caspian Networks"}, + { 2, 0x6b, "nCUBE"}, + { 2, 0xec, "Silicon Access Networks"}, + { 2, 0x6d, "FDK"}, + { 2, 0x6e, "High Bandwidth Access"}, + { 2, 0xef, "MultiLink Technology"}, + { 2, 0x70, "BRECIS"}, + { 2, 0xf1, "World Wide Packets"}, + { 2, 0xf2, "APW"}, + { 2, 0x73, "Chicory Systems"}, + { 2, 0xf4, "Xstream Logic"}, + { 2, 0x75, "Fast-Chip"}, + { 2, 0x76, "Zucotto Wireless"}, + { 2, 0xf7, "Realchip"}, + { 2, 0xf8, "Galaxy Power"}, + { 2, 0x79, "eSilicon"}, + { 2, 0x7a, "Morphics Technology"}, + { 2, 0xfb, "Accelerant Networks"}, + { 2, 0x7c, "Silicon Wave"}, + { 2, 0xfd, "SandCraft"}, + { 2, 0xfe, "Elpida"}, + { 3, 0x01, "Solectron"}, + { 3, 0x02, "Optosys Technologies"}, + { 3, 0x83, "Buffalo (Formerly Melco)"}, + { 3, 0x04, "TriMedia Technologies"}, + { 3, 0x85, "Cyan Technologies"}, + { 3, 0x86, "Global Locate"}, + { 3, 0x07, "Optillion"}, + { 3, 0x08, "Terago Communications"}, + { 3, 0x89, "Ikanos Communications"}, + { 3, 0x8a, "Preton Technology"}, + { 3, 0x0b, "Nanya Technology"}, + { 3, 0x8c, "Elite Flash Storage"}, + { 3, 0x0d, "Mysticom"}, + { 3, 0x0e, "LightSand Communications"}, + { 3, 0x8f, "ATI Technologies"}, + { 3, 0x10, "Agere Systems"}, + { 3, 0x91, "NeoMagic"}, + { 3, 0x92, "AuroraNetics"}, + { 3, 0x13, "Geil"}, + { 3, 0x94, "Mushkin"}, + { 3, 0x15, "Tioga Technologies"}, + { 3, 0x16, "Netlist"}, + { 3, 0x97, "TeraLogic"}, + { 3, 0x98, "Cicada Semiconductor"}, + { 3, 0x19, "Centon Electronics"}, + { 3, 0x1a, "Tyco Electronics"}, + { 3, 0x9b, "Magis Works"}, + { 3, 0x1c, "Zettacom"}, + { 3, 0x9d, "Cogency Semiconductor"}, + { 3, 0x9e, "Chipcon AS"}, + { 3, 0x1f, "Aspex Technology"}, + { 3, 0x20, "F5 Networks"}, + { 3, 0xa1, "Programmable Silicon Solutions"}, + { 3, 0xa2, "ChipWrights"}, + { 3, 0x23, "Acorn Networks"}, + { 3, 0xa4, "Quicklogic"}, + { 3, 0x25, "Kingmax Semiconductor"}, + { 3, 0x26, "BOPS"}, + { 3, 0xa7, "Flasys"}, + { 3, 0xa8, "BitBlitz Communications"}, + { 3, 0x29, "eMemory Technology"}, + { 3, 0x2a, "Procket Networks"}, + { 3, 0xab, "Purple Ray"}, + { 3, 0x2c, "Trebia Networks"}, + { 3, 0xad, "Delta Electronics"}, + { 3, 0xae, "Onex Communications"}, + { 3, 0x2f, "Ample Communications"}, + { 3, 0xb0, "Memory Experts Intl"}, + { 3, 0x31, "Astute Networks"}, + { 3, 0x32, "Azanda Network Devices"}, + { 3, 0xb3, "Dibcom"}, + { 3, 0x34, "Tekmos"}, + { 3, 0xb5, "API NetWorks"}, + { 3, 0xb6, "Bay Microsystems"}, + { 3, 0x37, "Firecron"}, + { 3, 0x38, "Resonext Communications"}, + { 3, 0xb9, "Tachys Technologies"}, + { 3, 0xba, "Equator Technology"}, + { 3, 0x3b, "Concept Computer"}, + { 3, 0xbc, "SILCOM"}, + { 3, 0x3d, "3Dlabs"}, + { 3, 0x3e, "c?t Magazine"}, + { 3, 0xbf, "Sanera Systems"}, + { 3, 0x40, "Silicon Packets"}, + { 3, 0xc1, "Viasystems Group"}, + { 3, 0xc2, "Simtek"}, + { 3, 0x43, "Semicon Devices Singapore"}, + { 3, 0xc4, "Satron Handelsges"}, + { 3, 0x45, "Improv Systems"}, + { 3, 0x46, "INDUSYS"}, + { 3, 0xc7, "Corrent"}, + { 3, 0xc8, "Infrant Technologies"}, + { 3, 0x49, "Ritek Corp"}, + { 3, 0x4a, "empowerTel Networks"}, + { 3, 0xcb, "Hypertec"}, + { 3, 0x4c, "Cavium Networks"}, + { 3, 0xcd, "PLX Technology"}, + { 3, 0xce, "Massana Design"}, + { 3, 0x4f, "Intrinsity"}, + { 3, 0xd0, "Valence Semiconductor"}, + { 3, 0x51, "Terawave Communications"}, + { 3, 0x52, "IceFyre Semiconductor"}, + { 3, 0xd3, "Primarion"}, + { 3, 0x54, "Picochip Designs"}, + { 3, 0xd5, "Silverback Systems"}, + { 3, 0xd6, "Jade Star Technologies"}, + { 3, 0x57, "Pijnenburg Securealink"}, + { 3, 0x58, "takeMS International AG"}, + { 3, 0xd9, "Cambridge Silicon Radio"}, + { 3, 0xda, "Swissbit"}, + { 3, 0x5b, "Nazomi Communications"}, + { 3, 0xdc, "eWave System"}, + { 3, 0x5d, "Rockwell Collins"}, + { 3, 0x5e, "Picocel Co. (Paion)"}, + { 3, 0xdf, "Alphamosaic"}, + { 3, 0xe0, "Sandburst"}, + { 3, 0x61, "SiCon Video"}, + { 3, 0x62, "NanoAmp Solutions"}, + { 3, 0xe3, "Ericsson Technology"}, + { 3, 0x64, "PrairieComm"}, + { 3, 0xe5, "Mitac International"}, + { 3, 0xe6, "Layer N Networks"}, + { 3, 0x67, "MtekVision (Atsana)"}, + { 3, 0x68, "Allegro Networks"}, + { 3, 0xe9, "Marvell Semiconductors"}, + { 3, 0xea, "Netergy Microelectronic"}, + { 3, 0x6b, "NVIDIA"}, + { 3, 0xec, "Internet Machines"}, + { 3, 0x6d, "Peak Electronics"}, + { 3, 0x6e, "Litchfield Communication"}, + { 3, 0xef, "Accton Technology"}, + { 3, 0x70, "Teradiant Networks"}, + { 3, 0xf1, "Scaleo Chip"}, + { 3, 0xf2, "Cortina Systems"}, + { 3, 0x73, "RAM Components"}, + { 3, 0xf4, "Raqia Networks"}, + { 3, 0x75, "ClearSpeed"}, + { 3, 0x76, "Matsushita Battery"}, + { 3, 0xf7, "Xelerated"}, + { 3, 0xf8, "SimpleTech"}, + { 3, 0x79, "Utron Technology"}, + { 3, 0x7a, "Astec International"}, + { 3, 0xfb, "AVM"}, + { 3, 0x7c, "Redux Communications"}, + { 3, 0xfd, "Dot Hill Systems"}, + { 3, 0xfe, "TeraChip"}, + { 4, 0x01, "T-RAM"}, + { 4, 0x02, "Innovics Wireless"}, + { 4, 0x83, "Teknovus"}, + { 4, 0x04, "KeyEye Communications"}, + { 4, 0x85, "Runcom Technologies"}, + { 4, 0x86, "RedSwitch"}, + { 4, 0x07, "Dotcast"}, + { 4, 0x08, "Silicon Mountain Memory"}, + { 4, 0x89, "Signia Technologies"}, + { 4, 0x8a, "Pixim"}, + { 4, 0x0b, "Galazar Networks"}, + { 4, 0x8c, "White Electronic Designs"}, + { 4, 0x0d, "Patriot Scientific"}, + { 4, 0x0e, "Neoaxiom"}, + { 4, 0x8f, "3Y Power Technology"}, + { 4, 0x10, "Scaleo Chip"}, + { 4, 0x91, "Potentia Power Systems"}, + { 4, 0x92, "C-guys"}, + { 4, 0x13, "Digital Communications Technology"}, + { 4, 0x94, "Silicon-Based Technology"}, + { 4, 0x15, "Fulcrum Microsystems"}, + { 4, 0x16, "Positivo Informatica"}, + { 4, 0x97, "XIOtech"}, + { 4, 0x98, "PortalPlayer"}, + { 4, 0x19, "Zhiying Software"}, + { 4, 0x1a, "ParkerVision"}, + { 4, 0x9b, "Phonex Broadband"}, + { 4, 0x1c, "Skyworks Solutions"}, + { 4, 0x9d, "Entropic Communications"}, + { 4, 0x9e, "Pacific Force Technology"}, + { 4, 0x1f, "Zensys A/S"}, + { 4, 0x20, "Legend Silicon Corp."}, + { 4, 0xa1, "Sci-worx"}, + { 4, 0xa2, "SMSC (Standard Microsystems)"}, + { 4, 0x23, "Renesas Technology"}, + { 4, 0xa4, "Raza Microelectronics"}, + { 4, 0x25, "Phyworks"}, + { 4, 0x26, "MediaTek"}, + { 4, 0xa7, "Non-cents Productions"}, + { 4, 0xa8, "US Modular"}, + { 4, 0x29, "Wintegra"}, + { 4, 0x2a, "Mathstar"}, + { 4, 0xab, "StarCore"}, + { 4, 0x2c, "Oplus Technologies"}, + { 4, 0xad, "Mindspeed"}, + { 4, 0xae, "Just Young Computer"}, + { 4, 0x2f, "Radia Communications"}, + { 4, 0xb0, "OCZ"}, + { 4, 0x31, "Emuzed"}, + { 4, 0x32, "LOGIC Devices"}, + { 4, 0xb3, "Inphi"}, + { 4, 0x34, "Quake Technologies"}, + { 4, 0xb5, "Vixel"}, + { 4, 0xb6, "SolusTek"}, + { 4, 0x37, "Kongsberg Maritime"}, + { 4, 0x38, "Faraday Technology"}, + { 4, 0xb9, "Altium"}, + { 4, 0xba, "Insyte"}, + { 4, 0x3b, "ARM"}, + { 4, 0xbc, "DigiVision"}, + { 4, 0x3d, "Vativ Technologies"}, + { 4, 0x3e, "Endicott Interconnect Technologies"}, + { 4, 0xbf, "Pericom"}, + { 4, 0x40, "Bandspeed"}, + { 4, 0xc1, "LeWiz Communications"}, + { 4, 0xc2, "CPU Technology"}, + { 4, 0x43, "Ramaxel Technology"}, + { 4, 0xc4, "DSP Group"}, + { 4, 0x45, "Axis Communications"}, + { 4, 0x46, "Legacy Electronics"}, + { 4, 0xc7, "Chrontel"}, + { 4, 0xc8, "Powerchip Semiconductor"}, + { 4, 0x49, "MobilEye Technologies"}, + { 4, 0x4a, "Excel Semiconductor"}, + { 4, 0xcb, "A-DATA Technology"}, + { 4, 0x4c, "VirtualDigm"}, + { 4, 0xcd, "G Skill Intl"}, + { 4, 0xce, "Quanta Computer"}, + { 4, 0x4f, "Yield Microelectronics"}, + { 4, 0xd0, "Afa Technologies"}, + { 4, 0x51, "KINGBOX Technology Co."}, + { 4, 0x52, "Ceva"}, + { 4, 0xd3, "iStor Networks"}, + { 4, 0x54, "Advance Modules"}, + { 4, 0xd5, "Microsoft"}, + { 4, 0xd6, "Open-Silicon"}, + { 4, 0x57, "Goal Semiconductor"}, + { 4, 0x58, "ARC International"}, + { 4, 0xd9, "Simmtec"}, + { 4, 0xda, "Metanoia"}, + { 4, 0x5b, "Key Stream"}, + { 4, 0xdc, "Lowrance Electronics"}, + { 4, 0x5d, "Adimos"}, + { 4, 0x5e, "SiGe Semiconductor"}, + { 4, 0xdf, "Fodus Communications"}, + { 4, 0xe0, "Credence Systems Corp."}, + { 4, 0x61, "Genesis Microchip"}, + { 4, 0x62, "Vihana"}, + { 4, 0xe3, "WIS Technologies"}, + { 4, 0x64, "GateChange Technologies"}, + { 4, 0xe5, "High Density Devices AS"}, + { 4, 0xe6, "Synopsys"}, + { 4, 0x67, "Gigaram"}, + { 4, 0x68, "Enigma Semiconductor"}, + { 4, 0xe9, "Century Micro"}, + { 4, 0xea, "Icera Semiconductor"}, + { 4, 0x6b, "Mediaworks Integrated Systems"}, + { 4, 0xec, "O?Neil Product Development"}, + { 4, 0x6d, "Supreme Top Technology"}, + { 4, 0x6e, "MicroDisplay"}, + { 4, 0xef, "Team Group"}, + { 4, 0x70, "Sinett"}, + { 4, 0xf1, "Toshiba"}, + { 4, 0xf2, "Tensilica"}, + { 4, 0x73, "SiRF Technology"}, + { 4, 0xf4, "Bacoc"}, + { 4, 0x75, "SMaL Camera Technologies"}, + { 4, 0x76, "Thomson SC"}, + { 4, 0xf7, "Airgo Networks"}, + { 4, 0xf8, "Wisair"}, + { 4, 0x79, "SigmaTel"}, + { 4, 0x7a, "Arkados"}, + { 4, 0xfb, "Compete IT Co. KG"}, + { 4, 0x7c, "Eudar Technology"}, + { 4, 0xfd, "Focus Enhancements"}, + { 4, 0xfe, "Xyratex"}, + { 5, 0x01, "Specular Networks"}, + { 5, 0x02, "Patriot Memory (PDP Systems)"}, + { 5, 0x83, "U-Chip Technology Corp."}, + { 5, 0x04, "Silicon Optix"}, + { 5, 0x85, "Greenfield Networks"}, + { 5, 0x86, "CompuRAM"}, + { 5, 0x07, "Stargen"}, + { 5, 0x08, "NetCell"}, + { 5, 0x89, "Excalibrus Technologies"}, + { 5, 0x8a, "SCM Microsystems"}, + { 5, 0x0b, "Xsigo Systems"}, + { 5, 0x8c, "CHIPS & Systems"}, + { 5, 0x0d, "Tier"}, + { 5, 0x0e, "CWRL Labs"}, + { 5, 0x8f, "Teradici"}, + { 5, 0x10, "Gigaram"}, + { 5, 0x91, "g2 Microsystems"}, + { 5, 0x92, "PowerFlash Semiconductor"}, + { 5, 0x13, "P.A. Semi"}, + { 5, 0x94, "NovaTech Solutions, S.A."}, + { 5, 0x15, "c2 Microsystems"}, + { 5, 0x16, "Level5 Networks"}, + { 5, 0x97, "COS Memory AG"}, + { 5, 0x98, "Innovasic Semiconductor"}, + { 5, 0x19, "02IC Co."}, + { 5, 0x1a, "Tabula,"}, + { 5, 0x9b, "Crucial Technology"}, + { 5, 0x1c, "Chelsio Communications"}, + { 5, 0x9d, "Solarflare Communications"}, + { 5, 0x9e, "Xambala"}, + { 5, 0x1f, "EADS Astrium"}, + { 5, 0x20, "Terra Semiconductor"}, + { 5, 0xa1, "Imaging Works"}, + { 5, 0xa2, "Astute Networks"}, + { 5, 0x23, "Tzero"}, + { 5, 0xa4, "Emulex"}, + { 5, 0x25, "Power-One"}, + { 5, 0x26, "Pulse~LINK"}, + { 5, 0xa7, "Hon Hai Precision Industry"}, + { 5, 0xa8, "White Rock Networks"}, + { 5, 0x29, "Telegent Systems USA"}, + { 5, 0x2a, "Atrua Technologies"}, + { 5, 0xab, "Acbel Polytech"}, + { 5, 0x2c, "eRide"}, + { 5, 0xad, "ULi Electronics"}, + { 5, 0xae, "Magnum Semiconductor"}, + { 5, 0x2f, "neoOne Technology"}, + { 5, 0xb0, "Connex Technology"}, + { 5, 0x31, "Stream Processors"}, + { 5, 0x32, "Focus Enhancements"}, + { 5, 0xb3, "Telecis Wireless"}, + { 5, 0x34, "uNav Microelectronics"}, + { 5, 0xb5, "Tarari"}, + { 5, 0xb6, "Ambric"}, + { 5, 0x37, "Newport Media"}, + { 5, 0x38, "VMTS"}, + { 5, 0xb9, "Enuclia Semiconductor"}, + { 5, 0xba, "Virtium Technology"}, + { 5, 0x3b, "Solid State System Co."}, + { 5, 0xbc, "Kian Tech LLC"}, + { 5, 0x3d, "Artimi"}, + { 5, 0x3e, "Power Quotient International"}, + { 5, 0xbf, "Avago Technologies"}, + { 5, 0x40, "ADTechnology"}, + { 5, 0xc1, "Sigma Designs"}, + { 5, 0xc2, "SiCortex"}, + { 5, 0x43, "Ventura Technology Group"}, + { 5, 0xc4, "eASIC"}, + { 5, 0x45, "M.H.S. SAS"}, + { 5, 0x46, "Micro Star International"}, + { 5, 0xc7, "Rapport"}, + { 5, 0xc8, "Makway International"}, + { 5, 0x49, "Broad Reach Engineering Co."}, + { 5, 0x4a, "Semiconductor Mfg Intl Corp"}, + { 5, 0xcb, "SiConnect"}, + { 5, 0x4c, "FCI USA"}, + { 5, 0xcd, "Validity Sensors"}, + { 5, 0xce, "Coney Technology Co."}, + { 5, 0x4f, "Spans Logic"}, + { 5, 0xd0, "Neterion"}, + { 5, 0x51, "Qimonda"}, + { 5, 0x52, "New Japan Radio Co."}, + { 5, 0xd3, "Velogix"}, + { 5, 0x54, "Montalvo Systems"}, + { 5, 0xd5, "iVivity"}, + { 5, 0xd6, "Walton Chaintech"}, + { 5, 0x57, "AENEON"}, + { 5, 0x58, "Lorom Industrial Co."}, + { 5, 0xd9, "Radiospire Networks"}, + { 5, 0xda, "Sensio Technologies"}, + { 5, 0x5b, "Nethra Imaging"}, + { 5, 0xdc, "Hexon Technology Pte"}, + { 5, 0x5d, "CompuStocx (CSX)"}, + { 5, 0x5e, "Methode Electronics"}, + { 5, 0xdf, "Connect One"}, + { 5, 0xe0, "Opulan Technologies"}, + { 5, 0x61, "Septentrio NV"}, + { 5, 0x62, "Goldenmars Technology"}, + { 5, 0xe3, "Kreton"}, + { 5, 0x64, "Cochlear"}, + { 5, 0xe5, "Altair Semiconductor"}, + { 5, 0xe6, "NetEffect"}, + { 5, 0x67, "Spansion"}, + { 5, 0x68, "Taiwan Semiconductor Mfg"}, + { 5, 0xe9, "Emphany Systems"}, + { 5, 0xea, "ApaceWave Technologies"}, + { 5, 0x6b, "Mobilygen"}, + { 5, 0xec, "Tego"}, + { 5, 0x6d, "Cswitch"}, + { 5, 0x6e, "Haier (Beijing) IC Design Co."}, + { 5, 0xef, "MetaRAM"}, + { 5, 0x70, "Axel Electronics Co."}, + { 5, 0xf1, "Tilera"}, + { 5, 0xf2, "Aquantia"}, + { 5, 0x73, "Vivace Semiconductor"}, + { 5, 0xf4, "Redpine Signals"}, + { 5, 0x75, "Octalica"}, + { 5, 0x76, "InterDigital Communications"}, + { 5, 0xf7, "Avant Technology"}, + { 5, 0xf8, "Asrock"}, + { 5, 0x79, "Availink"}, + { 5, 0x7a, "Quartics"}, + { 5, 0xfb, "Element CXI"}, + { 5, 0x7c, "Innovaciones Microelectronicas"}, + { 5, 0xfd, "VeriSilicon Microelectronics"}, + { 5, 0xfe, "W5 Networks"}, + { 6, 0x01, "MOVEKING"}, + { 6, 0x02, "Mavrix Technology"}, + { 6, 0x83, "CellGuide"}, + { 6, 0x04, "Faraday Technology"}, + { 6, 0x85, "Diablo Technologies"}, + { 6, 0x86, "Jennic"}, + { 6, 0x07, "Octasic"}, + { 6, 0x08, "Molex"}, + { 6, 0x89, "3Leaf Networks"}, + { 6, 0x8a, "Bright Micron Technology"}, + { 6, 0x0b, "Netxen"}, + { 6, 0x8c, "NextWave Broadband"}, + { 6, 0x0d, "DisplayLink"}, + { 6, 0x0e, "ZMOS Technology"}, + { 6, 0x8f, "Tec-Hill"}, + { 6, 0x10, "Multigig"}, + { 6, 0x91, "Amimon"}, + { 6, 0x92, "Euphonic Technologies"}, + { 6, 0x13, "BRN Phoenix"}, + { 6, 0x94, "InSilica"}, + { 6, 0x15, "Ember"}, + { 6, 0x16, "Avexir Technologies"}, + { 6, 0x97, "Echelon"}, + { 6, 0x98, "Edgewater Computer Systems"}, + { 6, 0x19, "XMOS Semiconductor"}, + { 6, 0x1a, "GENUSION"}, + { 6, 0x9b, "Memory Corp NV"}, + { 6, 0x1c, "SiliconBlue Technologies"}, + { 6, 0x9d, "Rambus"}, + { 6, 0x9e, "Andes Technology"}, + { 6, 0x1f, "Coronis Systems"}, + { 6, 0x20, "Achronix Semiconductor"}, + { 6, 0xa1, "Siano Mobile Silicon"}, + { 6, 0xa2, "Semtech"}, + { 6, 0x23, "Pixelworks"}, + { 6, 0xa4, "Gaisler Research AB"}, + { 6, 0x25, "Teranetics"}, + { 6, 0x26, "Toppan Printing Co."}, + { 6, 0xa7, "Kingxcon"}, + { 6, 0xa8, "Silicon Integrated Systems"}, + { 6, 0x29, "I-O Data Device"}, + { 6, 0x2a, "NDS Americas"}, + { 6, 0xab, "Solomon Systech Limited"}, + { 6, 0x2c, "On Demand Microelectronics"}, + { 6, 0xad, "Amicus Wireless"}, + { 6, 0xae, "SMARDTV SNC"}, + { 6, 0x2f, "Comsys Communication"}, + { 6, 0xb0, "Movidia"}, + { 6, 0x31, "Javad GNSS"}, + { 6, 0x32, "Montage Technology Group"}, + { 6, 0xb3, "Trident Microsystems"}, + { 6, 0x34, "Super Talent"}, + { 6, 0xb5, "Optichron"}, + { 6, 0xb6, "Future Waves UK"}, + { 6, 0x37, "SiBEAM"}, + { 6, 0x38, "Inicore,"}, + { 6, 0xb9, "Virident Systems"}, + { 6, 0xba, "M2000"}, + { 6, 0x3b, "ZeroG Wireless"}, + { 6, 0xbc, "Gingle Technology Co."}, + { 6, 0x3d, "Space Micro"}, + { 6, 0x3e, "Wilocity"}, + { 6, 0xbf, "Novafora, Ic."}, + { 6, 0x40, "iKoa"}, + { 6, 0xc1, "ASint Technology"}, + { 6, 0xc2, "Ramtron"}, + { 6, 0x43, "Plato Networks"}, + { 6, 0xc4, "IPtronics AS"}, + { 6, 0x45, "Infinite-Memories"}, + { 6, 0x46, "Parade Technologies"}, + { 6, 0xc7, "Dune Networks"}, + { 6, 0xc8, "GigaDevice Semiconductor"}, + { 6, 0x49, "Modu"}, + { 6, 0x4a, "CEITEC"}, + { 6, 0xcb, "Northrop Grumman"}, + { 6, 0x4c, "XRONET"}, + { 6, 0xcd, "Sicon Semiconductor AB"}, + { 6, 0xce, "Atla Electronics Co."}, + { 6, 0x4f, "TOPRAM Technology"}, + { 6, 0xd0, "Silego Technology"}, + { 6, 0x51, "Kinglife"}, + { 6, 0x52, "Ability Industries"}, + { 6, 0xd3, "Silicon Power Computer & Communications"}, + { 6, 0x54, "Augusta Technology"}, + { 6, 0xd5, "Nantronics Semiconductors"}, + { 6, 0xd6, "Hilscher Gesellschaft"}, + { 6, 0x57, "Quixant"}, + { 6, 0x58, "Percello"}, + { 6, 0xd9, "NextIO"}, + { 6, 0xda, "Scanimetrics"}, + { 6, 0x5b, "FS-Semi Company"}, + { 6, 0xdc, "Infinera"}, + { 6, 0x5d, "SandForce"}, + { 6, 0x5e, "Lexar Media"}, + { 6, 0xdf, "Teradyne"}, + { 6, 0xe0, "Memory Exchange Corp."}, + { 6, 0x61, "Suzhou Smartek Electronics"}, + { 6, 0x62, "Avantium"}, + { 6, 0xe3, "ATP Electronics"}, + { 6, 0x64, "Valens Semiconductor"}, + { 6, 0xe5, "Agate Logic"}, + { 6, 0xe6, "Netronome"}, + { 6, 0x67, "Zenverge"}, + { 6, 0x68, "N-trig"}, + { 6, 0xe9, "SanMax Technologies"}, + { 6, 0xea, "Contour Semiconductor"}, + { 6, 0x6b, "TwinMOS"}, + { 6, 0xec, "Silicon Systems"}, + { 6, 0x6d, "V-Color Technology"}, + { 6, 0x6e, "Certicom"}, + { 6, 0xef, "JSC ICC Milandr"}, + { 6, 0x70, "PhotoFast Global"}, + { 6, 0xf1, "InnoDisk"}, + { 6, 0xf2, "Muscle Power"}, + { 6, 0x73, "Energy Micro"}, + { 6, 0xf4, "Innofidei"}, + { 9, 0xff, ""} +}; + +#define VEN_MAP_SIZE (sizeof(vendorMap)/sizeof(VenIdName)) + +#endif Index: branches/slice/trunkM/i386/libsaio/msdos_private.h =================================================================== --- branches/slice/trunkM/i386/libsaio/msdos_private.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/msdos_private.h (revision 1171) @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 2.0 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Written by Paul Popelka (paulp@uts.amdahl.com) + * + * You can do anything you want with this software, just don't say you wrote + * it, and don't remove this notice. + * + * This software is provided "as is". + * + * The author supplies this software to be publicly redistributed on the + * understanding that the author is not responsible for the correct + * functioning of this software in any circumstances and is not liable for + * any damages caused by this software. + * + * October 1992 + */ + +/* + * Format of a boot sector. This is the first sector on a DOS floppy disk + * or the fist sector of a partition on a hard disk. But, it is not the + * first sector of a partitioned hard disk. + */ +struct bootsector33 { + u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */ + int8_t bsOemName[8]; /* OEM name and version */ + int8_t bsBPB[19]; /* BIOS parameter block */ + int8_t bsDriveNumber; /* drive number (0x80) */ + int8_t bsBootCode[479]; /* pad so struct is 512b */ + u_int8_t bsBootSectSig0; + u_int8_t bsBootSectSig1; +#define BOOTSIG0 0x55 +#define BOOTSIG1 0xaa +}; + +struct extboot { + int8_t exDriveNumber; /* drive number (0x80) */ + int8_t exReserved1; /* reserved */ + int8_t exBootSignature; /* ext. boot signature (0x29) */ +#define EXBOOTSIG 0x29 + int8_t exVolumeID[4]; /* volume ID number */ + int8_t exVolumeLabel[11]; /* volume label */ + int8_t exFileSysType[8]; /* fs type (FAT12 or FAT16) */ +}; + +struct bootsector50 { + u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */ + int8_t bsOemName[8]; /* OEM name and version */ + int8_t bsBPB[25]; /* BIOS parameter block */ + int8_t bsExt[26]; /* Bootsector Extension */ + int8_t bsBootCode[448]; /* pad so structure is 512b */ + u_int8_t bsBootSectSig0; + u_int8_t bsBootSectSig1; +#define BOOTSIG0 0x55 +#define BOOTSIG1 0xaa +}; + +struct bootsector710 { + u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */ + int8_t bsOEMName[8]; /* OEM name and version */ + int8_t bsBPB[53]; /* BIOS parameter block */ + int8_t bsExt[26]; /* Bootsector Extension */ + int8_t bsBootCode[420]; /* pad so structure is 512b */ + u_int8_t bsBootSectSig0; + u_int8_t bsBootSectSig1; +#define BOOTSIG0 0x55 +#define BOOTSIG1 0xaa +}; + +union bootsector { + struct bootsector33 bs33; + struct bootsector50 bs50; + struct bootsector710 bs710; +}; + + +/* BPB */ + +/* + * BIOS Parameter Block (BPB) for DOS 3.3 + */ +struct bpb33 { + u_int16_t bpbBytesPerSec; /* bytes per sector */ + u_int8_t bpbSecPerClust; /* sectors per cluster */ + u_int16_t bpbResSectors; /* number of reserved sectors */ + u_int8_t bpbFATs; /* number of FATs */ + u_int16_t bpbRootDirEnts; /* number of root directory entries */ + u_int16_t bpbSectors; /* total number of sectors */ + u_int8_t bpbMedia; /* media descriptor */ + u_int16_t bpbFATsecs; /* number of sectors per FAT */ + u_int16_t bpbSecPerTrack; /* sectors per track */ + u_int16_t bpbHeads; /* number of heads */ + u_int16_t bpbHiddenSecs; /* number of hidden sectors */ +} __attribute__((packed)); + +/* + * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3, + * and bpbHugeSectors is not in the 3.3 bpb. + */ +struct bpb50 { + u_int16_t bpbBytesPerSec; /* bytes per sector */ + u_int8_t bpbSecPerClust; /* sectors per cluster */ + u_int16_t bpbResSectors; /* number of reserved sectors */ + u_int8_t bpbFATs; /* number of FATs */ + u_int16_t bpbRootDirEnts; /* number of root directory entries */ + u_int16_t bpbSectors; /* total number of sectors */ + u_int8_t bpbMedia; /* media descriptor */ + u_int16_t bpbFATsecs; /* number of sectors per FAT */ + u_int16_t bpbSecPerTrack; /* sectors per track */ + u_int16_t bpbHeads; /* number of heads */ + u_int32_t bpbHiddenSecs; /* # of hidden sectors */ + u_int32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */ +} __attribute__((packed)); + +/* + * BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50. + */ +struct bpb710 { + u_int16_t bpbBytesPerSec; /* bytes per sector */ + u_int8_t bpbSecPerClust; /* sectors per cluster */ + u_int16_t bpbResSectors; /* number of reserved sectors */ + u_int8_t bpbFATs; /* number of FATs */ + u_int16_t bpbRootDirEnts; /* number of root directory entries */ + u_int16_t bpbSectors; /* total number of sectors */ + u_int8_t bpbMedia; /* media descriptor */ + u_int16_t bpbFATsecs; /* number of sectors per FAT */ + u_int16_t bpbSecPerTrack; /* sectors per track */ + u_int16_t bpbHeads; /* number of heads */ + u_int32_t bpbHiddenSecs; /* # of hidden sectors */ + u_int32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */ + u_int32_t bpbBigFATsecs; /* like bpbFATsecs for FAT32 */ + u_int16_t bpbExtFlags; /* extended flags: */ +#define FATNUM 0xf /* mask for numbering active FAT */ +#define FATMIRROR 0x80 /* FAT is mirrored (like it always was) */ + u_int16_t bpbFSVers; /* filesystem version */ +#define FSVERS 0 /* currently only 0 is understood */ + u_int32_t bpbRootClust; /* start cluster for root directory */ + u_int16_t bpbFSInfo; /* filesystem info structure sector */ + u_int16_t bpbBackup; /* backup boot sector */ + /* There is a 12 byte filler here, but we ignore it */ +} __attribute__((packed)); + +#if 0 +/* + * BIOS Parameter Block (BPB) for DOS 3.3 + */ +struct byte_bpb33 { + int8_t bpbBytesPerSec[2]; /* bytes per sector */ + int8_t bpbSecPerClust; /* sectors per cluster */ + int8_t bpbResSectors[2]; /* number of reserved sectors */ + int8_t bpbFATs; /* number of FATs */ + int8_t bpbRootDirEnts[2]; /* number of root directory entries */ + int8_t bpbSectors[2]; /* total number of sectors */ + int8_t bpbMedia; /* media descriptor */ + int8_t bpbFATsecs[2]; /* number of sectors per FAT */ + int8_t bpbSecPerTrack[2]; /* sectors per track */ + int8_t bpbHeads[2]; /* number of heads */ + int8_t bpbHiddenSecs[2]; /* number of hidden sectors */ +}; + +/* + * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3, + * and bpbHugeSectors is not in the 3.3 bpb. + */ +struct byte_bpb50 { + int8_t bpbBytesPerSec[2]; /* bytes per sector */ + int8_t bpbSecPerClust; /* sectors per cluster */ + int8_t bpbResSectors[2]; /* number of reserved sectors */ + int8_t bpbFATs; /* number of FATs */ + int8_t bpbRootDirEnts[2]; /* number of root directory entries */ + int8_t bpbSectors[2]; /* total number of sectors */ + int8_t bpbMedia; /* media descriptor */ + int8_t bpbFATsecs[2]; /* number of sectors per FAT */ + int8_t bpbSecPerTrack[2]; /* sectors per track */ + int8_t bpbHeads[2]; /* number of heads */ + int8_t bpbHiddenSecs[4]; /* number of hidden sectors */ + int8_t bpbHugeSectors[4]; /* # of sectors if bpbSectors == 0 */ +}; + +/* + * BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50. + */ +struct byte_bpb710 { + u_int8_t bpbBytesPerSec[2]; /* bytes per sector */ + u_int8_t bpbSecPerClust; /* sectors per cluster */ + u_int8_t bpbResSectors[2]; /* number of reserved sectors */ + u_int8_t bpbFATs; /* number of FATs */ + u_int8_t bpbRootDirEnts[2]; /* number of root directory entries */ + u_int8_t bpbSectors[2]; /* total number of sectors */ + u_int8_t bpbMedia; /* media descriptor */ + u_int8_t bpbFATsecs[2]; /* number of sectors per FAT */ + u_int8_t bpbSecPerTrack[2]; /* sectors per track */ + u_int8_t bpbHeads[2]; /* number of heads */ + u_int8_t bpbHiddenSecs[4]; /* # of hidden sectors */ + u_int8_t bpbHugeSectors[4]; /* # of sectors if bpbSectors == 0 */ + u_int8_t bpbBigFATsecs[4]; /* like bpbFATsecs for FAT32 */ + u_int8_t bpbExtFlags[2]; /* extended flags: */ + u_int8_t bpbFSVers[2]; /* filesystem version */ + u_int8_t bpbRootClust[4]; /* start cluster for root directory */ + u_int8_t bpbFSInfo[2]; /* filesystem info structure sector */ + u_int8_t bpbBackup[2]; /* backup boot sector */ + /* There is a 12 byte filler here, but we ignore it */ +}; +#endif + +/* + * FAT32 FSInfo block. + */ +struct fsinfo { + u_int8_t fsisig1[4]; + u_int8_t fsifill1[480]; + u_int8_t fsisig2[4]; + u_int8_t fsinfree[4]; + u_int8_t fsinxtfree[4]; + u_int8_t fsifill2[12]; + u_int8_t fsisig3[4]; +}; + + +/* direntry */ + +/*- + * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. + * Copyright (C) 1994, 1995, 1997 TooLs GmbH. + * All rights reserved. + * Original code by Paul Popelka (paulp@uts.amdahl.com) (see above). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Structure of a dos directory entry. + */ +struct direntry { + u_int8_t deName[8]; /* filename, blank filled */ +#define SLOT_EMPTY 0x00 /* slot has never been used */ +#define SLOT_E5 0x05 /* the real value is 0xe5 */ +#define SLOT_DELETED 0xe5 /* file in this slot deleted */ + u_int8_t deExtension[3]; /* extension, blank filled */ + u_int8_t deAttributes; /* file attributes */ +#define ATTR_NORMAL 0x00 /* normal file */ +#define ATTR_READONLY 0x01 /* file is read-only (immutable) */ +#define ATTR_HIDDEN 0x02 /* file is hidden */ +#define ATTR_SYSTEM 0x04 /* file is a system file */ +#define ATTR_VOLUME 0x08 /* entry is a volume label */ +#define ATTR_DIRECTORY 0x10 /* entry is a directory name */ +#define ATTR_ARCHIVE 0x20 /* file is new or modified */ + u_int8_t deLowerCase; /* NT VFAT lower case flags */ +#define LCASE_BASE 0x08 /* filename base in lower case */ +#define LCASE_EXT 0x10 /* filename extension in lower case */ + u_int8_t deCHundredth; /* hundredth of seconds in CTime */ + u_int8_t deCTime[2]; /* create time */ + u_int8_t deCDate[2]; /* create date */ + u_int8_t deADate[2]; /* access date */ + u_int8_t deHighClust[2]; /* high bytes of cluster number */ + u_int16_t deMTime; /* last update time */ + u_int16_t deMDate; /* last update date */ + u_int8_t deStartCluster[2]; /* starting cluster of file */ + u_int8_t deFileSize[4]; /* size of file in bytes */ +}; + +/* + * Structure of a Win95 long name directory entry + */ +struct winentry { + u_int8_t weCnt; +#define WIN_LAST 0x40 +#define WIN_CNT 0x3f + u_int8_t wePart1[10]; + u_int8_t weAttributes; +#define ATTR_WIN95 0x0f + u_int8_t weReserved1; + u_int8_t weChksum; + u_int8_t wePart2[12]; + u_int16_t weReserved2; + u_int8_t wePart3[4]; +}; +#define WIN_CHARS 13 /* Number of chars per winentry */ + +/* + * Maximum filename length in Win95 + * Note: Must be < sizeof(dirent.d_name) + */ +#define WIN_MAXLEN 255 + +/* + * This is the format of the contents of the deTime field in the direntry + * structure. + * We don't use bitfields because we don't know how compilers for + * arbitrary machines will lay them out. + */ +#define DT_2SECONDS_MASK 0x1F /* seconds divided by 2 */ +#define DT_2SECONDS_SHIFT 0 +#define DT_MINUTES_MASK 0x7E0 /* minutes */ +#define DT_MINUTES_SHIFT 5 +#define DT_HOURS_MASK 0xF800 /* hours */ +#define DT_HOURS_SHIFT 11 + +/* + * This is the format of the contents of the deDate field in the direntry + * structure. + */ +#define DD_DAY_MASK 0x1F /* day of month */ +#define DD_DAY_SHIFT 0 +#define DD_MONTH_MASK 0x1E0 /* month */ +#define DD_MONTH_SHIFT 5 +#define DD_YEAR_MASK 0xFE00 /* year - 1980 */ +#define DD_YEAR_SHIFT 9 + Index: branches/slice/trunkM/i386/libsaio/table.c =================================================================== --- branches/slice/trunkM/i386/libsaio/table.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/table.c (revision 1171) @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Mach Operating System + * Copyright (c) 1990 Carnegie-Mellon University + * Copyright (c) 1989 Carnegie-Mellon University + * All rights reserved. The CMU software License Agreement specifies + * the terms and conditions for use and redistribution. + */ + +/* + * INTEL CORPORATION PROPRIETARY INFORMATION + * + * This software is supplied under the terms of a license agreement or + * nondisclosure agreement with Intel Corporation and may not be copied + * nor disclosed except in accordance with the terms of that agreement. + * + * Copyright 1988, 1989 Intel Corporation + */ + +/* + * Copyright 1993 NeXT, Inc. + * All rights reserved. + */ + +#include "memory.h" + +/* Segment Descriptor + * + * 31 24 19 16 7 0 + * ------------------------------------------------------------ + * | | |B| |A| | | |1|0|E|W|A| | + * | BASE 31..24 |G|/|0|V| LIMIT |P|DPL| TYPE | BASE 23:16 | + * | | |D| |L| 19..16| | |1|1|C|R|A| | + * ------------------------------------------------------------ + * | | | + * | BASE 15..0 | LIMIT 15..0 | + * | | | + * ------------------------------------------------------------ + */ + +struct seg_desc { + unsigned short limit_15_0; + unsigned short base_15_0; + unsigned char base_23_16; + unsigned char bit_15_8; + unsigned char bit_23_16; + unsigned char base_31_24; +}; + +// turbo - GDT must be in first 64k segment +struct seg_desc __attribute__ ((section("__INIT,__data"))) Gdt[ NGDTENT ] = { + /* 0x0 : null */ + {0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00}, + + /* 0x8 : boot protected mode 32-bit code segment + byte granularity, 1MB limit, MEMBASE offset */ + //{0xFFFF, MEMBASE, 0x00, 0x9E, 0x4F, 0x00}, + {0xFFFF, 0x0000, 0x00, 0x9E, 0xCF, 0x00}, + // TODO: Restore the correct GDT 0x8 entry before exiting the bootloader + + /* 0x10 : boot protected mode data segment + page granularity, 4GB limit, MEMBASE offset */ + {0xFFFF, MEMBASE, 0x00, 0x92, 0xCF, 0x00}, + + /* 0x18 : boot protected mode 16-bit code segment + byte granularity, 1MB limit, MEMBASE offset */ + {0xFFFF, MEMBASE, 0x00, 0x9E, 0x0F, 0x00}, + + /* 0x20 : kernel init 32-bit data segment + page granularity, 4GB limit, zero offset */ + {0xFFFF, 0x0000, 0x00, 0x92, 0xCF, 0x00}, + + /* 0x28 : kernel init 32-bit code segment + page granularity, 4GB limit, zero offset */ + {0xFFFF, 0x0000, 0x00, 0x9E, 0xCF, 0x00}, + + /* 0x30 : boot real mode data/stack segment + byte granularity, 64K limit, MEMBASE offset, expand-up */ + {0xFFFF, MEMBASE, 0x00, 0x92, 0x00, 0x00}, +}; Index: branches/slice/trunkM/i386/libsaio/Cconfig =================================================================== Index: branches/slice/trunkM/i386/libsaio/usb.c =================================================================== --- branches/slice/trunkM/i386/libsaio/usb.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/usb.c (revision 1171) @@ -0,0 +1,344 @@ +/* + * usb.c + * + * + * Created by mackerintel on 12/20/08. + * Copyright 2008 mackerintel. All rights reserved. + * + */ + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "pci.h" + +#ifndef DEBUG_USB +#define DEBUG_USB 0 +#endif + +#if DEBUG_USB +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif + + +struct pciList +{ + pci_dt_t* pciDev; + struct pciList* next; +}; + +struct pciList* usbList = NULL; + +int legacy_off (pci_dt_t *pci_dev); +int ehci_acquire (pci_dt_t *pci_dev); +int uhci_reset (pci_dt_t *pci_dev); + +// Add usb device to the list +void notify_usb_dev(pci_dt_t *pci_dev) +{ + struct pciList* current = usbList; + if(!usbList) + { + usbList = (struct pciList*)malloc(sizeof(struct pciList)); + usbList->next = NULL; + usbList->pciDev = pci_dev; + + } + else + { + while(current != NULL && current->next != NULL) + { + current = current->next; + } + current->next = (struct pciList*)malloc(sizeof(struct pciList)); + current = current->next; + + current->pciDev = pci_dev; + current->next = NULL; + } +} + +// Loop through the list and call the apropriate patch function +int usb_loop() +{ + int retVal = 1; + bool fix_ehci, fix_uhci, fix_usb, fix_legacy; + fix_ehci = fix_uhci = fix_usb = fix_legacy = false; + + if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->chameleonConfig)) + { + fix_ehci = fix_uhci = fix_legacy = fix_usb; // Disable all if none set + } + else + { + getBoolForKey(kEHCIacquire, &fix_ehci, &bootInfo->chameleonConfig); + getBoolForKey(kUHCIreset, &fix_uhci, &bootInfo->chameleonConfig); + getBoolForKey(kLegacyOff, &fix_legacy, &bootInfo->chameleonConfig); + } + + struct pciList* current = usbList; + + while(current) + { + switch (pci_config_read8(current->pciDev->dev.addr, PCI_CLASS_PROG)) + { + // EHCI + case 0x20: + if(fix_ehci) retVal &= ehci_acquire(current->pciDev); + if(fix_legacy) retVal &= legacy_off(current->pciDev); + + break; + + // UHCI + case 0x00: + if (fix_uhci) retVal &= uhci_reset(current->pciDev); + + break; + } + + current = current->next; + } + return retVal; +} + +int legacy_off (pci_dt_t *pci_dev) +{ + // Set usb legacy off modification by Signal64 + // NOTE: This *must* be called after the last file is loaded from the drive in the event that we are booting form usb. + // NOTE2: This should be called after any getc()/getchar() call. (aka, after the Wait=y keyworkd is used) + // AKA: Make this run immediatly before the kernel is called + uint32_t capaddr, opaddr; + uint8_t eecp; + uint32_t usbcmd, usbsts, usbintr; + uint32_t usblegsup, usblegctlsts; + + int isOSowned; + int isBIOSowned; + + verbose("Setting Legacy USB Off on controller [%04x:%04x] at %02x:%2x.%x\n", + pci_dev->vendor_id, pci_dev->device_id, + pci_dev->dev.bits.bus, pci_dev->dev.bits.dev, pci_dev->dev.bits.func); + + + // capaddr = Capability Registers = dev.addr + offset stored in dev.addr + 0x10 (USBBASE) + capaddr = pci_config_read32(pci_dev->dev.addr, 0x10); + + // opaddr = Operational Registers = capaddr + offset (8bit CAPLENGTH in Capability Registers + offset 0) + opaddr = capaddr + *((unsigned char*)(capaddr)); + + // eecp = EHCI Extended Capabilities offset = capaddr HCCPARAMS bits 15:8 + eecp=*((unsigned char*)(capaddr + 9)); + + DBG("capaddr=%x opaddr=%x eecp=%x\n", capaddr, opaddr, eecp); + + usbcmd = *((unsigned int*)(opaddr)); // Command Register + usbsts = *((unsigned int*)(opaddr + 4)); // Status Register + usbintr = *((unsigned int*)(opaddr + 8)); // Interrupt Enable Register + + DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr); + + // read PCI Config 32bit USBLEGSUP (eecp+0) + usblegsup = pci_config_read32(pci_dev->dev.addr, eecp); + + // informational only + isBIOSowned = !!((usblegsup) & (1 << (16))); + isOSowned = !!((usblegsup) & (1 << (24))); + + // read PCI Config 32bit USBLEGCTLSTS (eecp+4) + usblegctlsts = pci_config_read32(pci_dev->dev.addr, eecp + 4); + + DBG("usblegsup=%08x isOSowned=%d isBIOSowned=%d usblegctlsts=%08x\n", usblegsup, isOSowned, isBIOSowned, usblegctlsts); + + // Reset registers to Legacy OFF + DBG("Clearing USBLEGCTLSTS\n"); + pci_config_write32(pci_dev->dev.addr, eecp + 4, 0); //usblegctlsts + + // if delay value is in milliseconds it doesn't appear to work. + // setting value to anything up to 65535 does not add the expected delay here. + delay(100); + + usbcmd = *((unsigned int*)(opaddr)); + usbsts = *((unsigned int*)(opaddr + 4)); + usbintr = *((unsigned int*)(opaddr + 8)); + + DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr); + + DBG("Clearing Registers\n"); + + // clear registers to default + usbcmd = (usbcmd & 0xffffff00); + *((unsigned int*)(opaddr)) = usbcmd; + *((unsigned int*)(opaddr + 8)) = 0; //usbintr - clear interrupt registers + *((unsigned int*)(opaddr + 4)) = 0x1000; //usbsts - clear status registers + pci_config_write32(pci_dev->dev.addr, eecp, 1); //usblegsup + + // get the results + usbcmd = *((unsigned int*)(opaddr)); + usbsts = *((unsigned int*)(opaddr + 4)); + usbintr = *((unsigned int*)(opaddr + 8)); + + DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr); + + // read 32bit USBLEGSUP (eecp+0) + usblegsup = pci_config_read32(pci_dev->dev.addr, eecp); + + // informational only + isBIOSowned = !!((usblegsup) & (1 << (16))); + isOSowned = !!((usblegsup) & (1 << (24))); + + // read 32bit USBLEGCTLSTS (eecp+4) + usblegctlsts = pci_config_read32(pci_dev->dev.addr, eecp + 4); + + DBG("usblegsup=%08x isOSowned=%d isBIOSowned=%d usblegctlsts=%08x\n", usblegsup, isOSowned, isBIOSowned, usblegctlsts); + + verbose("Legacy USB Off Done\n"); + return 1; +} + +int ehci_acquire (pci_dt_t *pci_dev) +{ + int j, k; + uint32_t base; + uint8_t eecp; + uint8_t legacy[8]; + bool isOwnershipConflict; + bool alwaysHardBIOSReset; + + alwaysHardBIOSReset = false; + if (!getBoolForKey(kEHCIhard, &alwaysHardBIOSReset, &bootInfo->chameleonConfig)) { + alwaysHardBIOSReset = true; + } + + pci_config_write16(pci_dev->dev.addr, 0x04, 0x0002); + base = pci_config_read32(pci_dev->dev.addr, 0x10); + + verbose("EHCI controller [%04x:%04x] at %02x:%2x.%x DMA @%x\n", + pci_dev->vendor_id, pci_dev->device_id, + pci_dev->dev.bits.bus, pci_dev->dev.bits.dev, pci_dev->dev.bits.func, + base); + + if (*((unsigned char*)base) < 0xc) + { + DBG("Config space too small: no legacy implementation\n"); + return 1; + } + eecp = *((unsigned char*)(base + 9)); + if (!eecp) { + DBG("No extended capabilities: no legacy implementation\n"); + return 1; + } + + DBG("eecp=%x\n",eecp); + + // bad way to do it + // pci_conf_write(pci_dev->dev.addr, eecp, 4, 0x01000001); + for (j = 0; j < 8; j++) { + legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j); + DBG("%02x ", legacy[j]); + } + DBG("\n"); + + //Real Job: based on orByte's AppleUSBEHCI.cpp + //We try soft reset first - some systems hang on reboot with hard reset + // Definitely needed during reboot on 10.4.6 + + isOwnershipConflict = ((legacy[3] & 1 != 0) && (legacy[2] & 1 != 0)); + if (!alwaysHardBIOSReset && isOwnershipConflict) { + DBG("EHCI - Ownership conflict - attempting soft reset ...\n"); + DBG("EHCI - toggle OS Ownership to 0\n"); + pci_config_write8(pci_dev->dev.addr, eecp + 3, 0); + for (k = 0; k < 25; k++) { + for (j = 0; j < 8; j++) { + legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j); + } + if (legacy[3] == 0) { + break; + } + delay(10); + } + } + + DBG("Found USBLEGSUP_ID - value %x:%x - writing OSOwned\n", legacy[3],legacy[2]); + pci_config_write8(pci_dev->dev.addr, eecp + 3, 1); + + // wait for kEHCI_USBLEGSUP_BIOSOwned bit to clear + for (k = 0; k < 25; k++) { + for (j = 0;j < 8; j++) { + legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j); + } + DBG ("%x:%x,",legacy[3],legacy[2]); + if (legacy[2] == 0) { + break; + } + delay(10); + } + + for (j = 0;j < 8; j++) { + legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j); + } + isOwnershipConflict = ((legacy[2]) != 0); + if (isOwnershipConflict) { + // Soft reset has failed. Assume SMI being ignored + // Hard reset + // Force Clear BIOS BIT + DBG("EHCI - Ownership conflict - attempting hard reset ...\n"); + DBG ("%x:%x\n",legacy[3],legacy[2]); + DBG("EHCI - Force BIOS Ownership to 0\n"); + + pci_config_write8(pci_dev->dev.addr, eecp + 2, 0); + for (k = 0; k < 25; k++) { + for (j = 0; j < 8; j++) { + legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j); + } + DBG ("%x:%x,",legacy[3],legacy[2]); + + if ((legacy[2]) == 0) { + break; + } + delay(10); + } + // Disable further SMI events + for (j = 4; j < 8; j++) { + pci_config_write8(pci_dev->dev.addr, eecp + j, 0); + } + } + + for (j = 0; j < 8; j++) { + legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j); + } + + DBG ("%x:%x\n",legacy[3],legacy[2]); + + // Final Ownership Resolution Check... + if (legacy[2] & 1) { + DBG("EHCI controller unable to take control from BIOS\n"); + return 0; + } + + DBG("EHCI Acquire OS Ownership done\n"); + return 1; +} + +int uhci_reset (pci_dt_t *pci_dev) +{ + uint32_t base, port_base; + + base = pci_config_read32(pci_dev->dev.addr, 0x20); + port_base = (base >> 5) & 0x07ff; + + verbose("UHCI controller [%04x:%04x] at %02x:%2x.%x base %x(%x)\n", + pci_dev->vendor_id, pci_dev->device_id, + pci_dev->dev.bits.bus, pci_dev->dev.bits.dev, pci_dev->dev.bits.func, + port_base, base); + + pci_config_write16(pci_dev->dev.addr, 0xc0, 0x8f00); + + outw (port_base, 0x0002); + delay(10); + outw (port_base+4,0); + delay(10); + outw (port_base,0); + return 1; +} Index: branches/slice/trunkM/i386/libsaio/device_inject.c =================================================================== --- branches/slice/trunkM/i386/libsaio/device_inject.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/device_inject.c (revision 1171) @@ -0,0 +1,360 @@ +/* + * Copyright 2009 Jasmin Fazlic All rights reserved. + */ +/* + * Cleaned and merged by iNDi + */ + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "pci.h" +#include "pci_root.h" +#include "device_inject.h" +#include "convert.h" + +#ifndef DEBUG_INJECT +#define DEBUG_INJECT 0 +#endif + +#if DEBUG_INJECT +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif + +uint32_t devices_number = 1; +uint32_t builtin_set = 0; +struct DevPropString *string = 0; +uint8_t *stringdata = 0; +uint32_t stringlength = 0; + +char *efi_inject_get_devprop_string(uint32_t *len) +{ + if(string) { + *len = string->length; + return devprop_generate_string(string); + } + verbose("efi_inject_get_devprop_string NULL trying stringdata\n"); + return NULL; +} + +void setupDeviceProperties(Node *node) +{ + const char *val; + uint8_t *binStr; + int cnt, cnt2; + + static char DEVICE_PROPERTIES_PROP[] = "device-properties"; + + /* Generate devprop string. + */ + uint32_t strlength; + char *string = efi_inject_get_devprop_string(&strlength); + + /* Use the static "device-properties" boot config key contents if available, + * otheriwse use the generated one. + */ + if (!getValueForKey(kDeviceProperties, &val, &cnt, &bootInfo->chameleonConfig) && string) + { + val = (const char*)string; + cnt = strlength * 2; + } + + if (cnt > 1) + { + binStr = convertHexStr2Binary(val, &cnt2); + if (cnt2 > 0) DT__AddProperty(node, DEVICE_PROPERTIES_PROP, cnt2, binStr); + } +} + +struct DevPropString *devprop_create_string(void) +{ + string = (struct DevPropString*)malloc(sizeof(struct DevPropString)); + + if(string == NULL) + return NULL; + + memset(string, 0, sizeof(struct DevPropString)); + string->length = 12; + string->WHAT2 = 0x01000000; + return string; +} + +struct DevPropDevice *devprop_add_device(struct DevPropString *string, char *path) +{ + struct DevPropDevice *device; + const char pciroot_string[] = "PciRoot(0x"; + const char pci_device_string[] = "Pci(0x"; + + if (string == NULL || path == NULL) { + return NULL; + } + device = malloc(sizeof(struct DevPropDevice)); + + if (strncmp(path, pciroot_string, strlen(pciroot_string))) { + printf("ERROR parsing device path\n"); + return NULL; + } + + memset(device, 0, sizeof(struct DevPropDevice)); + device->acpi_dev_path._UID = getPciRootUID(); + + int numpaths = 0; + int x, curr = 0; + char buff[] = "00"; + + for (x = 0; x < strlen(path); x++) { + if (!strncmp(&path[x], pci_device_string, strlen(pci_device_string))) { + x+=strlen(pci_device_string); + curr=x; + while(path[++x] != ','); + if(x-curr == 2) + sprintf(buff, "%c%c", path[curr], path[curr+1]); + else if(x-curr == 1) + sprintf(buff, "%c", path[curr]); + else + { + printf("ERROR parsing device path\n"); + numpaths = 0; + break; + } + device->pci_dev_path[numpaths].device = ascii_hex_to_int(buff); + + x += 3; // 0x + curr = x; + while(path[++x] != ')'); + if(x-curr == 2) + sprintf(buff, "%c%c", path[curr], path[curr+1]); + else if(x-curr == 1) + sprintf(buff, "%c", path[curr]); + else + { + printf("ERROR parsing device path\n"); + numpaths = 0; + break; + } + device->pci_dev_path[numpaths].function = ascii_hex_to_int(buff); // TODO: find dev from char *path + + numpaths++; + } + } + + if(!numpaths) + return NULL; + + device->numentries = 0x00; + + device->acpi_dev_path.length = 0x0c; + device->acpi_dev_path.type = 0x02; + device->acpi_dev_path.subtype = 0x01; + device->acpi_dev_path._HID = 0xd041030a; + + device->num_pci_devpaths = numpaths; + device->length = 24 + (6*numpaths); + + int i; + + for(i = 0; i < numpaths; i++) + { + device->pci_dev_path[i].length = 0x06; + device->pci_dev_path[i].type = 0x01; + device->pci_dev_path[i].subtype = 0x01; + } + + device->path_end.length = 0x04; + device->path_end.type = 0x7f; + device->path_end.subtype = 0xff; + + device->string = string; + device->data = NULL; + string->length += device->length; + + if(!string->entries) + if((string->entries = (struct DevPropDevice**)malloc(sizeof(device)))== NULL) + return 0; + + string->entries[string->numentries++] = (struct DevPropDevice*)malloc(sizeof(device)); + string->entries[string->numentries-1] = device; + + return device; +} + +int devprop_add_value(struct DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len) +{ + + if(!nm || !vl || !len) + return 0; + + uint32_t length = ((strlen(nm) * 2) + len + (2 * sizeof(uint32_t)) + 2); + uint8_t *data = (uint8_t*)malloc(length); + { + if(!data) + return 0; + + memset(data, 0, length); + uint32_t off= 0; + data[off+1] = ((strlen(nm) * 2) + 6) >> 8; + data[off] = ((strlen(nm) * 2) + 6) & 0x00FF; + + off += 4; + uint32_t i=0, l = strlen(nm); + for(i = 0 ; i < l ; i++, off += 2) + { + data[off] = *nm++; + } + + off += 2; + l = len; + uint32_t *datalength = (uint32_t*)&data[off]; + *datalength = l + 4; + off += 4; + for(i = 0 ; i < l ; i++, off++) + { + data[off] = *vl++; + } + } + + uint32_t offset = device->length - (24 + (6 * device->num_pci_devpaths)); + + uint8_t *newdata = (uint8_t*)malloc((length + offset)); + if(!newdata) + return 0; + if(device->data) + if(offset > 1) + memcpy(newdata, device->data, offset); + + memcpy(newdata + offset, data, length); + + device->length += length; + device->string->length += length; + device->numentries++; + + if(!device->data) + device->data = (uint8_t*)malloc(sizeof(uint8_t)); + else + free(device->data); + + free(data); + device->data = newdata; + + return 1; +} + +char *devprop_generate_string(struct DevPropString *string) +{ + char *buffer = (char*)malloc(string->length * 2); + char *ptr = buffer; + + if(!buffer) + return NULL; + + sprintf(buffer, "%08x%08x%04x%04x", dp_swap32(string->length), string->WHAT2, + dp_swap16(string->numentries), string->WHAT3); + buffer += 24; + int i = 0, x = 0; + + while(i < string->numentries) + { + sprintf(buffer, "%08x%04x%04x", dp_swap32(string->entries[i]->length), + dp_swap16(string->entries[i]->numentries), string->entries[i]->WHAT2); + + buffer += 16; + sprintf(buffer, "%02x%02x%04x%08x%08x", string->entries[i]->acpi_dev_path.type, + string->entries[i]->acpi_dev_path.subtype, + dp_swap16(string->entries[i]->acpi_dev_path.length), + string->entries[i]->acpi_dev_path._HID, + dp_swap32(string->entries[i]->acpi_dev_path._UID)); + + buffer += 24; + for(x=0;x < string->entries[i]->num_pci_devpaths; x++) + { + sprintf(buffer, "%02x%02x%04x%02x%02x", string->entries[i]->pci_dev_path[x].type, + string->entries[i]->pci_dev_path[x].subtype, + dp_swap16(string->entries[i]->pci_dev_path[x].length), + string->entries[i]->pci_dev_path[x].function, + string->entries[i]->pci_dev_path[x].device); + buffer += 12; + } + + sprintf(buffer, "%02x%02x%04x", string->entries[i]->path_end.type, + string->entries[i]->path_end.subtype, + dp_swap16(string->entries[i]->path_end.length)); + + buffer += 8; + uint8_t *dataptr = string->entries[i]->data; + for(x = 0; x < (string->entries[i]->length) - (24 + (6 * string->entries[i]->num_pci_devpaths)) ; x++) + { + sprintf(buffer, "%02x", *dataptr++); + buffer += 2; + } + i++; + } + return ptr; +} + +void devprop_free_string(struct DevPropString *string) +{ + if(!string) + return; + + int i; + for(i = 0; i < string->numentries; i++) + { + if(string->entries[i]) + { + if(string->entries[i]->data) + { + free(string->entries[i]->data); + string->entries[i]->data = NULL; + } + free(string->entries[i]); + string->entries[i] = NULL; + } + } + + free(string); + string = NULL; +} + +/* a fine place for this code */ + +int devprop_add_network_template(struct DevPropDevice *device, uint16_t vendor_id) +{ + if(!device) + return 0; + uint8_t builtin = 0x0; + if((vendor_id != 0x168c) && (builtin_set == 0)) + { + builtin_set = 1; + builtin = 0x01; + } + if(!devprop_add_value(device, "built-in", (uint8_t*)&builtin, 1)) + return 0; + devices_number++; + return 1; +} + +void set_eth_builtin(pci_dt_t *eth_dev) +{ + char *devicepath = get_pci_dev_path(eth_dev); + struct DevPropDevice *device = (struct DevPropDevice*)malloc(sizeof(struct DevPropDevice)); + + verbose("LAN Controller [%04x:%04x] :: %s\n", eth_dev->vendor_id, eth_dev->device_id, devicepath); + + if (!string) + string = devprop_create_string(); + + device = devprop_add_device(string, devicepath); + if(device) + { + verbose("Setting up lan keys\n"); + devprop_add_network_template(device, eth_dev->vendor_id); + stringdata = (uint8_t*)malloc(sizeof(uint8_t) * string->length); + if(stringdata) + { + memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length); + stringlength = string->length; + } + } +} Index: branches/slice/trunkM/i386/libsaio/device_inject.h =================================================================== --- branches/slice/trunkM/i386/libsaio/device_inject.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/device_inject.h (revision 1171) @@ -0,0 +1,74 @@ +/* + * Copyright 2009 Jasmin Fazlic All rights reserved. + */ +/* + * Cleaned and merged by iNDi + */ + +#ifndef __LIBSAIO_DEVICE_INJECT_H +#define __LIBSAIO_DEVICE_INJECT_H + +#define DP_ADD_TEMP_VAL(dev, val) devprop_add_value(dev, (char*)val[0], (uint8_t*)val[1], strlen(val[1]) + 1) +#define DP_ADD_TEMP_VAL_DATA(dev, val) devprop_add_value(dev, (char*)val.name, (uint8_t*)val.data, val.size) +#define MAX_PCI_DEV_PATHS 4 + +extern struct DevPropString *string; +extern uint8_t *stringdata; +extern uint32_t stringlength; + +extern void setupDeviceProperties(Node *node); + +struct ACPIDevPath { + uint8_t type; // = 2 ACPI device-path + uint8_t subtype; // = 1 ACPI Device-path + uint16_t length; // = 0x0c + uint32_t _HID; // = 0xD041030A ? + uint32_t _UID; // = 0x00000000 PCI ROOT +}; + +struct PCIDevPath { + uint8_t type; // = 1 Hardware device-path + uint8_t subtype; // = 1 PCI + uint16_t length; // = 6 + uint8_t function; // pci func number + uint8_t device; // pci dev number +}; + +struct DevicePathEnd { + uint8_t type; // = 0x7f + uint8_t subtype; // = 0xff + uint16_t length; // = 4; +}; + +struct DevPropDevice { + uint32_t length; + uint16_t numentries; + uint16_t WHAT2; // 0x0000 ? + struct ACPIDevPath acpi_dev_path; // = 0x02010c00 0xd041030a + struct PCIDevPath pci_dev_path[MAX_PCI_DEV_PATHS]; // = 0x01010600 func dev + struct DevicePathEnd path_end; // = 0x7fff0400 + uint8_t *data; + + // ------------------------ + uint8_t num_pci_devpaths; + struct DevPropString *string; + // ------------------------ +}; + +struct DevPropString { + uint32_t length; + uint32_t WHAT2; // 0x01000000 ? + uint16_t numentries; + uint16_t WHAT3; // 0x0000 ? + struct DevPropDevice **entries; +}; + +char *efi_inject_get_devprop_string(uint32_t *len); +int devprop_add_network_template(struct DevPropDevice *device, uint16_t vendor_id); +struct DevPropString *devprop_create_string(void); +struct DevPropDevice *devprop_add_device(struct DevPropString *string, char *path); +int devprop_add_value(struct DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len); +char *devprop_generate_string(struct DevPropString *string); +void devprop_free_string(struct DevPropString *string); + +#endif /* !__LIBSAIO_DEVICE_INJECT_H */ Index: branches/slice/trunkM/i386/libsaio/fdisk.h =================================================================== --- branches/slice/trunkM/i386/libsaio/fdisk.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/fdisk.h (revision 1171) @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1992 NeXT Computer, Inc. + * + * IBM PC disk partitioning data structures. + * + * HISTORY + * + * 8 July 1992 David E. Bohman at NeXT + * Created. + */ + +#ifndef __LIBSAIO_FDISK_H +#define __LIBSAIO_FDISK_H + +#define DISK_BLK0 0 /* blkno of boot block */ +#define DISK_BLK0SZ 512 /* size of boot block */ +#define DISK_BOOTSZ 446 /* size of boot code in boot block */ +#define DISK_SIGNATURE 0xAA55 /* signature of the boot record */ +#define FDISK_NPART 4 /* number of entries in fdisk table */ +#define FDISK_ACTIVE 0x80 /* indicator of active partition */ +#define FDISK_NEXTNAME 0xA7 /* indicator of NeXT partition */ +#define FDISK_DOS12 0x01 /* 12-bit fat < 10MB dos partition */ +#define FDISK_DOS16S 0x04 /* 16-bit fat < 32MB dos partition */ +#define FDISK_DOSEXT 0x05 /* extended dos partition */ +#define FDISK_DOS16B 0x06 /* 16-bit fat >= 32MB dos partition */ +#define FDISK_NTFS 0x07 /* NTFS partition */ +#define FDISK_SMALLFAT32 0x0b /* FAT32 partition */ +#define FDISK_FAT32 0x0c /* FAT32 partition */ +#define FDISK_DOS16SLBA 0x0e +#define FDISK_LINUX 0x83 +#define FDISK_UFS 0xa8 /* Apple UFS partition */ +#define FDISK_HFS 0xaf /* Apple HFS partition */ +#define FDISK_BOOTER 0xab /* Apple booter partition */ + +/* + * Format of fdisk partion entry (if present). + */ +struct fdisk_part { + unsigned char bootid; /* bootable or not */ + unsigned char beghead; /* begining head, sector, cylinder */ + unsigned char begsect; /* begcyl is a 10-bit number */ + unsigned char begcyl; /* High 2 bits are in begsect */ + unsigned char systid; /* OS type */ + unsigned char endhead; /* ending head, sector, cylinder */ + unsigned char endsect; /* endcyl is a 10-bit number */ + unsigned char endcyl; /* High 2 bits are in endsect */ + unsigned long relsect; /* partion physical offset on disk */ + unsigned long numsect; /* number of sectors in partition */ +} __attribute__((packed)); + +/* + * Format of boot block. + */ +struct disk_blk0 { + unsigned char bootcode[DISK_BOOTSZ]; + unsigned char parts[FDISK_NPART][sizeof (struct fdisk_part)]; + unsigned short signature; +}; + +struct REAL_disk_blk0 { + unsigned char bootcode[DISK_BOOTSZ]; + struct fdisk_part parts[FDISK_NPART]; + unsigned short signature; +} __attribute__((packed)); + +#endif /* !__LIBSAIO_FDISK_H */ Index: branches/slice/trunkM/i386/libsaio/dram_controllers.c =================================================================== --- branches/slice/trunkM/i386/libsaio/dram_controllers.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/dram_controllers.c (revision 1171) @@ -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), PCI_VENDOR_ID); + did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), PCI_DEVICE_ID); + 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 Active to precharge (tRAS) + Platform->RAM.RAS = (mc_channel_bank_timing >> 4) & 0x1F; + + // RAS Precharge (tRP) + 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 \n\tCAS:%d tRC:%d tRP:%d RAS:%d (%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 + ,Platform->RAM.CAS, Platform->RAM.TRC, Platform->RAM.TRP, Platform->RAM.RAS + ); +// getchar(); + } +} Index: branches/slice/trunkM/i386/libsaio/ntfs.c =================================================================== --- branches/slice/trunkM/i386/libsaio/ntfs.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/ntfs.c (revision 1171) @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2004 Apple Computer, Inc. All Rights Reserved. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include "libsaio.h" +#include "sl.h" + +#define BYTE_ORDER_MARK 0xFEFF + +#include "ntfs_private.h" + +#define FS_TYPE "ntfs" +#define FS_NAME_FILE "NTFS" + +#define MAX_BLOCK_SIZE 2048 +#define MAX_CLUSTER_SIZE 32768 + +#define LABEL_LENGTH 1024 +#define UNKNOWN_LABEL "Untitled NTFS" + +#define FSUR_IO_FAIL -1 +#define FSUR_UNRECOGNIZED -1 +#define FSUR_RECOGNIZED 0 + +#define ERROR -1 + +/* + * Process per-sector "fixups" that NTFS uses to detect corruption of + * multi-sector data structures, like MFT records. + */ +static int +ntfs_fixup( + char *buf, + size_t len, + u_int32_t magic, + u_int32_t bytesPerSector) +{ + struct fixuphdr *fhp = (struct fixuphdr *) buf; + int i; + u_int16_t fixup; + u_int16_t *fxp; + u_int16_t *cfxp; + u_int32_t fixup_magic; + u_int16_t fixup_count; + u_int16_t fixup_offset; + + fixup_magic = OSReadLittleInt32(&fhp->fh_magic,0); + if (fixup_magic != magic) { + error("ntfs_fixup: magic doesn't match: %08x != %08x\n", + fixup_magic, magic); + return (ERROR); + } + fixup_count = OSReadLittleInt16(&fhp->fh_fnum,0); + if ((fixup_count - 1) * bytesPerSector != len) { + error("ntfs_fixup: " \ + "bad fixups number: %d for %ld bytes block\n", + fixup_count, (long)len); /* XXX printf kludge */ + return (ERROR); + } + fixup_offset = OSReadLittleInt16(&fhp->fh_foff,0); + if (fixup_offset >= len) { + error("ntfs_fixup: invalid offset: %x", fixup_offset); + return (ERROR); + } + fxp = (u_int16_t *) (buf + fixup_offset); + cfxp = (u_int16_t *) (buf + bytesPerSector - 2); + fixup = *fxp++; + for (i = 1; i < fixup_count; i++, fxp++) { + if (*cfxp != fixup) { + error("ntfs_fixup: fixup %d doesn't match\n", i); + return (ERROR); + } + *cfxp = *fxp; + cfxp = (u_int16_t *)(((caddr_t)cfxp) + bytesPerSector); + } + return (0); +} + +/* + * Find a resident attribute of a given type. Returns a pointer to the + * attribute data, and its size in bytes. + */ +static int +ntfs_find_attr( + char *buf, + u_int32_t attrType, + void **attrData, + size_t *attrSize) +{ + struct filerec *filerec; + struct attr *attr; + u_int16_t offset; + + filerec = (struct filerec *) buf; + offset = OSReadLittleInt16(&filerec->fr_attroff,0); + attr = (struct attr *) (buf + offset); + + /* Should we also check offset < buffer size? */ + while (attr->a_hdr.a_type != 0xFFFFFFFF) /* same for big/little endian */ + { + if (OSReadLittleInt32(&attr->a_hdr.a_type,0) == attrType) + { + if (attr->a_hdr.a_flag != 0) + { + //verbose("NTFS: attriubte 0x%X is non-resident\n", attrType); + return 1; + } + + *attrSize = OSReadLittleInt16(&attr->a_r.a_datalen,0); + *attrData = buf + offset + OSReadLittleInt16(&attr->a_r.a_dataoff,0); + return 0; /* found it! */ + } + + /* Skip to the next attribute */ + offset += OSReadLittleInt32(&attr->a_hdr.reclen,0); + attr = (struct attr *) (buf + offset); + } + + return 1; /* No matching attrType found */ +} + +/* + * Examine a volume to see if we recognize it as a mountable. + */ +void +NTFSGetDescription(CICell ih, char *str, long strMaxLen) +{ + struct bootfile *boot; + unsigned bytesPerSector; + unsigned sectorsPerCluster; + int mftRecordSize; + u_int64_t totalClusters; + u_int64_t cluster, mftCluster; + size_t mftOffset; + void *nameAttr; + size_t nameSize; + char *buf; + + buf = (char *)malloc(MAX_CLUSTER_SIZE); + if (buf == 0) { + goto error; + } + + /* + * 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; + + /* + * The first three bytes are an Intel x86 jump instruction. I assume it + * can be the same forms as DOS FAT: + * 0xE9 0x?? 0x?? + * 0xEC 0x?? 0x90 + * where 0x?? means any byte value is OK. + */ + if (boot->reserved1[0] != 0xE9 + && (boot->reserved1[0] != 0xEB || boot->reserved1[2] != 0x90)) + { + goto error; + } + + /* + * Check the "NTFS " signature. + */ + if (memcmp((const char *)boot->bf_sysid, "NTFS ", 8) != 0) + { + goto error; + } + + /* + * Make sure the bytes per sector and sectors per cluster are + * powers of two, and within reasonable ranges. + */ + bytesPerSector = OSReadLittleInt16(&boot->bf_bps,0); + if ((bytesPerSector & (bytesPerSector-1)) || bytesPerSector < 512 || bytesPerSector > 32768) + { + //verbose("NTFS: invalid bytes per sector (%d)\n", bytesPerSector); + goto error; + } + + sectorsPerCluster = boot->bf_spc; /* Just one byte; no swapping needed */ + if ((sectorsPerCluster & (sectorsPerCluster-1)) || sectorsPerCluster > 128) + { + //verbose("NTFS: invalid sectors per cluster (%d)\n", bytesPerSector); + goto error; + } + + /* + * Calculate the number of clusters from the number of sectors. + * Then bounds check the $MFT and $MFTMirr clusters. + */ + totalClusters = OSReadLittleInt64(&boot->bf_spv,0) / sectorsPerCluster; + mftCluster = OSReadLittleInt64(&boot->bf_mftcn,0); + if (mftCluster > totalClusters) + { + ////verbose("NTFS: invalid $MFT cluster (%lld)\n", mftCluster); + goto error; + } + cluster = OSReadLittleInt64(&boot->bf_mftmirrcn,0); + if (cluster > totalClusters) + { + //verbose("NTFS: invalid $MFTMirr cluster (%lld)\n", cluster); + goto error; + } + + /* + * Determine the size of an MFT record. + */ + mftRecordSize = (int8_t) boot->bf_mftrecsz; + if (mftRecordSize < 0) + mftRecordSize = 1 << -mftRecordSize; + else + mftRecordSize *= bytesPerSector * sectorsPerCluster; + //verbose("NTFS: MFT record size = %d\n", mftRecordSize); + + /* + * Read the MFT record for $Volume. This assumes the first four + * file records in the MFT are contiguous; if they aren't, we + * would have to map the $MFT itself. + * + * This will fail if the device sector size is larger than the + * MFT record size, since the $Volume record won't be aligned + * on a sector boundary. + */ + mftOffset = mftCluster * sectorsPerCluster * bytesPerSector; + mftOffset += mftRecordSize * NTFS_VOLUMEINO; + + Seek(ih, mftOffset); + Read(ih, (long)buf, mftRecordSize); +#if UNUSED + if (lseek(fd, mftOffset, SEEK_SET) == -1) + { + //verbose("NTFS: lseek to $Volume failed: %s\n", strerror(errno)); + goto error; + } + if (read(fd, buf, mftRecordSize) != mftRecordSize) + { + //verbose("NTFS: error reading MFT $Volume record: %s\n", + strerror(errno)); + goto error; + } +#endif + + if (ntfs_fixup(buf, mftRecordSize, NTFS_FILEMAGIC, bytesPerSector) != 0) + { + //verbose("NTFS: block fixup failed\n"); + goto error; + } + + /* + * Loop over the attributes, looking for $VOLUME_NAME (0x60). + */ + if(ntfs_find_attr(buf, NTFS_A_VOLUMENAME, &nameAttr, &nameSize) != 0) + { + //verbose("NTFS: $VOLUME_NAME attribute not found\n"); + goto error; + } + + str[0] = '\0'; + + utf_encodestr( nameAttr, nameSize / 2, (u_int8_t *)str, strMaxLen, OSLittleEndian ); + + free(buf); + return; + + error: + if (buf) free(buf); + 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; + + const struct bootfile * part_bootfile = buffer; // NTFS boot sector structure + + // Looking for NTFS signature. + if (strncmp((const char *)part_bootfile->bf_sysid, NTFS_BBID, NTFS_BBIDLEN) == 0) + result = true; + + return result; +} Index: branches/slice/trunkM/i386/libsaio/nvidia.c =================================================================== --- branches/slice/trunkM/i386/libsaio/nvidia.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/nvidia.c (revision 1171) @@ -0,0 +1,1484 @@ +/* + * NVidia injector + * + * Copyright (C) 2009 Jasmin Fazlic, iNDi + * + * NVidia injector 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 3 of the License, or + * (at your option) any later version. + * + * NVidia driver and injector 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 NVidia injector. If not, see . + */ +/* + * Alternatively you can choose to comply with APSL + */ + + +/* + * DCB-Table parsing is based on software (nouveau driver) originally distributed under following license: + * + * + * Copyright 2005-2006 Erik Waling + * Copyright 2006 Stephane Marchesin + * Copyright 2007-2009 Stuart Bennett + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "boot.h" +#include "bootstruct.h" +#include "pci.h" +#include "platform.h" +#include "device_inject.h" +#include "nvidia.h" + +#ifndef DEBUG_NVIDIA +#define DEBUG_NVIDIA 0 +#endif + +#if DEBUG_NVIDIA +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif + +#define NVIDIA_ROM_SIZE 0x10000 +#define PATCH_ROM_SUCCESS 1 +#define PATCH_ROM_SUCCESS_HAS_LVDS 2 +#define PATCH_ROM_FAILED 0 +#define MAX_NUM_DCB_ENTRIES 16 +#define TYPE_GROUPED 0xff + +extern uint32_t devices_number; + +const char *nvidia_compatible_0[] = { "@0,compatible", "NVDA,NVMac" }; +const char *nvidia_compatible_1[] = { "@1,compatible", "NVDA,NVMac" }; +const char *nvidia_device_type_0[] = { "@0,device_type", "display" }; +const char *nvidia_device_type_1[] = { "@1,device_type", "display" }; +const char *nvidia_device_type[] = { "device_type", "NVDA,Parent" }; +const char *nvidia_name_0[] = { "@0,name", "NVDA,Display-A" }; +const char *nvidia_name_1[] = { "@1,name", "NVDA,Display-B" }; +const char *nvidia_slot_name[] = { "AAPL,slot-name", "Slot-1" }; + +static uint8_t default_NVCAP[]= { + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x00 +}; + +#define NVCAP_LEN ( sizeof(default_NVCAP) / sizeof(uint8_t) ) + +static uint8_t default_dcfg_0[] = {0xff, 0xff, 0xff, 0xff}; +static uint8_t default_dcfg_1[] = {0xff, 0xff, 0xff, 0xff}; + +#define DCFG0_LEN ( sizeof(default_dcfg_0) / sizeof(uint8_t) ) +#define DCFG1_LEN ( sizeof(default_dcfg_1) / sizeof(uint8_t) ) + +static struct nv_chipsets_t NVKnownChipsets[] = { + { 0x00000000, "Unknown" }, +// temporary placement + { 0x10DE0DF4, "GeForce GT 450M" }, //Azi + issue #99 + { 0x10DE1251, "GeForce GTX 560M" }, // Asus G74SX +//======================================== + // 0040 - 004F + { 0x10DE0040, "GeForce 6800 Ultra" }, + { 0x10DE0041, "GeForce 6800" }, + { 0x10DE0042, "GeForce 6800 LE" }, + { 0x10DE0043, "GeForce 6800 XE" }, + { 0x10DE0044, "GeForce 6800 XT" }, + { 0x10DE0045, "GeForce 6800 GT" }, + { 0x10DE0046, "GeForce 6800 GT" }, + { 0x10DE0047, "GeForce 6800 GS" }, + { 0x10DE0048, "GeForce 6800 XT" }, + { 0x10DE004D, "Quadro FX 3400" }, + { 0x10DE004E, "Quadro FX 4000" }, + // 0050 - 005F + // 0060 - 006F + // 0070 - 007F + // 0080 - 008F + // 0090 - 009F + { 0x10DE0090, "GeForce 7800 GTX" }, + { 0x10DE0091, "GeForce 7800 GTX" }, + { 0x10DE0092, "GeForce 7800 GT" }, + { 0x10DE0093, "GeForce 7800 GS" }, + { 0x10DE0095, "GeForce 7800 SLI" }, + { 0x10DE0098, "GeForce Go 7800" }, + { 0x10DE0099, "GeForce Go 7800 GTX" }, + { 0x10DE009D, "Quadro FX 4500" }, + // 00A0 - 00AF + // 00B0 - 00BF + // 00C0 - 00CF + { 0x10DE00C0, "GeForce 6800 GS" }, + { 0x10DE00C1, "GeForce 6800" }, + { 0x10DE00C2, "GeForce 6800 LE" }, + { 0x10DE00C3, "GeForce 6800 XT" }, + { 0x10DE00C8, "GeForce Go 6800" }, + { 0x10DE00C9, "GeForce Go 6800 Ultra" }, + { 0x10DE00CC, "Quadro FX Go1400" }, + { 0x10DE00CD, "Quadro FX 3450/4000 SDI" }, + { 0x10DE00CE, "Quadro FX 1400" }, + // 00D0 - 00DF + // 00E0 - 00EF + // 00F0 - 00FF + { 0x10DE00F1, "GeForce 6600 GT" }, + { 0x10DE00F2, "GeForce 6600" }, + { 0x10DE00F3, "GeForce 6200" }, + { 0x10DE00F4, "GeForce 6600 LE" }, + { 0x10DE00F5, "GeForce 7800 GS" }, + { 0x10DE00F6, "GeForce 6800 GS/XT" }, + { 0x10DE00F8, "Quadro FX 3400/4400" }, + { 0x10DE00F9, "GeForce 6800 Series GPU" }, + // 0100 - 010F + // 0110 - 011F + // 0120 - 012F + // 0130 - 013F + // 0140 - 014F + { 0x10DE0140, "GeForce 6600 GT" }, + { 0x10DE0141, "GeForce 6600" }, + { 0x10DE0142, "GeForce 6600 LE" }, + { 0x10DE0143, "GeForce 6600 VE" }, + { 0x10DE0144, "GeForce Go 6600" }, + { 0x10DE0145, "GeForce 6610 XL" }, + { 0x10DE0146, "GeForce Go 6600 TE/6200 TE" }, + { 0x10DE0147, "GeForce 6700 XL" }, + { 0x10DE0148, "GeForce Go 6600" }, + { 0x10DE0149, "GeForce Go 6600 GT" }, + { 0x10DE014A, "Quadro NVS 440" }, + { 0x10DE014C, "Quadro FX 550" }, + { 0x10DE014D, "Quadro FX 550" }, + { 0x10DE014E, "Quadro FX 540" }, + { 0x10DE014F, "GeForce 6200" }, + // 0150 - 015F + // 0160 - 016F + { 0x10DE0160, "GeForce 6500" }, + { 0x10DE0161, "GeForce 6200 TurboCache(TM)" }, + { 0x10DE0162, "GeForce 6200SE TurboCache(TM)" }, + { 0x10DE0163, "GeForce 6200 LE" }, + { 0x10DE0164, "GeForce Go 6200" }, + { 0x10DE0165, "Quadro NVS 285" }, + { 0x10DE0166, "GeForce Go 6400" }, + { 0x10DE0167, "GeForce Go 6200" }, + { 0x10DE0168, "GeForce Go 6400" }, + { 0x10DE0169, "GeForce 6250" }, + { 0x10DE016A, "GeForce 7100 GS" }, + // 0170 - 017F + // 0180 - 018F + // 0190 - 019F + { 0x10DE0191, "GeForce 8800 GTX" }, + { 0x10DE0193, "GeForce 8800 GTS" }, + { 0x10DE0194, "GeForce 8800 Ultra" }, + { 0x10DE0197, "Tesla C870" }, + { 0x10DE019D, "Quadro FX 5600" }, + { 0x10DE019E, "Quadro FX 4600" }, + // 01A0 - 01AF + // 01B0 - 01BF + // 01C0 - 01CF + // 01D0 - 01DF + { 0x10DE01D0, "GeForce 7350 LE" }, + { 0x10DE01D1, "GeForce 7300 LE" }, + { 0x10DE01D2, "GeForce 7550 LE" }, + { 0x10DE01D3, "GeForce 7300 SE/7200 GS" }, + { 0x10DE01D6, "GeForce Go 7200" }, + { 0x10DE01D7, "GeForce Go 7300" }, + { 0x10DE01D8, "GeForce Go 7400" }, + { 0x10DE01D9, "GeForce Go 7400 GS" }, + { 0x10DE01DA, "Quadro NVS 110M" }, + { 0x10DE01DB, "Quadro NVS 120M" }, + { 0x10DE01DC, "Quadro FX 350M" }, + { 0x10DE01DD, "GeForce 7500 LE" }, + { 0x10DE01DE, "Quadro FX 350" }, + { 0x10DE01DF, "GeForce 7300 GS" }, + // 01E0 - 01EF + // 01F0 - 01FF + // 0200 - 020F + // 0210 - 021F + { 0x10DE0211, "GeForce 6800" }, + { 0x10DE0212, "GeForce 6800 LE" }, + { 0x10DE0215, "GeForce 6800 GT" }, + { 0x10DE0218, "GeForce 6800 XT" }, + // 0220 - 022F + { 0x10DE0221, "GeForce 6200" }, + { 0x10DE0222, "GeForce 6200 A-LE" }, + // 0230 - 023F + // 0240 - 024F + { 0x10DE0240, "GeForce 6150" }, + { 0x10DE0241, "GeForce 6150 LE" }, + { 0x10DE0242, "GeForce 6100" }, + { 0x10DE0244, "GeForce Go 6150" }, + { 0x10DE0245, "Quadro NVS 210S / GeForce 6150LE" }, + { 0x10DE0247, "GeForce Go 6100" }, + // 0250 - 025F + // 0260 - 026F + // 0270 - 027F + // 0280 - 028F + // 0290 - 029F + { 0x10DE0290, "GeForce 7900 GTX" }, + { 0x10DE0291, "GeForce 7900 GT/GTO" }, + { 0x10DE0292, "GeForce 7900 GS" }, + { 0x10DE0293, "GeForce 7950 GX2" }, + { 0x10DE0294, "GeForce 7950 GX2" }, + { 0x10DE0295, "GeForce 7950 GT" }, + { 0x10DE0298, "GeForce Go 7900 GS" }, + { 0x10DE0299, "GeForce Go 7900 GTX" }, + { 0x10DE029A, "Quadro FX 2500M" }, + { 0x10DE029B, "Quadro FX 1500M" }, + { 0x10DE029C, "Quadro FX 5500" }, + { 0x10DE029D, "Quadro FX 3500" }, + { 0x10DE029E, "Quadro FX 1500" }, + { 0x10DE029F, "Quadro FX 4500 X2" }, + // 02A0 - 02AF + // 02B0 - 02BF + // 02C0 - 02CF + // 02D0 - 02DF + // 02E0 - 02EF + { 0x10DE02E0, "GeForce 7600 GT" }, + { 0x10DE02E1, "GeForce 7600 GS" }, + { 0x10DE02E2, "GeForce 7300 GT" }, + { 0x10DE02E3, "GeForce 7900 GS" }, + { 0x10DE02E4, "GeForce 7950 GT" }, + // 02F0 - 02FF + // 0300 - 030F + { 0x10DE0301, "GeForce FX 5800 Ultra" }, + { 0x10DE0302, "GeForce FX 5800" }, + { 0x10DE0308, "Quadro FX 2000" }, + { 0x10DE0309, "Quadro FX 1000" }, + // 0310 - 031F + { 0x10DE0311, "GeForce FX 5600 Ultra" }, + { 0x10DE0312, "GeForce FX 5600" }, + { 0x10DE0314, "GeForce FX 5600XT" }, + { 0x10DE031A, "GeForce FX Go5600" }, + { 0x10DE031B, "GeForce FX Go5650" }, + { 0x10DE031C, "Quadro FX Go700" }, + // 0320 - 032F + { 0x10DE0324, "GeForce FX Go5200" }, + { 0x10DE0325, "GeForce FX Go5250" }, + { 0x10DE0326, "GeForce FX 5500" }, + { 0x10DE0328, "GeForce FX Go5200 32M/64M" }, + { 0x10DE032A, "Quadro NVS 55/280 PCI" }, + { 0x10DE032B, "Quadro FX 500/600 PCI" }, + { 0x10DE032C, "GeForce FX Go53xx Series" }, + { 0x10DE032D, "GeForce FX Go5100" }, + // 0330 - 033F + { 0x10DE0330, "GeForce FX 5900 Ultra" }, + { 0x10DE0331, "GeForce FX 5900" }, + { 0x10DE0332, "GeForce FX 5900XT" }, + { 0x10DE0333, "GeForce FX 5950 Ultra" }, + { 0x10DE0334, "GeForce FX 5900ZT" }, + { 0x10DE0338, "Quadro FX 3000" }, + { 0x10DE033F, "Quadro FX 700" }, + // 0340 - 034F + { 0x10DE0341, "GeForce FX 5700 Ultra" }, + { 0x10DE0342, "GeForce FX 5700" }, + { 0x10DE0343, "GeForce FX 5700LE" }, + { 0x10DE0344, "GeForce FX 5700VE" }, + { 0x10DE0347, "GeForce FX Go5700" }, + { 0x10DE0348, "GeForce FX Go5700" }, + { 0x10DE034C, "Quadro FX Go1000" }, + { 0x10DE034E, "Quadro FX 1100" }, + // 0350 - 035F + // 0360 - 036F + // 0370 - 037F + // 0380 - 038F + { 0x10DE038B, "GeForce 7650 GS" }, + // 0390 - 039F + { 0x10DE0390, "GeForce 7650 GS" }, + { 0x10DE0391, "GeForce 7600 GT" }, + { 0x10DE0392, "GeForce 7600 GS" }, + { 0x10DE0393, "GeForce 7300 GT" }, + { 0x10DE0394, "GeForce 7600 LE" }, + { 0x10DE0395, "GeForce 7300 GT" }, + { 0x10DE0397, "GeForce Go 7700" }, + { 0x10DE0398, "GeForce Go 7600" }, + { 0x10DE0399, "GeForce Go 7600 GT"}, + { 0x10DE039A, "Quadro NVS 300M" }, + { 0x10DE039B, "GeForce Go 7900 SE" }, + { 0x10DE039C, "Quadro FX 550M" }, + { 0x10DE039E, "Quadro FX 560" }, + // 03A0 - 03AF + // 03B0 - 03BF + // 03C0 - 03CF + // 03D0 - 03DF + { 0x10DE03D0, "GeForce 6150SE nForce 430" }, + { 0x10DE03D1, "GeForce 6100 nForce 405" }, + { 0x10DE03D2, "GeForce 6100 nForce 400" }, + { 0x10DE03D5, "GeForce 6100 nForce 420" }, + { 0x10DE03D6, "GeForce 7025 / nForce 630a" }, + // 03E0 - 03EF + // 03F0 - 03FF + // 0400 - 040F + { 0x10DE0400, "GeForce 8600 GTS" }, + { 0x10DE0401, "GeForce 8600 GT" }, + { 0x10DE0402, "GeForce 8600 GT" }, + { 0x10DE0403, "GeForce 8600 GS" }, + { 0x10DE0404, "GeForce 8400 GS" }, + { 0x10DE0405, "GeForce 9500M GS" }, + { 0x10DE0406, "GeForce 8300 GS" }, + { 0x10DE0407, "GeForce 8600M GT" }, + { 0x10DE0408, "GeForce 9650M GS" }, + { 0x10DE0409, "GeForce 8700M GT" }, + { 0x10DE040A, "Quadro FX 370" }, + { 0x10DE040B, "Quadro NVS 320M" }, + { 0x10DE040C, "Quadro FX 570M" }, + { 0x10DE040D, "Quadro FX 1600M" }, + { 0x10DE040E, "Quadro FX 570" }, + { 0x10DE040F, "Quadro FX 1700" }, + // 0410 - 041F + { 0x10DE0410, "GeForce GT 330" }, + // 0420 - 042F + { 0x10DE0420, "GeForce 8400 SE" }, + { 0x10DE0421, "GeForce 8500 GT" }, + { 0x10DE0422, "GeForce 8400 GS" }, + { 0x10DE0423, "GeForce 8300 GS" }, + { 0x10DE0424, "GeForce 8400 GS" }, + { 0x10DE0425, "GeForce 8600M GS" }, + { 0x10DE0426, "GeForce 8400M GT" }, + { 0x10DE0427, "GeForce 8400M GS" }, + { 0x10DE0428, "GeForce 8400M G" }, + { 0x10DE0429, "Quadro NVS 140M" }, + { 0x10DE042A, "Quadro NVS 130M" }, + { 0x10DE042B, "Quadro NVS 135M" }, + { 0x10DE042C, "GeForce 9400 GT" }, + { 0x10DE042D, "Quadro FX 360M" }, + { 0x10DE042E, "GeForce 9300M G" }, + { 0x10DE042F, "Quadro NVS 290" }, + // 0430 - 043F + // 0440 - 044F + // 0450 - 045F + // 0460 - 046F + // 0470 - 047F + // 0480 - 048F + // 0490 - 049F + // 04A0 - 04AF + // 04B0 - 04BF + // 04C0 - 04CF + // 04D0 - 04DF + // 04E0 - 04EF + // 04F0 - 04FF + // 0500 - 050F + // 0510 - 051F + // 0520 - 052F + // 0530 - 053F + { 0x10DE053A, "GeForce 7050 PV / nForce 630a" }, + { 0x10DE053B, "GeForce 7050 PV / nForce 630a" }, + { 0x10DE053E, "GeForce 7025 / nForce 630a" }, + // 0540 - 054F + // 0550 - 055F + // 0560 - 056F + // 0570 - 057F + // 0580 - 058F + // 0590 - 059F + // 05A0 - 05AF + // 05B0 - 05BF + // 05C0 - 05CF + // 05D0 - 05DF + // 05E0 - 05EF + { 0x10DE05E0, "GeForce GTX 295" }, + { 0x10DE05E1, "GeForce GTX 280" }, + { 0x10DE05E2, "GeForce GTX 260" }, + { 0x10DE05E3, "GeForce GTX 285" }, + { 0x10DE05E6, "GeForce GTX 275" }, + { 0x10DE05EA, "GeForce GTX 260" }, + { 0x10DE05EB, "GeForce GTX 295" }, + { 0x10DE05ED, "Quadroplex 2200 D2" }, + // 05F0 - 05FF + { 0x10DE05F8, "Quadroplex 2200 S4" }, + { 0x10DE05F9, "Quadro CX" }, + { 0x10DE05FD, "Quadro FX 5800" }, + { 0x10DE05FE, "Quadro FX 4800" }, + { 0x10DE05FF, "Quadro FX 3800" }, + // 0600 - 060F + { 0x10DE0600, "GeForce 8800 GTS 512" }, + { 0x10DE0601, "GeForce 9800 GT" }, + { 0x10DE0602, "GeForce 8800 GT" }, + { 0x10DE0603, "GeForce GT 230" }, + { 0x10DE0604, "GeForce 9800 GX2" }, + { 0x10DE0605, "GeForce 9800 GT" }, + { 0x10DE0606, "GeForce 8800 GS" }, + { 0x10DE0607, "GeForce GTS 240" }, + { 0x10DE0608, "GeForce 9800M GTX" }, + { 0x10DE0609, "GeForce 8800M GTS" }, + { 0x10DE060A, "GeForce GTX 280M" }, + { 0x10DE060B, "GeForce 9800M GT" }, + { 0x10DE060C, "GeForce 8800M GTX" }, + { 0x10DE060D, "GeForce 8800 GS" }, + { 0x10DE060F, "GeForce GTX 285M" }, + // 0610 - 061F + { 0x10DE0610, "GeForce 9600 GSO" }, + { 0x10DE0611, "GeForce 8800 GT" }, + { 0x10DE0612, "GeForce 9800 GTX" }, + { 0x10DE0613, "GeForce 9800 GTX+" }, + { 0x10DE0614, "GeForce 9800 GT" }, + { 0x10DE0615, "GeForce GTS 250" }, + { 0x10DE0617, "GeForce 9800M GTX" }, + { 0x10DE0618, "GeForce GTX 260M" }, + { 0x10DE0619, "Quadro FX 4700 X2" }, + { 0x10DE061A, "Quadro FX 3700" }, + { 0x10DE061B, "Quadro VX 200" }, + { 0x10DE061C, "Quadro FX 3600M" }, + { 0x10DE061D, "Quadro FX 2800M" }, + { 0x10DE061F, "Quadro FX 3800M" }, + // 0620 - 062F + { 0x10DE0622, "GeForce 9600 GT" }, + { 0x10DE0623, "GeForce 9600 GS" }, + { 0x10DE0625, "GeForce 9600 GSO 512"}, + { 0x10DE0626, "GeForce GT 130" }, + { 0x10DE0627, "GeForce GT 140" }, + { 0x10DE0628, "GeForce 9800M GTS" }, + { 0x10DE062A, "GeForce 9700M GTS" }, + { 0x10DE062C, "GeForce 9800M GTS" }, + { 0x10DE062D, "GeForce 9600 GT" }, + { 0x10DE062E, "GeForce 9600 GT" }, + // 0630 - 063F + { 0x10DE0631, "GeForce GTS 160M" }, + { 0x10DE0632, "GeForce GTS 150M" }, + { 0x10DE0635, "GeForce 9600 GSO" }, + { 0x10DE0637, "GeForce 9600 GT" }, + { 0x10DE0638, "Quadro FX 1800" }, + { 0x10DE063A, "Quadro FX 2700M" }, + // 0640 - 064F + { 0x10DE0640, "GeForce 9500 GT" }, + { 0x10DE0641, "GeForce 9400 GT" }, + { 0x10DE0642, "GeForce 8400 GS" }, + { 0x10DE0643, "GeForce 9500 GT" }, + { 0x10DE0644, "GeForce 9500 GS" }, + { 0x10DE0645, "GeForce 9500 GS" }, + { 0x10DE0646, "GeForce GT 120" }, + { 0x10DE0647, "GeForce 9600M GT" }, + { 0x10DE0648, "GeForce 9600M GS" }, + { 0x10DE0649, "GeForce 9600M GT" }, + { 0x10DE064A, "GeForce 9700M GT" }, + { 0x10DE064B, "GeForce 9500M G" }, + { 0x10DE064C, "GeForce 9650M GT" }, + // 0650 - 065F + { 0x10DE0651, "GeForce G 110M" }, + { 0x10DE0652, "GeForce GT 130M" }, + { 0x10DE0653, "GeForce GT 120M" }, + { 0x10DE0654, "GeForce GT 220M" }, + { 0x10DE0656, "GeForce 9650 S" }, + { 0x10DE0658, "Quadro FX 380" }, + { 0x10DE0659, "Quadro FX 580" }, + { 0x10DE065A, "Quadro FX 1700M" }, + { 0x10DE065B, "GeForce 9400 GT" }, + { 0x10DE065C, "Quadro FX 770M" }, + { 0x10DE065F, "GeForce G210" }, + // 0660 - 066F + // 0670 - 067F + // 0680 - 068F + // 0690 - 069F + // 06A0 - 06AF + // 06B0 - 06BF + // 06C0 - 06CF + { 0x10DE06C0, "GeForce GTX 480" }, + { 0x10DE06C3, "GeForce GTX D12U" }, + { 0x10DE06C4, "GeForce GTX 465" }, + { 0x10DE06CA, "GeForce GTX 480M" }, + { 0x10DE06CD, "GeForce GTX 470" }, + // 06D0 - 06DF + { 0x10DE06D1, "Tesla C2050" }, // TODO: sub-device id: 0x0771 + { 0x10DE06D1, "Tesla C2070" }, // TODO: sub-device id: 0x0772 + { 0x10DE06D2, "Tesla M2070" }, + { 0x10DE06D8, "Quadro 6000" }, + { 0x10DE06D9, "Quadro 5000" }, + { 0x10DE06DA, "Quadro 5000M" }, + { 0x10DE06DC, "Quadro 6000" }, + { 0x10DE06DD, "Quadro 4000" }, + { 0x10DE06DE, "Tesla M2050" }, // TODO: sub-device id: 0x0846 + { 0x10DE06DE, "Tesla M2070" }, // TODO: sub-device id: ? + // 0x10DE06DE also applies to misc S2050, X2070, M2050, M2070 + // 06E0 - 06EF + { 0x10DE06E0, "GeForce 9300 GE" }, + { 0x10DE06E1, "GeForce 9300 GS" }, + { 0x10DE06E2, "GeForce 8400" }, + { 0x10DE06E3, "GeForce 8400 SE" }, + { 0x10DE06E4, "GeForce 8400 GS" }, + { 0x10DE06E5, "GeForce 9300M GS" }, + { 0x10DE06E6, "GeForce G100" }, + { 0x10DE06E7, "GeForce 9300 SE" }, + { 0x10DE06E8, "GeForce 9200M GS" }, + { 0x10DE06E9, "GeForce 9300M GS" }, + { 0x10DE06EA, "Quadro NVS 150M" }, + { 0x10DE06EB, "Quadro NVS 160M" }, + { 0x10DE06EC, "GeForce G 105M" }, + { 0x10DE06EF, "GeForce G 103M" }, + // 06F0 - 06FF + { 0x10DE06F8, "Quadro NVS 420" }, + { 0x10DE06F9, "Quadro FX 370 LP" }, + { 0x10DE06FA, "Quadro NVS 450" }, + { 0x10DE06FB, "Quadro FX 370M" }, + { 0x10DE06FD, "Quadro NVS 295" }, + // 0700 - 070F + // 0710 - 071F + // 0720 - 072F + // 0730 - 073F + // 0740 - 074F + // 0750 - 075F + // 0760 - 076F + // 0770 - 077F + // 0780 - 078F + // 0790 - 079F + // 07A0 - 07AF + // 07B0 - 07BF + // 07C0 - 07CF + // 07D0 - 07DF + // 07E0 - 07EF + { 0x10DE07E0, "GeForce 7150 / nForce 630i" }, + { 0x10DE07E1, "GeForce 7100 / nForce 630i" }, + { 0x10DE07E2, "GeForce 7050 / nForce 630i" }, + { 0x10DE07E3, "GeForce 7050 / nForce 610i" }, + { 0x10DE07E5, "GeForce 7050 / nForce 620i" }, + // 07F0 - 07FF + // 0800 - 080F + // 0810 - 081F + // 0820 - 082F + // 0830 - 083F + // 0840 - 084F + { 0x10DE0844, "GeForce 9100M G" }, + { 0x10DE0845, "GeForce 8200M G" }, + { 0x10DE0846, "GeForce 9200" }, + { 0x10DE0847, "GeForce 9100" }, + { 0x10DE0848, "GeForce 8300" }, + { 0x10DE0849, "GeForce 8200" }, + { 0x10DE084A, "nForce 730a" }, + { 0x10DE084B, "GeForce 9200" }, + { 0x10DE084C, "nForce 980a/780a SLI" }, + { 0x10DE084D, "nForce 750a SLI" }, + { 0x10DE084F, "GeForce 8100 / nForce 720a" }, + // 0850 - 085F + // 0860 - 086F + { 0x10DE0860, "GeForce 9400" }, + { 0x10DE0861, "GeForce 9400" }, + { 0x10DE0862, "GeForce 9400M G" }, + { 0x10DE0863, "GeForce 9400M" }, + { 0x10DE0864, "GeForce 9300" }, + { 0x10DE0865, "ION" }, + { 0x10DE0866, "GeForce 9400M G" }, + { 0x10DE0867, "GeForce 9400" }, + { 0x10DE0868, "nForce 760i SLI" }, + { 0x10DE086A, "GeForce 9400" }, + { 0x10DE086C, "GeForce 9300 / nForce 730i" }, + { 0x10DE086D, "GeForce 9200" }, + { 0x10DE086E, "GeForce 9100M G" }, + { 0x10DE086F, "GeForce 8200M G" }, + // 0870 - 087F + { 0x10DE0870, "GeForce 9400M" }, + { 0x10DE0871, "GeForce 9200" }, + { 0x10DE0872, "GeForce G102M" }, + { 0x10DE0873, "GeForce G102M" }, + { 0x10DE0874, "ION 9300M" }, + { 0x10DE0876, "ION" }, + { 0x10DE087A, "GeForce 9400" }, + { 0x10DE087D, "ION 9400M" }, + { 0x10DE087E, "ION LE" }, + { 0x10DE087F, "ION LE" }, + // 0880 - 088F + // 0890 - 089F + // 08A0 - 08AF + // 08B0 - 08BF + // 08C0 - 08CF + // 08D0 - 08DF + // 08E0 - 08EF + // 08F0 - 08FF + // 0900 - 090F + // 0910 - 091F + // 0920 - 092F + // 0930 - 093F + // 0940 - 094F + // 0950 - 095F + // 0960 - 096F + // 0970 - 097F + // 0980 - 098F + // 0990 - 099F + // 09A0 - 09AF + // 09B0 - 09BF + // 09C0 - 09CF + // 09D0 - 09DF + // 09E0 - 09EF + // 09F0 - 09FF + // 0A00 - 0A0F + // 0A10 - 0A1F + // 0A20 - 0A2F + { 0x10DE0A20, "GeForce GT220" }, + { 0x10DE0A22, "GeForce 315" }, + { 0x10DE0A23, "GeForce 210" }, + { 0x10DE0A28, "GeForce GT 230M" }, + { 0x10DE0A29, "GeForce GT 330M" }, + { 0x10DE0A2A, "GeForce GT 230M" }, + { 0x10DE0A2B, "GeForce GT 330M" }, + { 0x10DE0A2C, "NVS 5100M" }, + { 0x10DE0A2D, "GeForce GT 320M" }, + // 0A30 - 0A3F + { 0x10DE0A34, "GeForce GT 240M" }, + { 0x10DE0A35, "GeForce GT 325M" }, + { 0x10DE0A3C, "Quadro FX 880M" }, + // 0A40 - 0A4F + // 0A50 - 0A5F + // 0A60 - 0A6F + { 0x10DE0A60, "GeForce G210" }, + { 0x10DE0A62, "GeForce 205" }, + { 0x10DE0A63, "GeForce 310" }, + { 0x10DE0A64, "ION" }, + { 0x10DE0A65, "GeForce 210" }, + { 0x10DE0A66, "GeForce 310" }, + { 0x10DE0A67, "GeForce 315" }, + { 0x10DE0A68, "GeForce G105M" }, + { 0x10DE0A69, "GeForce G105M" }, + { 0x10DE0A6A, "NVS 2100M" }, + { 0x10DE0A6C, "NVS 3100M" }, + { 0x10DE0A6E, "GeForce 305M" }, + { 0x10DE0A6F, "ION" }, + // 0A70 - 0A7F + { 0x10DE0A70, "GeForce 310M" }, + { 0x10DE0A71, "GeForce 305M" }, + { 0x10DE0A72, "GeForce 310M" }, + { 0x10DE0A73, "GeForce 305M" }, + { 0x10DE0A74, "GeForce G210M" }, + { 0x10DE0A75, "GeForce G310M" }, + { 0x10DE0A78, "Quadro FX 380 LP" }, + { 0x10DE0A7C, "Quadro FX 380M" }, + // 0A80 - 0A8F + // 0A90 - 0A9F + // 0AA0 - 0AAF + // 0AB0 - 0ABF + // 0AC0 - 0ACF + // 0AD0 - 0ADF + // 0AE0 - 0AEF + // 0AF0 - 0AFF + // 0B00 - 0B0F + // 0B10 - 0B1F + // 0B20 - 0B2F + // 0B30 - 0B3F + // 0B40 - 0B4F + // 0B50 - 0B5F + // 0B60 - 0B6F + // 0B70 - 0B7F + // 0B80 - 0B8F + // 0B90 - 0B9F + // 0BA0 - 0BAF + // 0BB0 - 0BBF + // 0BC0 - 0BCF + // 0BD0 - 0BDF + // 0BE0 - 0BEF + // 0BF0 - 0BFF + // 0C00 - 0C0F + // 0C10 - 0C1F + // 0C20 - 0C2F + // 0C30 - 0C3F + // 0C40 - 0C4F + // 0C50 - 0C5F + // 0C60 - 0C6F + // 0C70 - 0C7F + // 0C80 - 0C8F + // 0C90 - 0C9F + // 0CA0 - 0CAF + { 0x10DE0CA0, "GeForce GT 330 " }, + { 0x10DE0CA2, "GeForce GT 320" }, + { 0x10DE0CA3, "GeForce GT 240" }, + { 0x10DE0CA4, "GeForce GT 340" }, + { 0x10DE0CA7, "GeForce GT 330" }, + { 0x10DE0CA8, "GeForce GTS 260M" }, + { 0x10DE0CA9, "GeForce GTS 250M" }, + { 0x10DE0CAC, "GeForce 315" }, + { 0x10DE0CAF, "GeForce GT 335M" }, + // 0CB0 - 0CBF + { 0x10DE0CB0, "GeForce GTS 350M" }, + { 0x10DE0CB1, "GeForce GTS 360M" }, + { 0x10DE0CBC, "Quadro FX 1800M" }, + // 0CC0 - 0CCF + // 0CD0 - 0CDF + // 0CE0 - 0CEF + // 0CF0 - 0CFF + // 0D00 - 0D0F + // 0D10 - 0D1F + // 0D20 - 0D2F + // 0D30 - 0D3F + // 0D40 - 0D4F + // 0D50 - 0D5F + // 0D60 - 0D6F + // 0D70 - 0D7F + // 0D80 - 0D8F + // 0D90 - 0D9F + // 0DA0 - 0DAF + // 0DB0 - 0DBF + // 0DC0 - 0DCF + { 0x10DE0DC0, "GeForce GT 440" }, + { 0x10DE0DC1, "D12-P1-35" }, + { 0x10DE0DC2, "D12-P1-35" }, + { 0x10DE0DC4, "GeForce GTS 450" }, + { 0x10DE0DC5, "GeForce GTS 450" }, + { 0x10DE0DC6, "GeForce GTS 450" }, + { 0x10DE0DCA, "GF10x" }, + // 0DD0 - 0DDF + { 0x10DE0DD1, "GeForce GTX 460M" }, + { 0x10DE0DD2, "GeForce GT 445M" }, + { 0x10DE0DD3, "GeForce GT 435M" }, + { 0x10DE0DD8, "Quadro 2000" }, + { 0x10DE0DDE, "GF106-ES" }, + { 0x10DE0DDF, "GF106-INT" }, + // 0DE0 - 0DEF + { 0x10DE0DE0, "GeForce GT 440" }, + { 0x10DE0DE1, "GeForce GT 430" }, + { 0x10DE0DE2, "GeForce GT 420" }, + { 0x10DE0DE5, "GeForce GT 530" }, + { 0x10DE0DEB, "GeForce GT 555M" }, + { 0x10DE0DEE, "GeForce GT 415M" }, + // 0DF0 - 0DFF + { 0x10DE0DF0, "GeForce GT 425M" }, + { 0x10DE0DF1, "GeForce GT 420M" }, + { 0x10DE0DF2, "GeForce GT 435M" }, + { 0x10DE0DF3, "GeForce GT 420M" }, + { 0x10DE0DF8, "Quadro 600" }, + { 0x10DE0DFE, "GF108 ES" }, + { 0x10DE0DFF, "GF108 INT" }, + // 0E00 - 0E0F + // 0E10 - 0E1F + // 0E20 - 0E2F + { 0x10DE0E21, "D12U-25" }, + { 0x10DE0E22, "GeForce GTX 460" }, + { 0x10DE0E23, "GeForce GTX 460 SE" }, + { 0x10DE0E24, "GeForce GTX 460" }, + { 0x10DE0E25, "D12U-50" }, + // 0E30 - 0E3F + { 0x10DE0E30, "GeForce GTX 470M" }, + { 0x10DE0E38, "GF104GL" }, + { 0x10DE0E3E, "GF104-ES" }, + { 0x10DE0E3F, "GF104-INT" }, + // 0E40 - 0E4F + // 0E50 - 0E5F + // 0E60 - 0E6F + // 0E70 - 0E7F + // 0E80 - 0E8F + // 0E90 - 0E9F + // 0EA0 - 0EAF + // 0EB0 - 0EBF + // 0EC0 - 0ECF + // 0ED0 - 0EDF + // 0EE0 - 0EEF + // 0EF0 - 0EFF + // 0F00 - 0F0F + // 0F10 - 0F1F + // 0F20 - 0F2F + // 0F30 - 0F3F + // 0F40 - 0F4F + // 0F50 - 0F5F + // 0F60 - 0F6F + // 0F70 - 0F7F + // 0F80 - 0F8F + // 0F90 - 0F9F + // 0FA0 - 0FAF + // 0FB0 - 0FBF + // 0FC0 - 0FCF + // 0FD0 - 0FDF + // 0FE0 - 0FEF + // 0FF0 - 0FFF + // 1000 - 100F + // 1010 - 101F + // 1020 - 102F + // 1030 - 103F + // 1040 - 104F + { 0x10DE1040, "GeForce GT 520" }, + // 1050 - 105F + { 0x10DE1050, "GeForce GT 520M" }, + // 1060 - 106F + // 1070 - 107F + // 1080 - 108F + { 0x10DE1080, "GeForce GTX 580" }, + { 0x10DE1081, "GeForce GTX 570" }, + { 0x10DE1082, "GeForce GTX 560 Ti" }, + { 0x10DE1083, "D13U" }, + { 0x10DE1088, "GeForce GTX 590" }, + // 1090 - 109F + { 0x10DE1098, "D13U" }, + { 0x10DE109A, "N12E-Q5" }, + // 10A0 - 10AF + // 10B0 - 10BF + // 10C0 - 10CF + { 0x10DE10C3, "GeForce 8400 GS" }, + // 1200 - + { 0x10DE1200, "GeForce GTX 560 Ti" }, + { 0x10DE1244, "GeForce GTX 550 Ti" }, + { 0x10DE1245, "GeForce GTS 450" }, +}; + +static uint16_t swap16(uint16_t x) +{ + return (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8)); +} + +static uint16_t read16(uint8_t *ptr, uint16_t offset) +{ + uint8_t ret[2]; + + ret[0] = ptr[offset+1]; + ret[1] = ptr[offset]; + + return *((uint16_t*)&ret); +} + +#if 0 +static uint32_t swap32(uint32_t x) +{ + return ((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8 ) | ((x & 0x00FF0000) >> 8 ) | ((x & 0xFF000000) >> 24); +} + +static uint8_t read8(uint8_t *ptr, uint16_t offset) +{ + return ptr[offset]; +} + +static uint32_t read32(uint8_t *ptr, uint16_t offset) +{ + uint8_t ret[4]; + + ret[0] = ptr[offset+3]; + ret[1] = ptr[offset+2]; + ret[2] = ptr[offset+1]; + ret[3] = ptr[offset]; + + return *((uint32_t*)&ret); +} +#endif + +static int patch_nvidia_rom(uint8_t *rom) +{ + if (!rom || (rom[0] != 0x55 && rom[1] != 0xaa)) { + printf("False ROM signature: 0x%02x%02x\n", rom[0], rom[1]); + pause(); + return PATCH_ROM_FAILED; + } + + uint16_t dcbptr = swap16(read16(rom, 0x36)); + + if (!dcbptr) { + printf("no dcb table found\n"); + pause(); + return PATCH_ROM_FAILED; + } +// else +// printf("dcb table at offset 0x%04x\n", dcbptr); + + uint8_t *dcbtable = &rom[dcbptr]; + uint8_t dcbtable_version = dcbtable[0]; + uint8_t headerlength = 0; + uint8_t numentries = 0; + uint8_t recordlength = 0; + + if (dcbtable_version >= 0x20) + { + uint32_t sig; + + if (dcbtable_version >= 0x30) + { + headerlength = dcbtable[1]; + numentries = dcbtable[2]; + recordlength = dcbtable[3]; + + sig = *(uint32_t *)&dcbtable[6]; + } + else + { + sig = *(uint32_t *)&dcbtable[4]; + headerlength = 8; + } + + if (sig != 0x4edcbdcb) + { + printf("Bad display config block signature (0x%8x)\n", sig); //Azi: issue #48 + pause(); + return PATCH_ROM_FAILED; + } + } + else if (dcbtable_version >= 0x14) /* some NV15/16, and NV11+ */ + { + char sig[8] = { 0 }; + + strncpy(sig, (char *)&dcbtable[-7], 7); + recordlength = 10; + + if (strcmp(sig, "DEV_REC")) + { + printf("Bad Display Configuration Block signature (%s)\n", sig); + pause(); + return PATCH_ROM_FAILED; + } + } + else + { + printf("ERROR: dcbtable_version is 0x%X\n", dcbtable_version); + pause(); + return PATCH_ROM_FAILED; + } + + if (numentries >= MAX_NUM_DCB_ENTRIES) + numentries = MAX_NUM_DCB_ENTRIES; + + uint8_t num_outputs = 0, i = 0; + + struct dcbentry + { + uint8_t type; + uint8_t index; + uint8_t *heads; + } entries[numentries]; + + for (i = 0; i < numentries; i++) + { + uint32_t connection; + connection = *(uint32_t *)&dcbtable[headerlength + recordlength * i]; + + /* Should we allow discontinuous DCBs? Certainly DCB I2C tables can be discontinuous */ + if ((connection & 0x0000000f) == 0x0000000f) /* end of records */ + continue; + if (connection == 0x00000000) /* seen on an NV11 with DCB v1.5 */ + continue; + if ((connection & 0xf) == 0x6) /* we skip type 6 as it doesnt appear on macbook nvcaps */ + continue; + + entries[num_outputs].type = connection & 0xf; + entries[num_outputs].index = num_outputs; + entries[num_outputs++].heads = (uint8_t*)&(dcbtable[(headerlength + recordlength * i) + 1]); + } + + int has_lvds = false; + uint8_t channel1 = 0, channel2 = 0; + + for (i = 0; i < num_outputs; i++) + { + if (entries[i].type == 3) + { + has_lvds = true; + //printf("found LVDS\n"); + channel1 |= ( 0x1 << entries[i].index); + entries[i].type = TYPE_GROUPED; + } + } + + // if we have a LVDS output, we group the rest to the second channel + if (has_lvds) + { + for (i = 0; i < num_outputs; i++) + { + if (entries[i].type == TYPE_GROUPED) + continue; + + channel2 |= ( 0x1 << entries[i].index); + entries[i].type = TYPE_GROUPED; + } + } + else + { + int x; + // we loop twice as we need to generate two channels + for (x = 0; x <= 1; x++) + { + for (i=0; i channel2) + { + uint8_t buff = channel1; + channel1 = channel2; + channel2 = buff; + } + + default_NVCAP[6] = channel1; + default_NVCAP[8] = channel2; + + // patching HEADS + for (i = 0; i < num_outputs; i++) + { + if (channel1 & (1 << i)) + { + *entries[i].heads = 1; + } + else if(channel2 & (1 << i)) + { + *entries[i].heads = 2; + } + } + return (has_lvds ? PATCH_ROM_SUCCESS_HAS_LVDS : PATCH_ROM_SUCCESS); +} + +static char *get_nvidia_model(uint32_t id) +{ + int i; + + for (i = 1; i < (sizeof(NVKnownChipsets) / sizeof(NVKnownChipsets[0])); i++) { + if (NVKnownChipsets[i].device == id) + { + return NVKnownChipsets[i].name; + } + } + return NVKnownChipsets[0].name; +} + +static uint32_t load_nvidia_bios_file(const char *filename, uint8_t *buf, int bufsize) +{ + int fd; + int size; + + if ((fd = open_bvdev("bt(0,0)", filename, 0)) < 0) + { + return 0; + } + + size = file_size(fd); + + if (size > bufsize) + { + printf("Filesize of %s is bigger than expected! Truncating to 0x%x Bytes!\n", + filename, bufsize); + size = bufsize; + } + size = read(fd, (char *)buf, size); + close(fd); + + return size > 0 ? size : 0; +} + +static int devprop_add_nvidia_template(struct DevPropDevice *device) +{ + char tmp[16]; + + if (!device) + return 0; + + if (!DP_ADD_TEMP_VAL(device, nvidia_compatible_0)) + return 0; + if (!DP_ADD_TEMP_VAL(device, nvidia_device_type_0)) + return 0; + if (!DP_ADD_TEMP_VAL(device, nvidia_name_0)) + return 0; + if (!DP_ADD_TEMP_VAL(device, nvidia_compatible_1)) + return 0; + if (!DP_ADD_TEMP_VAL(device, nvidia_device_type_1)) + return 0; + if (!DP_ADD_TEMP_VAL(device, nvidia_name_1)) + return 0; + if (!DP_ADD_TEMP_VAL(device, nvidia_device_type)) + return 0; + + // Rek : Dont use sprintf return, it does not WORK !! our custom sprintf() always return 0! + // len = sprintf(tmp, "Slot-%x", devices_number); + sprintf(tmp, "Slot-%x",devices_number); + devprop_add_value(device, "AAPL,slot-name", (uint8_t *) tmp, strlen(tmp)); + devices_number++; + + return 1; +} + +int hex2bin(const char *hex, uint8_t *bin, int len) +{ + char *p; + int i; + char buf[3]; + + if (hex == NULL || bin == NULL || len <= 0 || strlen(hex) != len * 2) { + printf("[ERROR] bin2hex input error\n"); + return -1; + } + + buf[2] = '\0'; + p = (char *) hex; + + for (i = 0; i < len; i++) + { + if (p[0] == '\0' || p[1] == '\0' || !isxdigit(p[0]) || !isxdigit(p[1])) { + printf("[ERROR] bin2hex '%s' syntax error\n", hex); + return -2; + } + buf[0] = *p++; + buf[1] = *p++; + bin[i] = (unsigned char) strtoul(buf, NULL, 16); + } + 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(NV04_PFB_FIFO_DATA); + vram_size |= (vram_size & 0xff) << 32; + vram_size &= 0xffffffff00ll; + } + else // >= NV_ARCH_C0 + { + vram_size = REG32(NVC0_MEM_CTRLR_RAM_AMOUNT) << 20; + vram_size *= REG32(NVC0_MEM_CTRLR_COUNT); + } + + // Workaround for GT 420/430 & 9600M GT + switch (nvda_dev->device_id) + { + case 0x0DE1: vram_size = 1024*1024*1024; break; // GT 430 + case 0x0DE2: vram_size = 1024*1024*1024; break; // GT 420 + case 0x0649: vram_size = 512*1024*1024; break; // 9600M GT + default: break; + } + + return vram_size; +} + +bool setup_nvidia_devprop(pci_dt_t *nvda_dev) +{ + struct DevPropDevice *device; + char *devicepath; + option_rom_pci_header_t *rom_pci_header; + volatile uint8_t *regs; + uint8_t *rom; + uint8_t *nvRom; + uint8_t nvCardType; + unsigned long long videoRam; + uint32_t nvBiosOveride; + uint32_t bar[7]; + uint32_t boot_display; + int nvPatch; + int len; + char biosVersion[32]; + char nvFilename[32]; + char kNVCAP[12]; + char *model; + const char *value; + bool doit; + + devicepath = get_pci_dev_path(nvda_dev); + bar[0] = pci_config_read32(nvda_dev->dev.addr, 0x10 ); + regs = (uint8_t *) (bar[0] & ~0x0f); + + // get card type + nvCardType = (REG32(0) >> 20) & 0x1ff; + + // Amount of VRAM in kilobytes + 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, (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); + + if (getBoolForKey(kUseNvidiaROM, &doit, &bootInfo->chameleonConfig) && doit) + { + verbose("Looking for nvidia video bios file %s\n", nvFilename); + nvBiosOveride = load_nvidia_bios_file(nvFilename, rom, NVIDIA_ROM_SIZE); + + if (nvBiosOveride > 0) + { + verbose("Using nVidia Video BIOS File %s (%d Bytes)\n", nvFilename, nvBiosOveride); + DBG("%s Signature 0x%02x%02x %d bytes\n", nvFilename, rom[0], rom[1], nvBiosOveride); + } + else + { + printf("ERROR: unable to open nVidia Video BIOS File %s\n", nvFilename); + return false; + } + } + else + { + // Otherwise read bios from card + nvBiosOveride = 0; + + // TODO: we should really check for the signature before copying the rom, i think. + + // PRAMIN first + nvRom = (uint8_t*)®s[NV_PRAMIN_OFFSET]; + bcopy((uint32_t *)nvRom, rom, NVIDIA_ROM_SIZE); + + // Valid Signature ? + if (rom[0] != 0x55 && rom[1] != 0xaa) + { + // PROM next + // Enable PROM access + (REG32(NV_PBUS_PCI_NV_20)) = NV_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED; + + nvRom = (uint8_t*)®s[NV_PROM_OFFSET]; + bcopy((uint8_t *)nvRom, rom, NVIDIA_ROM_SIZE); + + // disable PROM access + (REG32(NV_PBUS_PCI_NV_20)) = NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED; + + // Valid Signature ? + if (rom[0] != 0x55 && rom[1] != 0xaa) + { + // 0xC0000 last + bcopy((char *)0xc0000, rom, NVIDIA_ROM_SIZE); + + // Valid Signature ? + if (rom[0] != 0x55 && rom[1] != 0xaa) + { + printf("ERROR: Unable to locate nVidia Video BIOS\n"); + return false; + } + else + { + DBG("ROM Address 0x%x Signature 0x%02x%02x\n", nvRom, rom[0], rom[1]); + } + } + else + { + DBG("PROM Address 0x%x Signature 0x%02x%02x\n", nvRom, rom[0], rom[1]); + } + } + else + { + DBG("PRAM Address 0x%x Signature 0x%02x%02x\n", nvRom, rom[0], rom[1]); + } + } + + if ((nvPatch = patch_nvidia_rom(rom)) == PATCH_ROM_FAILED) { + printf("ERROR: nVidia ROM Patching Failed!\n"); + pause(); + //return false; + } + + rom_pci_header = (option_rom_pci_header_t*)(rom + *(uint16_t *)&rom[24]); + + // check for 'PCIR' sig + if (rom_pci_header->signature == 0x50434952) + { + if (rom_pci_header->device_id != nvda_dev->device_id) + { + // Get Model from the OpROM + model = get_nvidia_model((rom_pci_header->vendor_id << 16) | rom_pci_header->device_id); + } + else + { + printf("nVidia incorrect PCI ROM signature: 0x%x\n", rom_pci_header->signature); + } + } + + if (!string) { + string = devprop_create_string(); + } + device = devprop_add_device(string, devicepath); + + /* FIXME: for primary graphics card only */ + boot_display = 1; + devprop_add_value(device, "@0,AAPL,boot-display", (uint8_t*)&boot_display, 4); + + if (nvPatch == PATCH_ROM_SUCCESS_HAS_LVDS) { + 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); + sprintf(kNVCAP, "NVCAP_%04x", nvda_dev->device_id); + + if (getValueForKey(kNVCAP, &value, &len, &bootInfo->chameleonConfig) && len == NVCAP_LEN * 2) + { + uint8_t new_NVCAP[NVCAP_LEN]; + + if (hex2bin(value, new_NVCAP, NVCAP_LEN) == 0) + { + verbose("Using user supplied NVCAP for %s :: %s\n", model, devicepath); + memcpy(default_NVCAP, new_NVCAP, NVCAP_LEN); + } + } + + if (getValueForKey(kDcfg0, &value, &len, &bootInfo->chameleonConfig) && len == DCFG0_LEN * 2) + { + uint8_t new_dcfg0[DCFG0_LEN]; + + if (hex2bin(value, new_dcfg0, DCFG0_LEN) == 0) + { + memcpy(default_dcfg_0, new_dcfg0, DCFG0_LEN); + + verbose("Using user supplied @0,display-cfg\n"); + printf("@0,display-cfg: %02x%02x%02x%02x\n", + default_dcfg_0[0], default_dcfg_0[1], default_dcfg_0[2], default_dcfg_0[3]); + } + } + + if (getValueForKey(kDcfg1, &value, &len, &bootInfo->chameleonConfig) && len == DCFG1_LEN * 2) + { + uint8_t new_dcfg1[DCFG1_LEN]; + + if (hex2bin(value, new_dcfg1, DCFG1_LEN) == 0) + { + memcpy(default_dcfg_1, new_dcfg1, DCFG1_LEN); + + verbose("Using user supplied @1,display-cfg\n"); + printf("@1,display-cfg: %02x%02x%02x%02x\n", + default_dcfg_1[0], default_dcfg_1[1], default_dcfg_1[2], default_dcfg_1[3]); + } + } + +#if DEBUG_NVCAP + printf("NVCAP: %02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x\n", + default_NVCAP[0], default_NVCAP[1], default_NVCAP[2], default_NVCAP[3], + default_NVCAP[4], default_NVCAP[5], default_NVCAP[6], default_NVCAP[7], + default_NVCAP[8], default_NVCAP[9], default_NVCAP[10], default_NVCAP[11], + default_NVCAP[12], default_NVCAP[13], default_NVCAP[14], default_NVCAP[15], + default_NVCAP[16], default_NVCAP[17], default_NVCAP[18], default_NVCAP[19]); +#endif + + devprop_add_nvidia_template(device); + devprop_add_value(device, "NVCAP", default_NVCAP, NVCAP_LEN); + devprop_add_value(device, "VRAM,totalsize", (uint8_t*)&videoRam, 4); + devprop_add_value(device, "model", (uint8_t*)model, strlen(model) + 1); + devprop_add_value(device, "rom-revision", (uint8_t*)biosVersion, strlen(biosVersion) + 1); + devprop_add_value(device, "@0,display-cfg", default_dcfg_0, DCFG0_LEN); + devprop_add_value(device, "@1,display-cfg", default_dcfg_1, DCFG1_LEN); + + //add HDMI Audio back to nvidia + //http://forge.voodooprojects.org/p/chameleon/issues/67/ +// uint8_t connector_type_1[]= {0x00, 0x08, 0x00, 0x00}; +// devprop_add_value(device, "@1,connector-type",connector_type_1, 4); + //end Nvidia HDMI Audio + + if (getBoolForKey(kVBIOS, &doit, &bootInfo->chameleonConfig) && doit) + { + devprop_add_value(device, "vbios", rom, (nvBiosOveride > 0) ? nvBiosOveride : (rom[2] * 512)); + } + + stringdata = malloc(sizeof(uint8_t) * string->length); + memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length); + stringlength = string->length; + + return true; +} Index: branches/slice/trunkM/i386/libsaio/ati.c =================================================================== --- branches/slice/trunkM/i386/libsaio/ati.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/ati.c (revision 1171) @@ -0,0 +1,1266 @@ +/* + * ATI Graphics Card Enabler, part of the Chameleon Boot Loader Project + * + * Copyright 2010 by Islam M. Ahmed Zaid. All rights reserved. + * + */ + +#include "boot.h" +#include "bootstruct.h" +#include "pci.h" +#include "platform.h" +#include "device_inject.h" +#include "ati_reg.h" + +#define OFFSET_TO_GET_ATOMBIOS_STRINGS_START 0x6e + +#define Reg32(reg) (*(volatile uint32_t *)(card->mmio + reg)) +#define RegRead32(reg) (Reg32(reg)) +#define RegWrite32(reg, value) (Reg32(reg) = value) + +typedef enum { + kNul, + kStr, + kPtr, + kCst +} type_t; + +typedef enum { + CHIP_FAMILY_UNKNOW, + CHIP_FAMILY_RS600, + CHIP_FAMILY_RS690, + CHIP_FAMILY_RS740, + /* R600 */ + CHIP_FAMILY_R600, + CHIP_FAMILY_RV610, + CHIP_FAMILY_RV630, + CHIP_FAMILY_RV670, + CHIP_FAMILY_RV620, + CHIP_FAMILY_RV635, + CHIP_FAMILY_RS780, + CHIP_FAMILY_RS880, + /* R700 */ + CHIP_FAMILY_RV770, + CHIP_FAMILY_RV730, + CHIP_FAMILY_RV710, + CHIP_FAMILY_RV740, + /* Evergreen */ + CHIP_FAMILY_CEDAR, + CHIP_FAMILY_REDWOOD, + CHIP_FAMILY_JUNIPER, + CHIP_FAMILY_CYPRESS, + CHIP_FAMILY_HEMLOCK, +// CHIP_FAMILY_GRANVILLE, //Azi:--- + /* Northern Islands */ + CHIP_FAMILY_BARTS, + CHIP_FAMILY_CAICOS, + CHIP_FAMILY_CAYMAN, + CHIP_FAMILY_TURKS, + CHIP_FAMILY_LAST +} chip_family_t; + +static const char *chip_family_name[] = { + "UNKNOW", + "RS600", + "RS690", + "RS740", + /* R600 */ + "R600", + "RV610", + "RV630", + "RV670", + "RV620", + "RV635", + "RS780", + "RS880", + /* R700 */ + "RV770", + "RV730", + "RV710", + "RV740", + /* Evergreen */ + "Cedar", // RV810 + "Redwood", // RV830 + "Juniper", // RV840 + "Cypress", // RV870 + "Hemlock", +// "Granville" //Azi:--- + /* Northern Islands */ + "Barts", + "Caicos", + "Cayman", + "Turks", + "" +}; + +typedef struct { + const char *name; + uint8_t ports; +} card_config_t; + +static card_config_t card_configs[] = { + {NULL, 0}, + {"Alopias", 2}, + {"Alouatta", 4}, + {"Baboon", 3}, + {"Cardinal", 2}, + {"Caretta", 1}, + {"Colobus", 2}, + {"Douc", 2}, + {"Eulemur", 3}, + {"Flicker", 3}, + {"Galago", 2}, + {"Gliff", 3}, + {"Hoolock", 3}, + {"Hypoprion", 2}, + {"Iago", 2}, + {"Kakapo", 3}, + {"Kipunji", 4}, + {"Lamna", 2}, + {"Langur", 3}, + {"Megalodon", 3}, + {"Motmot", 2}, + {"Nomascus", 5}, + {"Orangutan", 2}, + {"Peregrine", 2}, + {"Quail", 3}, + {"Raven", 3}, + {"Shrike", 3}, + {"Sphyrna", 1}, + {"Triakis", 2}, + {"Uakari", 4}, + {"Vervet", 4}, + {"Zonalis", 6}, + {"Pithecia", 3}, + {"Bulrushes", 6}, + {"Cattail", 4}, + {"Hydrilla", 5}, + {"Duckweed", 4}, + {"Fanwort", 4}, + {"Elodea", 5}, + {"Kudzu", 2}, + {"Gibba", 5}, + {"Lotus", 3}, + {"Ipomoea", 3}, + {"Mangabey", 2}, + {"Muskgrass", 4}, + {"Juncus", 4} +}; + +typedef enum { + kNull, + kAlopias, + kAlouatta, + kBaboon, + kCardinal, + kCaretta, + kColobus, + kDouc, + kEulemur, + kFlicker, + kGalago, + kGliff, + kHoolock, + kHypoprion, + kIago, + kKakapo, + kKipunji, + kLamna, + kLangur, + kMegalodon, + kMotmot, + kNomascus, + kOrangutan, + kPeregrine, + kQuail, + kRaven, + kShrike, + kSphyrna, + kTriakis, + kUakari, + kVervet, + kZonalis, + kPithecia, + kBulrushes, + kCattail, + kHydrilla, + kDuckweed, + kFanwort, + kElodea, + kKudzu, + kGibba, + kLotus, + kIpomoea, + kMangabey, + kMuskgrass, + kJuncus, + kCfgEnd +} config_name_t; + +typedef struct { + uint16_t device_id; + uint32_t subsys_id; + chip_family_t chip_family; + const char *model_name; + config_name_t cfg_name; +} radeon_card_info_t; + +static radeon_card_info_t radeon_cards[] = { + //Azi: added devices +// temporary placement + // issue #88 + { 0x6741, 0x1646103C, CHIP_FAMILY_TURKS,/*???*/"AMD Radeon HD 6600M Series", kNull }, + // issue #89 + { 0x68A8, 0x050E1025, CHIP_FAMILY_CYPRESS, "AMD Radeon HD 6850M", kUakari }, //Azi: CHIP_FAMILY_GRANVILLE ?? + // issue #90 + { 0x68E4, 0x1c921043, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5470M", kEulemur }, + // issue #91 + { 0x68C0, 0x1594103C, CHIP_FAMILY_REDWOOD, "AMD Radeon HD 6570M", kNull }, + + //==================================//================================//============================// + + /* Earlier cards are not supported */ + { 0x9400, 0x30001002, CHIP_FAMILY_R600, "ATI Radeon HD 2900 PRO", kNull }, + { 0x9400, 0x25521002, CHIP_FAMILY_R600, "ATI Radeon HD 2900 XT", kNull }, + + { 0x9440, 0x24401682, CHIP_FAMILY_RV770, "ATI Radeon HD 4870", kMotmot }, + { 0x9440, 0x24411682, CHIP_FAMILY_RV770, "ATI Radeon HD 4870", kMotmot }, + { 0x9440, 0x24441682, CHIP_FAMILY_RV770, "ATI Radeon HD 4870", kMotmot }, + { 0x9440, 0x24451682, CHIP_FAMILY_RV770, "ATI Radeon HD 4870", kMotmot }, + + { 0x9441, 0x24401682, CHIP_FAMILY_RV770, "ATI Radeon HD 4870 X2", kMotmot }, + + { 0x9442, 0x24701682, CHIP_FAMILY_RV770, "ATI Radeon HD 4850", kMotmot }, + { 0x9442, 0x24711682, CHIP_FAMILY_RV770, "ATI Radeon HD 4850", kMotmot }, + { 0x9442, 0x080110B0, CHIP_FAMILY_RV770, "ATI Radeon HD 4850", kMotmot }, + { 0x9442, 0xE104174B, CHIP_FAMILY_RV770, "ATI Radeon HD 4850", kMotmot }, + + { 0x944A, 0x30001682, CHIP_FAMILY_RV770, "ATI Radeon HD 4800 Series", kMotmot }, + { 0x944A, 0x30001043, CHIP_FAMILY_RV770, "ATI Radeon HD 4800 Series", kMotmot }, + { 0x944A, 0x30001458, CHIP_FAMILY_RV770, "ATI Radeon HD 4800 Series", kMotmot }, + { 0x944A, 0x30001462, CHIP_FAMILY_RV770, "ATI Radeon HD 4800 Series", kMotmot }, + { 0x944A, 0x30001545, CHIP_FAMILY_RV770, "ATI Radeon HD 4800 Series", kMotmot }, + { 0x944A, 0x30001787, CHIP_FAMILY_RV770, "ATI Radeon HD 4800 Series", kMotmot }, + { 0x944A, 0x3000174B, CHIP_FAMILY_RV770, "ATI Radeon HD 4800 Series", kMotmot }, + { 0x944A, 0x300017AF, CHIP_FAMILY_RV770, "ATI Radeon HD 4800 Series", kMotmot }, + + { 0x944C, 0x24801682, CHIP_FAMILY_RV770, "ATI Radeon HD 4830", kMotmot }, + { 0x944C, 0x24811682, CHIP_FAMILY_RV770, "ATI Radeon HD 4830", kMotmot }, + + { 0x944E, 0x3260174B, CHIP_FAMILY_RV770, "ATI Radeon HD 4810 Series", kMotmot }, + { 0x944E, 0x3261174B, CHIP_FAMILY_RV770, "ATI Radeon HD 4810 series", kMotmot }, + { 0x944E, 0x30001787, CHIP_FAMILY_RV770, "ATI Radeon HD 4730 Series", kMotmot }, + { 0x944E, 0x30101787, CHIP_FAMILY_RV770, "ATI Radeon HD 4810 Series", kMotmot }, + { 0x944E, 0x31001787, CHIP_FAMILY_RV770, "ATI Radeon HD 4820", kMotmot }, + + { 0x9490, 0x30501787, CHIP_FAMILY_RV730, "ATI Radeon HD 4710", kNull }, + { 0x9490, 0x4710174B, CHIP_FAMILY_RV730, "ATI Radeon HD 4710", kNull }, + { 0x9490, 0x300017AF, CHIP_FAMILY_RV730, "ATI Radeon HD 4710", kNull }, + + { 0x9498, 0x30501787, CHIP_FAMILY_RV730, "ATI Radeon HD 4700", kNull }, + { 0x9498, 0x31001787, CHIP_FAMILY_RV730, "ATI Radeon HD 4720", kNull }, + { 0x9498, 0x24511682, CHIP_FAMILY_RV730, "ATI Radeon HD 4650", kNull }, + { 0x9498, 0x24521682, CHIP_FAMILY_RV730, "ATI Radeon HD 4650", kNull }, + { 0x9498, 0x24541682, CHIP_FAMILY_RV730, "ATI Radeon HD 4650", kNull }, + { 0x9498, 0x29331682, CHIP_FAMILY_RV730, "ATI Radeon HD 4670", kNull }, + { 0x9498, 0x29341682, CHIP_FAMILY_RV730, "ATI Radeon HD 4670", kNull }, + { 0x9498, 0x21CF1458, CHIP_FAMILY_RV730, "ATI Radeon HD 4600 Series", kNull }, + + { 0x94B3, 0x29001682, CHIP_FAMILY_RV740, "ATI Radeon HD 4770", kFlicker }, + { 0x94B3, 0x1170174B, CHIP_FAMILY_RV740, "ATI Radeon HD 4770", kFlicker }, + { 0x94B3, 0x10020D00, CHIP_FAMILY_RV740, "ATI Radeon HD 4770", kFlicker }, + + { 0x94C1, 0x10021002, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 Pro", kNull }, + { 0x94C1, 0x0D021002, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 XT", kNull }, + { 0x94C1, 0x0D021028, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 Pro", kNull }, + { 0x94C1, 0x0D021028, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 XT", kNull }, + { 0x94C1, 0x21741458, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 XT", kNull }, + { 0x94C1, 0x10401462, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 XT", kNull }, + { 0x94C1, 0x10331462, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 XT", kNull }, + { 0x94C1, 0x10331462, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 XT", kNull }, + { 0x94C1, 0x11101462, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 XT", kNull }, + + { 0x94C3, 0x37161642, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 PRO", kNull }, + { 0x94C3, 0x30001642, CHIP_FAMILY_RV610, "ATI Radeon HD 3410", kNull }, + { 0x94C3, 0x03421002, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 PRO", kNull }, + { 0x94C3, 0x30001025, CHIP_FAMILY_RV610, "ATI Radeon HD 2350 Series", kNull }, + { 0x94C3, 0x04021028, CHIP_FAMILY_RV610, "ATI Radeon HD 2400", kNull }, + { 0x94C3, 0x03021028, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 PRO", kNull }, + { 0x94C3, 0x04021028, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 PRO", kNull }, + { 0x94C3, 0x216A1458, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 PRO", kNull }, + { 0x94C3, 0x21721458, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 PRO", kNull }, + { 0x94C3, 0x30001458, CHIP_FAMILY_RV610, "ATI Radeon HD 3410", kNull }, + { 0x94C3, 0x11041462, CHIP_FAMILY_RV610, "ATI Radeon HD 2400", kNull }, + { 0x94C3, 0x10411462, CHIP_FAMILY_RV610, "ATI Radeon HD 2400", kNull }, + { 0x94C3, 0x11051462, CHIP_FAMILY_RV610, "ATI Radeon HD 2400", kNull }, + { 0x94C3, 0x10321462, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 PRO", kNull }, + { 0x94C3, 0x30001462, CHIP_FAMILY_RV610, "ATI Radeon HD 3410", kNull }, + { 0x94C3, 0x3000148C, CHIP_FAMILY_RV610, "ATI Radeon HD 2350 Series", kNull }, + { 0x94C3, 0x2247148C, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 LE", kNull }, + { 0x94C3, 0x3000174B, CHIP_FAMILY_RV610, "ATI Radeon HD 2350 Series", kNull }, + { 0x94C3, 0xE400174B, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 PRO", kNull }, + { 0x94C3, 0xE370174B, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 PRO", kNull }, + { 0x94C3, 0xE400174B, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 PRO", kNull }, + { 0x94C3, 0xE370174B, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 PRO", kNull }, + { 0x94C3, 0xE400174B, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 PRO", kNull }, + { 0x94C3, 0x203817AF, CHIP_FAMILY_RV610, "ATI Radeon HD 2400", kNull }, + { 0x94C3, 0x30001787, CHIP_FAMILY_RV610, "ATI Radeon HD 2350 Series", kNull }, + { 0x94C3, 0x22471787, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 LE", kNull }, + { 0x94C3, 0x01011A93, CHIP_FAMILY_RV610, "Qimonda Radeon HD 2400 PRO", kNull }, + + { 0x9501, 0x30001002, CHIP_FAMILY_RV670, "ATI Radeon HD 3690", kNull }, + { 0x9501, 0x25421002, CHIP_FAMILY_RV670, "ATI Radeon HD 3870", kNull }, + { 0x9501, 0x4750174B, CHIP_FAMILY_RV670, "ATI Radeon HD 4750", kNull }, + { 0x9501, 0x3000174B, CHIP_FAMILY_RV670, "Sapphire Radeon HD 3690", kNull }, + { 0x9501, 0x30001787, CHIP_FAMILY_RV670, "ATI Radeon HD 3690", kNull }, + + { 0x9505, 0x30001002, CHIP_FAMILY_RV670, "ATI Radeon HD 3690", kNull }, + { 0x9505, 0x25421002, CHIP_FAMILY_RV670, "ATI Radeon HD 3850", kNull }, + { 0x9505, 0x30011043, CHIP_FAMILY_RV670, "ATI Radeon HD 4730", kNull }, + { 0x9505, 0x3000148C, CHIP_FAMILY_RV670, "ATI Radeon HD 3850", kNull }, + { 0x9505, 0x3002148C, CHIP_FAMILY_RV670, "ATI Radeon HD 4730", kNull }, + { 0x9505, 0x3001148C, CHIP_FAMILY_RV670, "ATI Radeon HD 4730", kNull }, + { 0x9505, 0x3003148C, CHIP_FAMILY_RV670, "ATI Radeon HD 4750", kNull }, + { 0x9505, 0x3004148C, CHIP_FAMILY_RV670, "ATI Radeon HD 4750", kNull }, + { 0x9505, 0x4730174B, CHIP_FAMILY_RV670, "ATI Radeon HD 4730", kNull }, + { 0x9505, 0x3010174B, CHIP_FAMILY_RV670, "ATI Radeon HD 4750", kNull }, + { 0x9505, 0x3001174B, CHIP_FAMILY_RV670, "ATI Radeon HD 4750", kNull }, + { 0x9505, 0x3000174B, CHIP_FAMILY_RV670, "Sapphire Radeon HD 3690", kNull }, + { 0x9505, 0x30001787, CHIP_FAMILY_RV670, "ATI Radeon HD 3690", kNull }, + { 0x9505, 0x301017AF, CHIP_FAMILY_RV670, "ATI Radeon HD 4750", kNull }, + + { 0x9540, 0x4590174B, CHIP_FAMILY_RV710, "ATI Radeon HD 4590", kNull }, + { 0x9540, 0x30501787, CHIP_FAMILY_RV710, "ATI Radeon HD 4590", kNull }, + + { 0x954F, 0x29201682, CHIP_FAMILY_RV710, "ATI Radeon HD 4550", kNull }, + { 0x954F, 0x29211682, CHIP_FAMILY_RV710, "ATI Radeon HD 4550", kNull }, + { 0x954F, 0x30901682, CHIP_FAMILY_RV710, "XFX Radeon HD 4570", kNull }, + { 0x954F, 0x4450174B, CHIP_FAMILY_RV710, "ATI Radeon HD 4450", kNull }, + { 0x954F, 0x3000174B, CHIP_FAMILY_RV710, "ATI Radeon HD 4520", kNull }, + { 0x954F, 0x30501787, CHIP_FAMILY_RV710, "ATI Radeon HD 4450", kNull }, + { 0x954F, 0x31001787, CHIP_FAMILY_RV710, "ATI Radeon HD 4520", kNull }, + { 0x954F, 0x4570174B, CHIP_FAMILY_RV710, "Sapphire Radeon HD4570", kNull }, + { 0x954F, 0x301017AF, CHIP_FAMILY_RV710, "ATI Radeon HD 4450", kNull }, + + { 0x9552, 0x3000148C, CHIP_FAMILY_RV710, "ATI Radeon HD 4300/4500 Series", kNull }, + { 0x9552, 0x3000174B, CHIP_FAMILY_RV710, "ATI Radeon HD 4300/4500 Series", kNull }, + { 0x9552, 0x30001787, CHIP_FAMILY_RV710, "ATI Radeon HD 4300/4500 Series", kNull }, + { 0x9552, 0x300017AF, CHIP_FAMILY_RV710, "ATI Radeon HD 4300/4500 Series", kNull }, + + { 0x9581, 0x95811002, CHIP_FAMILY_RV630, "ATI Radeon HD 3600 Series", kNull }, + { 0x9581, 0x3000148C, CHIP_FAMILY_RV630, "ATI Radeon HD 3600 Series", kNull }, + + { 0x9583, 0x3000148C, CHIP_FAMILY_RV630, "ATI Radeon HD 3600 Series", kNull }, + { 0x9588, 0x01021A93, CHIP_FAMILY_RV630, "Qimonda Radeon HD 2600 XT", kNull }, + + { 0x9589, 0x30001462, CHIP_FAMILY_RV630, "ATI Radeon HD 3610", kNull }, + { 0x9589, 0x30001642, CHIP_FAMILY_RV630, "ATI Radeon HD 3610", kNull }, + { 0x9589, 0x0E41174B, CHIP_FAMILY_RV630, "ATI Radeon HD 3600 Series", kNull }, + { 0x9589, 0x30001787, CHIP_FAMILY_RV630, "ATI Radeon HD 3600 Series", kNull }, + { 0x9589, 0x01001A93, CHIP_FAMILY_RV630, "Qimonda Radeon HD 2600 PRO", kNull }, + + { 0x9591, 0x2303148C, CHIP_FAMILY_RV635, "ATI Radeon HD 3600 Series", kNull }, + + //Azi: most of the 9598 are rv630, according to http://developer.amd.com/gpu_assets/ATI_Device_IDs_xxx_xx.txt + { 0x9598, 0xB3831002, CHIP_FAMILY_RV635, "ATI All-in-Wonder HD", kNull }, + { 0x9598, 0x30011043, CHIP_FAMILY_RV635, "ATI Radeon HD 4570", kNull }, + { 0x9598, 0x30001043, CHIP_FAMILY_RV635, "HD3730", kNull }, + { 0x9598, 0x3000148C, CHIP_FAMILY_RV635, "ATI Radeon HD 3730", kNull }, + { 0x9598, 0x3031148C, CHIP_FAMILY_RV635, "ATI Radeon HD 4570", kNull }, + { 0x9598, 0x3001148C, CHIP_FAMILY_RV635, "ATI Radeon HD 4580", kNull }, + { 0x9598, 0x30011545, CHIP_FAMILY_RV635, "VisionTek Radeon HD 2600 Pro", kNull }, + { 0x9598, 0x30001545, CHIP_FAMILY_RV635, "VisionTek Radeon HD 2600 XT", kNull }, + { 0x9598, 0x4570174B, CHIP_FAMILY_RV635, "ATI Radeon HD 4570", kNull }, + { 0x9598, 0x4580174B, CHIP_FAMILY_RV635, "ATI Radeon HD 4580", kNull }, + { 0x9598, 0x4610174B, CHIP_FAMILY_RV635, "ATI Radeon HD 4610", kNull }, + { 0x9598, 0x3000174B, CHIP_FAMILY_RV635, "Sapphire Radeon HD 3730", kNull }, + { 0x9598, 0x3001174B, CHIP_FAMILY_RV635, "Sapphire Radeon HD 3750", kNull }, + { 0x9598, 0x301017AF, CHIP_FAMILY_RV635, "ATI Radeon HD 4570", kNull }, + { 0x9598, 0x301117AF, CHIP_FAMILY_RV635, "ATI Radeon HD 4580", kNull }, + { 0x9598, 0x300117AF, CHIP_FAMILY_RV635, "ATI Radeon HD3750", kNull }, + { 0x9598, 0x30501787, CHIP_FAMILY_RV635, "ATI Radeon HD 4610", kNull }, + + { 0x95C0, 0x3000148C, CHIP_FAMILY_RV620, "ATI Radeon HD 3550", kNull }, + { 0x95C0, 0xE3901745, CHIP_FAMILY_RV620, "ATI Radeon HD 3550", kNull }, + { 0x95C0, 0x3002174B, CHIP_FAMILY_RV620, "ATI Radeon HD 3570", kNull }, + { 0x95C0, 0x3020174B, CHIP_FAMILY_RV620, "ATI Radeon HD 4250", kNull }, + { 0x95C0, 0x3000174B, CHIP_FAMILY_RV620, "Sapphire Radeon HD 3550", kNull }, + + { 0x95C5, 0x3000148C, CHIP_FAMILY_RV620, "ATI Radeon HD 3450", kNull }, + { 0x95C5, 0x3001148C, CHIP_FAMILY_RV620, "ATI Radeon HD 3550", kNull }, + { 0x95C5, 0x3002148C, CHIP_FAMILY_RV620, "ATI Radeon HD 4230", kNull }, + { 0x95C5, 0x3033148C, CHIP_FAMILY_RV620, "ATI Radeon HD 4230", kNull }, + { 0x95C5, 0x3003148C, CHIP_FAMILY_RV620, "ATI Radeon HD 4250", kNull }, + { 0x95C5, 0x3032148C, CHIP_FAMILY_RV620, "ATI Radeon HD 4250", kNull }, + { 0x95C5, 0x3010174B, CHIP_FAMILY_RV620, "ATI Radeon HD 4250", kNull }, + { 0x95C5, 0x4250174B, CHIP_FAMILY_RV620, "ATI Radeon HD 4250", kNull }, + { 0x95C5, 0x30501787, CHIP_FAMILY_RV620, "ATI Radeon HD 4250", kNull }, + { 0x95C5, 0x301017AF, CHIP_FAMILY_RV620, "ATI Radeon HD 4230", kNull }, + { 0x95C5, 0x01051A93, CHIP_FAMILY_RV620, "Qimonda Radeon HD 3450", kNull }, + { 0x95C5, 0x01041A93, CHIP_FAMILY_RV620, "Qimonda Radeon HD 3450", kNull }, + + /* Evergreen */ + { 0x6898, 0x032E1043, CHIP_FAMILY_CYPRESS, "ATI Radeon HD 5870", kUakari }, + { 0x6898, 0xE140174B, CHIP_FAMILY_CYPRESS, "ATI Radeon HD 5870", kUakari }, + { 0x6898, 0x29611682, CHIP_FAMILY_CYPRESS, "ATI Radeon HD 5870", kUakari }, + { 0x6898, 0x0B001002, CHIP_FAMILY_CYPRESS, "ATI Radeon HD 5870", kZonalis }, + { 0x6898, 0x00D0106B, CHIP_FAMILY_CYPRESS, "ATI Radeon HD 5870", kLangur }, + + { 0x6899, 0x21E41458, CHIP_FAMILY_CYPRESS, "ATI Radeon HD 5850", kUakari }, + { 0x6899, 0x200A1787, CHIP_FAMILY_CYPRESS, "ATI Radeon HD 5850", kUakari }, + { 0x6899, 0x22901787, CHIP_FAMILY_CYPRESS, "ATI Radeon HD 5850", kUakari }, + { 0x6899, 0xE140174B, CHIP_FAMILY_CYPRESS, "ATI Radeon HD 5850", kUakari }, + + { 0x689C, 0x03521043, CHIP_FAMILY_HEMLOCK, "ASUS ARES", kUakari }, + { 0x689C, 0x039E1043, CHIP_FAMILY_HEMLOCK, "ASUS EAH5870 Series", kUakari }, + { 0x689C, 0x30201682, CHIP_FAMILY_HEMLOCK, "ATI Radeon HD 5970", kUakari }, + + { 0x68B8, 0xE147174B, CHIP_FAMILY_JUNIPER, "ATI Radeon HD 5770", kVervet }, + { 0x68B8, 0x21D71458, CHIP_FAMILY_JUNIPER, "ATI Radeon HD 5770", kVervet }, + { 0x68B8, 0x1482174B, CHIP_FAMILY_JUNIPER, "ATI Radeon HD 5770", kVervet }, + { 0x68B8, 0x29901682, CHIP_FAMILY_JUNIPER, "ATI Radeon HD 5770", kVervet }, + { 0x68B8, 0x29911682, CHIP_FAMILY_JUNIPER, "ATI Radeon HD 5770", kVervet }, + { 0x68B8, 0x200B1787, CHIP_FAMILY_JUNIPER, "ATI Radeon HD 5770", kVervet }, + { 0x68B8, 0x22881787, CHIP_FAMILY_JUNIPER, "ATI Radeon HD 5770", kVervet }, + { 0x68B8, 0x00CF106B, CHIP_FAMILY_JUNIPER, "ATI Radeon HD 5770", kHoolock }, + + { 0x68D8, 0x301117AF, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5690", kNull }, + { 0x68D8, 0x301017AF, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5730", kNull }, + { 0x68D8, 0x30001787, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5730", kNull }, + { 0x68D8, 0x5690174B, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5690", kNull }, + { 0x68D8, 0x5730174B, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5730", kNull }, + { 0x68D8, 0x21D91458, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5670", kBaboon }, + { 0x68D8, 0x03561043, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5670", kBaboon }, + { 0x68D8, 0xE151174B, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5670", kBaboon }, + { 0x68D9, 0x301017AF, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5630", kNull }, + { 0x68DA, 0x301017AF, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5630", kNull }, + { 0x68DA, 0x30001787, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5630", kNull }, + { 0x68DA, 0x5630174B, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5630", kNull }, + + { 0x68E0, 0x04561028, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5470M", kEulemur }, + { 0x68E1, 0x1426103C, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5430M", kEulemur }, + { 0x68F9, 0x301317AF, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5470", kNull }, + { 0x68F9, 0x301117AF, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5470", kNull }, + { 0x68F9, 0x301217AF, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5490", kNull }, + { 0x68F9, 0x30001787, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5470", kNull }, + { 0x68F9, 0x30021787, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5490", kNull }, + { 0x68F9, 0x30011787, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5530", kNull }, + { 0x68F9, 0x5470174B, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5470", kNull }, + { 0x68F9, 0x5490174B, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5490", kNull }, + { 0x68F9, 0x5530174B, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5530", kNull }, + + /* Northen Islands */ + { 0x6718, 0x0B001002, CHIP_FAMILY_CAYMAN, "AMD Radeon HD 6970", kNull }, + { 0x6718, 0x31301682, CHIP_FAMILY_CAYMAN, "AMD Radeon HD 6970", kNull }, + { 0x6718, 0x67181002, CHIP_FAMILY_CAYMAN, "AMD Radeon HD 6970", kNull }, + + { 0x6738, 0x67381002, CHIP_FAMILY_BARTS, "AMD Radeon HD 6870", kDuckweed }, + { 0x6739, 0x67391002, CHIP_FAMILY_BARTS, "AMD Radeon HD 6850", kDuckweed }, + { 0x6739, 0x21F81458, CHIP_FAMILY_BARTS, "AMD Radeon HD 6850", kDuckweed }, + + { 0x6759, 0xE193174B, CHIP_FAMILY_TURKS, "AMD Radeon HD 6570", kNull }, + + /* standard/default models */ + { 0x9400, 0x00000000, CHIP_FAMILY_R600, "ATI Radeon HD 2900 XT", kNull }, + { 0x9405, 0x00000000, CHIP_FAMILY_R600, "ATI Radeon HD 2900 GT", kNull }, + { 0x9440, 0x00000000, CHIP_FAMILY_RV770, "ATI Radeon HD 4800 Series", kMotmot }, + { 0x9441, 0x00000000, CHIP_FAMILY_RV770, "ATI Radeon HD 4870 X2", kMotmot }, + { 0x9442, 0x00000000, CHIP_FAMILY_RV770, "ATI Radeon HD 4800 Series", kMotmot }, + { 0x9443, 0x00000000, CHIP_FAMILY_RV770, "ATI Radeon HD 4850 X2", kMotmot }, + { 0x944C, 0x00000000, CHIP_FAMILY_RV770, "ATI Radeon HD 4800 Series", kMotmot }, + { 0x944E, 0x00000000, CHIP_FAMILY_RV770, "ATI Radeon HD 4700 Series", kMotmot }, + { 0x9450, 0x00000000, CHIP_FAMILY_RV770, "AMD FireStream 9270", kMotmot }, + { 0x9452, 0x00000000, CHIP_FAMILY_RV770, "AMD FireStream 9250", kMotmot }, + { 0x9460, 0x00000000, CHIP_FAMILY_RV770, "ATI Radeon HD 4800 Series", kMotmot }, + { 0x9462, 0x00000000, CHIP_FAMILY_RV770, "ATI Radeon HD 4800 Series", kMotmot }, + { 0x9490, 0x00000000, CHIP_FAMILY_RV730, "ATI Radeon HD 4600 Series", kFlicker }, + { 0x9498, 0x00000000, CHIP_FAMILY_RV730, "ATI Radeon HD 4600 Series", kFlicker }, + { 0x94B3, 0x00000000, CHIP_FAMILY_RV740, "ATI Radeon HD 4770", kFlicker }, + { 0x94B4, 0x00000000, CHIP_FAMILY_RV740, "ATI Radeon HD 4700 Series", kFlicker }, + { 0x94B5, 0x00000000, CHIP_FAMILY_RV740, "ATI Radeon HD 4770", kFlicker }, + { 0x94C1, 0x00000000, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 Series", kIago }, + { 0x94C3, 0x00000000, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 Series", kIago }, + { 0x94C7, 0x00000000, CHIP_FAMILY_RV610, "ATI Radeon HD 2350", kIago }, + { 0x94CC, 0x00000000, CHIP_FAMILY_RV610, "ATI Radeon HD 2400 Series", kIago }, + + { 0x9501, 0x00000000, CHIP_FAMILY_RV670, "ATI Radeon HD 3800 Series", kMegalodon }, + { 0x9505, 0x00000000, CHIP_FAMILY_RV670, "ATI Radeon HD 3800 Series", kMegalodon }, + { 0x9507, 0x00000000, CHIP_FAMILY_RV670, "ATI Radeon HD 3830", kMegalodon }, + { 0x950F, 0x00000000, CHIP_FAMILY_RV670, "ATI Radeon HD 3870 X2", kMegalodon }, + { 0x9513, 0x00000000, CHIP_FAMILY_RV670, "ATI Radeon HD 3850 X2", kMegalodon }, + { 0x9519, 0x00000000, CHIP_FAMILY_RV670, "AMD FireStream 9170", kMegalodon }, + { 0x9540, 0x00000000, CHIP_FAMILY_RV710, "ATI Radeon HD 4550", kNull }, + { 0x954F, 0x00000000, CHIP_FAMILY_RV710, "ATI Radeon HD 4300/4500 Series", kNull }, + { 0x9588, 0x00000000, CHIP_FAMILY_RV630, "ATI Radeon HD 2600 XT", kLamna }, + { 0x9589, 0x00000000, CHIP_FAMILY_RV630, "ATI Radeon HD 2600 PRO", kLamna }, + { 0x958A, 0x00000000, CHIP_FAMILY_RV630, "ATI Radeon HD 2600 X2 Series", kLamna }, + { 0x9598, 0x00000000, CHIP_FAMILY_RV635, "ATI Radeon HD 3600 Series", kMegalodon }, + { 0x95C0, 0x00000000, CHIP_FAMILY_RV620, "ATI Radeon HD 3400 Series", kIago }, + { 0x95C5, 0x00000000, CHIP_FAMILY_RV620, "ATI Radeon HD 3400 Series", kIago }, + + { 0x9610, 0x00000000, CHIP_FAMILY_RS780, "ATI Radeon HD 3200 Graphics", kNull }, + { 0x9611, 0x00000000, CHIP_FAMILY_RS780, "ATI Radeon 3100 Graphics", kNull }, + { 0x9614, 0x00000000, CHIP_FAMILY_RS780, "ATI Radeon HD 3300 Graphics", kNull }, + { 0x9616, 0x00000000, CHIP_FAMILY_RS780, "AMD 760G", kNull }, + + { 0x9710, 0x00000000, CHIP_FAMILY_RS880, "ATI Radeon HD 4200", kNull }, + { 0x9715, 0x00000000, CHIP_FAMILY_RS880, "ATI Radeon HD 4250", kNull }, + { 0x9714, 0x00000000, CHIP_FAMILY_RS880, "ATI Radeon HD 4290", kNull }, + + /* Evergreen */ + { 0x688D, 0x00000000, CHIP_FAMILY_CYPRESS, "AMD FireStream 9350", kUakari }, + + { 0x6898, 0x00000000, CHIP_FAMILY_CYPRESS, "ATI Radeon HD 5800 Series", kUakari }, + { 0x6899, 0x00000000, CHIP_FAMILY_CYPRESS, "ATI Radeon HD 5800 Series", kUakari }, + { 0x689E, 0x00000000, CHIP_FAMILY_CYPRESS, "ATI Radeon HD 5800 Series", kUakari }, + { 0x689C, 0x00000000, CHIP_FAMILY_HEMLOCK, "ATI Radeon HD 5900 Series", kUakari }, + + { 0x68B9, 0x00000000, CHIP_FAMILY_JUNIPER, "ATI Radeon HD 5600 Series", kVervet }, + { 0x68B8, 0x00000000, CHIP_FAMILY_JUNIPER, "ATI Radeon HD 5700 Series", kVervet }, + { 0x68BE, 0x00000000, CHIP_FAMILY_JUNIPER, "ATI Radeon HD 5700 Series", kVervet }, + //Azi: from Slice { 0x100268C0, "ATI Radeon 5670 Series", "Galago"} + // http://www.insanelymac.com/forum/index.php?s=&showtopic=255866&view=findpost&p=1695482 + + { 0x68D8, 0x00000000, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5600 Series", kBaboon }, + { 0x68D9, 0x00000000, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5500 Series", kBaboon }, + { 0x68DA, 0x00000000, CHIP_FAMILY_REDWOOD, "ATI Radeon HD 5500 Series", kBaboon }, + + { 0x68F9, 0x00000000, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5400 Series", kNull }, + + /* Northen Islands */ + { 0x6718, 0x00000000, CHIP_FAMILY_CAYMAN, "AMD Radeon HD 6970 Series", kNull }, + + { 0x6738, 0x00000000, CHIP_FAMILY_BARTS, "AMD Radeon HD 6870 Series", kDuckweed }, + { 0x6739, 0x00000000, CHIP_FAMILY_BARTS, "AMD Radeon HD 6850 Series", kDuckweed }, + { 0x673E, 0x00000000, CHIP_FAMILY_BARTS, "AMD Radeon HD 6790 Series", kNull }, + + { 0x6758, 0x00000000, CHIP_FAMILY_TURKS, "AMD Radeon HD 6670 Series", kNull }, + { 0x6759, 0x00000000, CHIP_FAMILY_TURKS, "AMD Radeon HD 6500 Series", kNull }, + + { 0x6770, 0x00000000, CHIP_FAMILY_CAICOS, "AMD Radeon HD 6400 Series", kNull }, + { 0x6779, 0x00000000, CHIP_FAMILY_CAICOS, "AMD Radeon HD 6450 Series", kNull }, + + { 0x0000, 0x00000000, CHIP_FAMILY_UNKNOW, NULL, kNull } +}; + +typedef struct { + struct DevPropDevice *device; + radeon_card_info_t *info; + pci_dt_t *pci_dev; + uint8_t *fb; + uint8_t *mmio; + uint8_t *io; + uint8_t *rom; + uint32_t rom_size; + uint32_t vram_size; + const char *cfg_name; + uint8_t ports; + uint32_t flags; + bool posted; +} card_t; +card_t *card; + +/* Flags */ +#define MKFLAG(n) (1 << n) +#define FLAGTRUE MKFLAG(0) +#define EVERGREEN MKFLAG(1) + +static uint8_t atN = 0; + +typedef struct { + type_t type; + uint32_t size; + uint8_t *data; +} value_t; + +static value_t aty_name; +static value_t aty_nameparent; +//static value_t aty_model; + +#define DATVAL(x) {kPtr, sizeof(x), (uint8_t *)x} +#define STRVAL(x) {kStr, sizeof(x), (uint8_t *)x} +#define BYTVAL(x) {kCst, 1, (uint8_t *)x} +#define WRDVAL(x) {kCst, 2, (uint8_t *)x} +#define DWRVAL(x) {kCst, 4, (uint8_t *)x} +#define QWRVAL(x) {kCst, 8, (uint8_t *)x} +#define NULVAL {kNul, 0, (uint8_t *)NULL} + +bool get_bootdisplay_val(value_t *val); +bool get_vrammemory_val(value_t *val); +bool get_name_val(value_t *val); +bool get_nameparent_val(value_t *val); +bool get_model_val(value_t *val); +bool get_conntype_val(value_t *val); +bool get_vrammemsize_val(value_t *val); +bool get_binimage_val(value_t *val); +bool get_romrevision_val(value_t *val); +bool get_deviceid_val(value_t *val); +bool get_mclk_val(value_t *val); +bool get_sclk_val(value_t *val); +bool get_refclk_val(value_t *val); +bool get_platforminfo_val(value_t *val); +bool get_vramtotalsize_val(value_t *val); + +typedef struct { + uint32_t flags; + bool all_ports; + char *name; + bool (*get_value)(value_t *val); + value_t default_val; +} dev_prop_t; + +dev_prop_t ati_devprop_list[] = { + {FLAGTRUE, false, "@0,AAPL,boot-display", get_bootdisplay_val, NULVAL }, +// {FLAGTRUE, false, "@0,ATY,EFIDisplay", NULL, STRVAL("TMDSA") }, + +// {FLAGTRUE, true, "@0,AAPL,vram-memory", get_vrammemory_val, NULVAL }, +// {FLAGTRUE, true, "@0,compatible", get_name_val, NULVAL }, +// {FLAGTRUE, true, "@0,connector-type", get_conntype_val, NULVAL }, +// {FLAGTRUE, true, "@0,device_type", NULL, STRVAL("display") }, +// {FLAGTRUE, false, "@0,display-connect-flags", NULL, DWRVAL((uint32_t)0) }, +// {FLAGTRUE, true, "@0,display-type", NULL, STRVAL("NONE") }, + {FLAGTRUE, true, "@0,name", get_name_val, NULVAL }, +// {FLAGTRUE, true, "@0,VRAM,memsize", get_vrammemsize_val, NULVAL }, + +// {FLAGTRUE, false, "AAPL,aux-power-connected", NULL, DWRVAL((uint32_t)1) }, +// {FLAGTRUE, false, "AAPL,backlight-control", NULL, DWRVAL((uint32_t)0) }, + {FLAGTRUE, false, "ATY,bin_image", get_binimage_val, NULVAL }, + {FLAGTRUE, false, "ATY,Copyright", NULL, STRVAL("Copyright AMD Inc. All Rights Reserved. 2005-2010") }, + {FLAGTRUE, false, "ATY,Card#", get_romrevision_val, NULVAL }, + {FLAGTRUE, false, "ATY,VendorID", NULL, WRDVAL((uint16_t)0x1002) }, + {FLAGTRUE, false, "ATY,DeviceID", get_deviceid_val, NULVAL }, + +// {FLAGTRUE, false, "ATY,MCLK", get_mclk_val, NULVAL }, +// {FLAGTRUE, false, "ATY,SCLK", get_sclk_val, NULVAL }, +// {FLAGTRUE, false, "ATY,RefCLK", get_refclk_val, DWRVAL((uint32_t)0x0a8c) }, + +// {FLAGTRUE, false, "ATY,PlatformInfo", get_platforminfo_val, NULVAL }, + + {FLAGTRUE, false, "name", get_nameparent_val, NULVAL }, + {FLAGTRUE, false, "device_type", get_nameparent_val, NULVAL }, + {FLAGTRUE, false, "model", get_model_val, STRVAL("ATI Radeon") }, +// {FLAGTRUE, false, "VRAM,totalsize", get_vramtotalsize_val, NULVAL }, + + {FLAGTRUE, false, NULL, NULL, NULVAL } +}; + +bool get_bootdisplay_val(value_t *val) +{ + static uint32_t v = 0; + + if (v) + return false; + + if (!card->posted) + return false; + + v = 1; + val->type = kCst; + val->size = 4; + val->data = (uint8_t *)&v; + + return true; +} + +bool get_vrammemory_val(value_t *val) +{ + return false; +} + +bool get_name_val(value_t *val) +{ + val->type = aty_name.type; + val->size = aty_name.size; + val->data = aty_name.data; + + return true; +} + +bool get_nameparent_val(value_t *val) +{ + val->type = aty_nameparent.type; + val->size = aty_nameparent.size; + val->data = aty_nameparent.data; + + return true; +} + +bool get_model_val(value_t *val) +{ + if (!card->info->model_name) + return false; + + val->type = kStr; + val->size = strlen(card->info->model_name) + 1; + val->data = (uint8_t *)card->info->model_name; + + return true; +} + +bool get_conntype_val(value_t *val) +{ +//Connector types: +//0x4 : DisplayPort +//0x400: DL DVI-I +//0x800: HDMI + + return false; +} + +bool get_vrammemsize_val(value_t *val) +{ + static int idx = -1; + static uint64_t memsize; + + idx++; + memsize = ((uint64_t)card->vram_size << 32); + if (idx == 0) + memsize = memsize | (uint64_t)card->vram_size; + + val->type = kCst; + val->size = 8; + val->data = (uint8_t *)&memsize; + + return true; +} + +bool get_binimage_val(value_t *val) +{ + if (!card->rom) + return false; + + val->type = kPtr; + val->size = card->rom_size; + val->data = card->rom; + + return true; +} + +bool get_romrevision_val(value_t *val) +{ + uint8_t *rev; + if (!card->rom) + return false; + + rev = card->rom + *(uint8_t *)(card->rom + OFFSET_TO_GET_ATOMBIOS_STRINGS_START); + + val->type = kPtr; + val->size = strlen((char *)rev); + val->data = malloc(val->size); + + if (!val->data) + return false; + + memcpy(val->data, rev, val->size); + + return true; +} + +bool get_deviceid_val(value_t *val) +{ + val->type = kCst; + val->size = 2; + val->data = (uint8_t *)&card->pci_dev->device_id; + + return true; +} + +bool get_mclk_val(value_t *val) +{ + return false; +} + +bool get_sclk_val(value_t *val) +{ + return false; +} + +bool get_refclk_val(value_t *val) +{ + return false; +} + +bool get_platforminfo_val(value_t *val) +{ + val->data = malloc(0x80); + if (!val->data) + return false; + + bzero(val->data, 0x80); + + val->type = kPtr; + val->size = 0x80; + val->data[0] = 1; + + return true; +} + +bool get_vramtotalsize_val(value_t *val) +{ + val->type = kCst; + val->size = 4; + val->data = (uint8_t *)&card->vram_size; + + return true; +} + +void free_val(value_t *val) +{ + if (val->type == kPtr) + free(val->data); + + bzero(val, sizeof(value_t)); +} + +void devprop_add_list(dev_prop_t devprop_list[]) +{ + value_t *val = malloc(sizeof(value_t)); + int i, pnum; + + for (i = 0; devprop_list[i].name != NULL; i++) + { + if ((devprop_list[i].flags == FLAGTRUE) || (devprop_list[i].flags | card->flags)) + { + if (devprop_list[i].get_value && devprop_list[i].get_value(val)) + { + devprop_add_value(card->device, devprop_list[i].name, val->data, val->size); + free_val(val); + + if (devprop_list[i].all_ports) + { + for (pnum = 1; pnum < card->ports; pnum++) + { + if (devprop_list[i].get_value(val)) + { + devprop_list[i].name[1] = 0x30 + pnum; // convert to ascii + devprop_add_value(card->device, devprop_list[i].name, val->data, val->size); + free_val(val); + } + } + devprop_list[i].name[1] = 0x30; // write back our "@0," for a next possible card + } + } + else + { + if (devprop_list[i].default_val.type != kNul) + { + devprop_add_value(card->device, devprop_list[i].name, + devprop_list[i].default_val.type == kCst ? + (uint8_t *)&(devprop_list[i].default_val.data) : devprop_list[i].default_val.data, + devprop_list[i].default_val.size); + } + + if (devprop_list[i].all_ports) + { + for (pnum = 1; pnum < card->ports; pnum++) + { + if (devprop_list[i].default_val.type != kNul) + { + devprop_list[i].name[1] = 0x30 + pnum; // convert to ascii + devprop_add_value(card->device, devprop_list[i].name, + devprop_list[i].default_val.type == kCst ? + (uint8_t *)&(devprop_list[i].default_val.data) : devprop_list[i].default_val.data, + devprop_list[i].default_val.size); + } + } + devprop_list[i].name[1] = 0x30; // write back our "@0," for a next possible card + } + } + } + } + + free(val); +} + +bool validate_rom(option_rom_header_t *rom_header, pci_dt_t *pci_dev) +{ + option_rom_pci_header_t *rom_pci_header; + + if (rom_header->signature != 0xaa55) + return false; + + rom_pci_header = (option_rom_pci_header_t *)((uint8_t *)rom_header + rom_header->pci_header_offset); + + if (rom_pci_header->signature != 0x52494350) + return false; + + if (rom_pci_header->vendor_id != pci_dev->vendor_id || rom_pci_header->device_id != pci_dev->device_id) + return false; + + return true; +} + +bool load_vbios_file(const char *key, uint16_t vendor_id, uint16_t device_id, uint32_t subsys_id) +{ + int fd; + char file_name[24]; + bool do_load = false; + + getBoolForKey(key, &do_load, &bootInfo->chameleonConfig); + if (!do_load) + return false; + + sprintf(file_name, "/Extra/%04x_%04x_%08x.rom", vendor_id, device_id, subsys_id); + if ((fd = open_bvdev("bt(0,0)", file_name, 0)) < 0) + return false; + + card->rom_size = file_size(fd); + card->rom = malloc(card->rom_size); + if (!card->rom) + return false; + + read(fd, (char *)card->rom, card->rom_size); + + if (!validate_rom((option_rom_header_t *)card->rom, card->pci_dev)) + { + card->rom_size = 0; + card->rom = 0; + return false; + } + + card->rom_size = ((option_rom_header_t *)card->rom)->rom_size * 512; + + close(fd); + + return true; +} + +void get_vram_size(void) +{ + chip_family_t chip_family = card->info->chip_family; + + card->vram_size = 0; + + if (chip_family >= CHIP_FAMILY_CEDAR) + // size in MB on evergreen + // XXX watch for overflow!!! + card->vram_size = RegRead32(R600_CONFIG_MEMSIZE) * 1024 * 1024; + else + if (chip_family >= CHIP_FAMILY_R600) + card->vram_size = RegRead32(R600_CONFIG_MEMSIZE); +} + +bool read_vbios(bool from_pci) +{ + option_rom_header_t *rom_addr; + + if (from_pci) + { + rom_addr = (option_rom_header_t *)(pci_config_read32(card->pci_dev->dev.addr, PCI_ROM_ADDRESS) & ~0x7ff); + verbose(" @0x%x", rom_addr); + } + else + rom_addr = (option_rom_header_t *)0xc0000; + + if (!validate_rom(rom_addr, card->pci_dev)) + return false; + + card->rom_size = rom_addr->rom_size * 512; + if (!card->rom_size) + return false; + + card->rom = malloc(card->rom_size); + if (!card->rom) + return false; + + memcpy(card->rom, (void *)rom_addr, card->rom_size); + + return true; +} + +bool read_disabled_vbios(void) +{ + bool ret = false; + chip_family_t chip_family = card->info->chip_family; + + if (chip_family >= CHIP_FAMILY_RV770) + { + uint32_t viph_control = RegRead32(RADEON_VIPH_CONTROL); + uint32_t bus_cntl = RegRead32(RADEON_BUS_CNTL); + uint32_t d1vga_control = RegRead32(AVIVO_D1VGA_CONTROL); + uint32_t d2vga_control = RegRead32(AVIVO_D2VGA_CONTROL); + uint32_t vga_render_control = RegRead32(AVIVO_VGA_RENDER_CONTROL); + uint32_t rom_cntl = RegRead32(R600_ROM_CNTL); + uint32_t cg_spll_func_cntl = 0; + uint32_t cg_spll_status; + + // disable VIP + RegWrite32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); + + // enable the rom + RegWrite32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); + + // Disable VGA mode + RegWrite32(AVIVO_D1VGA_CONTROL, (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | AVIVO_DVGA_CONTROL_TIMING_SELECT))); + RegWrite32(AVIVO_D2VGA_CONTROL, (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | AVIVO_DVGA_CONTROL_TIMING_SELECT))); + RegWrite32(AVIVO_VGA_RENDER_CONTROL, (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK)); + + if (chip_family == CHIP_FAMILY_RV730) + { + cg_spll_func_cntl = RegRead32(R600_CG_SPLL_FUNC_CNTL); + + // enable bypass mode + RegWrite32(R600_CG_SPLL_FUNC_CNTL, (cg_spll_func_cntl | R600_SPLL_BYPASS_EN)); + + // wait for SPLL_CHG_STATUS to change to 1 + cg_spll_status = 0; + while (!(cg_spll_status & R600_SPLL_CHG_STATUS)) + cg_spll_status = RegRead32(R600_CG_SPLL_STATUS); + + RegWrite32(R600_ROM_CNTL, (rom_cntl & ~R600_SCK_OVERWRITE)); + } + else + RegWrite32(R600_ROM_CNTL, (rom_cntl | R600_SCK_OVERWRITE)); + + ret = read_vbios(true); + + // restore regs + if (chip_family == CHIP_FAMILY_RV730) + { + RegWrite32(R600_CG_SPLL_FUNC_CNTL, cg_spll_func_cntl); + + // wait for SPLL_CHG_STATUS to change to 1 + cg_spll_status = 0; + while (!(cg_spll_status & R600_SPLL_CHG_STATUS)) + cg_spll_status = RegRead32(R600_CG_SPLL_STATUS); + } + RegWrite32(RADEON_VIPH_CONTROL, viph_control); + RegWrite32(RADEON_BUS_CNTL, bus_cntl); + RegWrite32(AVIVO_D1VGA_CONTROL, d1vga_control); + RegWrite32(AVIVO_D2VGA_CONTROL, d2vga_control); + RegWrite32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); + RegWrite32(R600_ROM_CNTL, rom_cntl); + } + else + if (chip_family >= CHIP_FAMILY_R600) + { + uint32_t viph_control = RegRead32(RADEON_VIPH_CONTROL); + uint32_t bus_cntl = RegRead32(RADEON_BUS_CNTL); + uint32_t d1vga_control = RegRead32(AVIVO_D1VGA_CONTROL); + uint32_t d2vga_control = RegRead32(AVIVO_D2VGA_CONTROL); + uint32_t vga_render_control = RegRead32(AVIVO_VGA_RENDER_CONTROL); + uint32_t rom_cntl = RegRead32(R600_ROM_CNTL); + uint32_t general_pwrmgt = RegRead32(R600_GENERAL_PWRMGT); + uint32_t low_vid_lower_gpio_cntl = RegRead32(R600_LOW_VID_LOWER_GPIO_CNTL); + uint32_t medium_vid_lower_gpio_cntl = RegRead32(R600_MEDIUM_VID_LOWER_GPIO_CNTL); + uint32_t high_vid_lower_gpio_cntl = RegRead32(R600_HIGH_VID_LOWER_GPIO_CNTL); + uint32_t ctxsw_vid_lower_gpio_cntl = RegRead32(R600_CTXSW_VID_LOWER_GPIO_CNTL); + uint32_t lower_gpio_enable = RegRead32(R600_LOWER_GPIO_ENABLE); + + // disable VIP + RegWrite32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); + + // enable the rom + RegWrite32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); + + // Disable VGA mode + RegWrite32(AVIVO_D1VGA_CONTROL, (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | AVIVO_DVGA_CONTROL_TIMING_SELECT))); + RegWrite32(AVIVO_D2VGA_CONTROL, (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | AVIVO_DVGA_CONTROL_TIMING_SELECT))); + RegWrite32(AVIVO_VGA_RENDER_CONTROL, (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK)); + RegWrite32(R600_ROM_CNTL, ((rom_cntl & ~R600_SCK_PRESCALE_CRYSTAL_CLK_MASK) | (1 << R600_SCK_PRESCALE_CRYSTAL_CLK_SHIFT) | R600_SCK_OVERWRITE)); + RegWrite32(R600_GENERAL_PWRMGT, (general_pwrmgt & ~R600_OPEN_DRAIN_PADS)); + RegWrite32(R600_LOW_VID_LOWER_GPIO_CNTL, (low_vid_lower_gpio_cntl & ~0x400)); + RegWrite32(R600_MEDIUM_VID_LOWER_GPIO_CNTL, (medium_vid_lower_gpio_cntl & ~0x400)); + RegWrite32(R600_HIGH_VID_LOWER_GPIO_CNTL, (high_vid_lower_gpio_cntl & ~0x400)); + RegWrite32(R600_CTXSW_VID_LOWER_GPIO_CNTL, (ctxsw_vid_lower_gpio_cntl & ~0x400)); + RegWrite32(R600_LOWER_GPIO_ENABLE, (lower_gpio_enable | 0x400)); + + ret = read_vbios(true); + + // restore regs + RegWrite32(RADEON_VIPH_CONTROL, viph_control); + RegWrite32(RADEON_BUS_CNTL, bus_cntl); + RegWrite32(AVIVO_D1VGA_CONTROL, d1vga_control); + RegWrite32(AVIVO_D2VGA_CONTROL, d2vga_control); + RegWrite32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); + RegWrite32(R600_ROM_CNTL, rom_cntl); + RegWrite32(R600_GENERAL_PWRMGT, general_pwrmgt); + RegWrite32(R600_LOW_VID_LOWER_GPIO_CNTL, low_vid_lower_gpio_cntl); + RegWrite32(R600_MEDIUM_VID_LOWER_GPIO_CNTL, medium_vid_lower_gpio_cntl); + RegWrite32(R600_HIGH_VID_LOWER_GPIO_CNTL, high_vid_lower_gpio_cntl); + RegWrite32(R600_CTXSW_VID_LOWER_GPIO_CNTL, ctxsw_vid_lower_gpio_cntl); + RegWrite32(R600_LOWER_GPIO_ENABLE, lower_gpio_enable); + } + + return ret; +} + +bool radeon_card_posted(void) +{ + uint32_t reg; + + // first check CRTCs + reg = RegRead32(RADEON_CRTC_GEN_CNTL) | RegRead32(RADEON_CRTC2_GEN_CNTL); + if (reg & RADEON_CRTC_EN) + return true; + + // then check MEM_SIZE, in case something turned the crtcs off + reg = RegRead32(R600_CONFIG_MEMSIZE); + if (reg) + return true; + + return false; +} + +#if 0 +bool devprop_add_pci_config_space(void) +{ + int offset; + + uint8_t *config_space = malloc(0x100); + if (!config_space) + return false; + + for (offset = 0; offset < 0x100; offset += 4) + config_space[offset / 4] = pci_config_read32(card->pci_dev->dev.addr, offset); + + devprop_add_value(card->device, "ATY,PCIConfigSpace", config_space, 0x100); + free(config_space); + + return true; +} +#endif + +static bool init_card(pci_dt_t *pci_dev) +{ + char name[24]; + char name_parent[24]; + int i; + bool add_vbios = true; + + card = malloc(sizeof(card_t)); + if (!card) + return false; + bzero(card, sizeof(card_t)); + + card->pci_dev = pci_dev; + + for (i = 0; radeon_cards[i].device_id ; i++) + { + if (radeon_cards[i].device_id == pci_dev->device_id) + { + card->info = &radeon_cards[i]; + if ((radeon_cards[i].subsys_id == 0x00000000) || + (radeon_cards[i].subsys_id == pci_dev->subsys_id.subsys_id)) + break; + } + } + + if (!card->info->device_id || !card->info->cfg_name) + { + printf("Unsupported card!\nUse AtiConfig key to specify a framebuffer for your card.\nIf still unsupported, report dev id, subsys id and vendor."); + pause(); + return false; + } + + card->fb = (uint8_t *)(pci_config_read32(pci_dev->dev.addr, PCI_BASE_ADDRESS_0) & ~0x0f); + card->mmio = (uint8_t *)(pci_config_read32(pci_dev->dev.addr, PCI_BASE_ADDRESS_2) & ~0x0f); + card->io = (uint8_t *)(pci_config_read32(pci_dev->dev.addr, PCI_BASE_ADDRESS_4) & ~0x03); + + verbose("Framebuffer @0x%08X MMIO @0x%08X I/O Port @0x%08X ROM Addr @0x%08X\n", + card->fb, card->mmio, card->io, pci_config_read32(pci_dev->dev.addr, PCI_ROM_ADDRESS)); + + card->posted = radeon_card_posted(); + verbose("ATI card %s, ", card->posted ? "POSTed" : "non-POSTed"); + + get_vram_size(); + + getBoolForKey(kATYbinimage, &add_vbios, &bootInfo->chameleonConfig); + + if (add_vbios) + { + if (!load_vbios_file(kUseAtiROM, pci_dev->vendor_id, pci_dev->device_id, pci_dev->subsys_id.subsys_id)) + { + verbose("reading VBIOS from %s", card->posted ? "legacy space" : "PCI ROM"); + if (card->posted) + read_vbios(false); + else + read_disabled_vbios(); + verbose("\n"); + } + } + + card->ports = 2; // default + + if (card->info->chip_family >= CHIP_FAMILY_CEDAR) + { + card->flags |= EVERGREEN; + card->ports = 3; + } + + atN = 0; + + card->cfg_name = getStringForKey(kAtiConfig, &bootInfo->chameleonConfig); + if (!card->cfg_name) + { + card->cfg_name = card_configs[card->info->cfg_name].name; + card->ports = card_configs[card->info->cfg_name].ports; + } + else + { + for (i = 0; i < kCfgEnd; i++) + if (strcmp(card->cfg_name, card_configs[i].name) == 0) + card->ports = card_configs[i].ports; + } + + sprintf(name, "ATY,%s", card->cfg_name); + aty_name.type = kStr; + aty_name.size = strlen(name) + 1; + aty_name.data = (uint8_t *)name; + + sprintf(name_parent, "ATY,%sParent", card->cfg_name); + aty_nameparent.type = kStr; + aty_nameparent.size = strlen(name_parent) + 1; + aty_nameparent.data = (uint8_t *)name_parent; + + return true; +} + +bool setup_ati_devprop(pci_dt_t *ati_dev) +{ + char *devicepath; + + if (!init_card(ati_dev)) + return false; + + // ------------------------------------------------- + // Find a better way to do this (in device_inject.c) + if (!string) + string = devprop_create_string(); + + devicepath = get_pci_dev_path(ati_dev); + card->device = devprop_add_device(string, devicepath); + if (!card->device) + return false; + // ------------------------------------------------- + +#if 0 + uint64_t fb = (uint32_t)card->fb; + uint64_t mmio = (uint32_t)card->mmio; + uint64_t io = (uint32_t)card->io; + devprop_add_value(card->device, "ATY,FrameBufferOffset", &fb, 8); + devprop_add_value(card->device, "ATY,RegisterSpaceOffset", &mmio, 8); + devprop_add_value(card->device, "ATY,IOSpaceOffset", &io, 8); +#endif + + devprop_add_list(ati_devprop_list); + + // ------------------------------------------------- + // Find a better way to do this (in device_inject.c) + //Azi: XXX tried to fix a malloc error in vain; this is related to XCode 4 compilation! + stringdata = malloc(sizeof(uint8_t) * string->length); + memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length); + stringlength = string->length; + // ------------------------------------------------- + + verbose("ATI %s %s %dMB (%s) [%04x:%04x] (subsys [%04x:%04x]):: %s\n", + chip_family_name[card->info->chip_family], card->info->model_name, + (uint32_t)(card->vram_size / (1024 * 1024)), card->cfg_name, + ati_dev->vendor_id, ati_dev->device_id, + ati_dev->subsys_id.subsys.vendor_id, ati_dev->subsys_id.subsys.device_id, + devicepath); + + free(card); + + return true; +} Index: branches/slice/trunkM/i386/libsaio/sys.c =================================================================== --- branches/slice/trunkM/i386/libsaio/sys.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/sys.c (revision 1171) @@ -0,0 +1,1119 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Mach Operating System + * Copyright (c) 1990 Carnegie-Mellon University + * Copyright (c) 1989 Carnegie-Mellon University + * Copyright (c) 1988 Carnegie-Mellon University + * Copyright (c) 1987 Carnegie-Mellon University + * All rights reserved. The CMU software License Agreement specifies + * the terms and conditions for use and redistribution. + * + */ +/* + * HISTORY + * Revision 2.3 88/08/08 13:47:07 rvb + * Allocate buffers dynamically vs statically. + * Now b[i] and i_fs and i_buf, are allocated dynamically. + * boot_calloc(size) allocates and zeros a buffer rounded to a NPG + * boundary. + * Generalize boot spec to allow, xx()/mach, xx(n,[a..h])/mach, + * xx([a..h])/mach, ... + * Also default "xx" if unspecified and alloc just "/mach", + * where everything is defaulted + * Add routine, ptol(), to parse partition letters. + * + */ + +/* + * Copyright (c) 1982, 1986 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + * + * @(#)sys.c 7.1 (Berkeley) 6/5/86 + */ + +/* Copyright 2007 VMware Inc. + "Preboot" ramdisk support added by David Elliott + */ + + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "disk.h" +#include "ramdisk.h" +#include "xml.h" + +#include +//#include + +#if 0 /* No OS X release has ever included this. */ +#include +#else +// from our uuid/namespace.h (UFS and HFS uuids can live in the same space?) +static unsigned char kFSUUIDNamespaceSHA1[] = {0xB3,0xE2,0x0F,0x39,0xF2,0x92,0x11,0xD6,0x97,0xA4,0x00,0x30,0x65,0x43,0xEC,0xAC}; +#endif + +extern int multiboot_partition; +extern int multiboot_partition_set; +extern int multiboot_skip_partition; +extern int multiboot_skip_partition_set; + +struct devsw { + const char * name; + // size increased from char to short to handle non-BIOS internal devices + unsigned short biosdev; + int type; +}; + +// Device entries must be ordered by bios device numbers. +static struct devsw devsw[] = +{ + { "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. + */ +#define NFILES 6 + +static struct iob iob[NFILES]; + +void * gFSLoadAddress = 0; + +// Turbo - save what we think is our original BIOS boot volume if we have one 0xab +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 ); + +//========================================================================== +// LoadVolumeFile - LOW-LEVEL FILESYSTEM FUNCTION. +// Load the specified file from the specified volume +// to the load buffer at LOAD_ADDR. +// If the file is fat, load only the i386 portion. + +long LoadVolumeFile(BVRef bvr, const char *filePath) +{ + long fileSize; + + // Read file into load buffer. The data in the load buffer will be + // overwritten by the next LoadFile() call. + + gFSLoadAddress = (void *) LOAD_ADDR; + + fileSize = bvr->fs_loadfile(bvr, (char *)filePath); + + // Return the size of the file, or -1 if load failed. + + return fileSize; +} + +//========================================================================== +// LoadFile - LOW-LEVEL FILESYSTEM FUNCTION. +// Load the specified file to the load buffer at LOAD_ADDR. +// If the file is fat, load only the i386 portion. + +long LoadFile(const char * fileSpec) +{ + const char * filePath; + BVRef bvr; + + // Resolve the boot volume from the file spec. + + if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL) + return -1; + + return LoadVolumeFile(bvr, filePath); +} + +long ReadFileAtOffset(const char * fileSpec, void *buffer, uint64_t offset, uint64_t length) +{ + const char *filePath; + BVRef bvr; + + if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL) + return -1; + + if (bvr->fs_readfile == NULL) + return -1; + + return bvr->fs_readfile(bvr, (char *)filePath, buffer, offset, length); +} + +long LoadThinFatFile(const char *fileSpec, void **binary) +{ + const char *filePath; + FSReadFile readFile; + BVRef bvr; + unsigned long length, length2; + + // Resolve the boot volume from the file spec. + + if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL) + return -1; + + *binary = (void *)kLoadAddr; + + // Read file into load buffer. The data in the load buffer will be + // overwritten by the next LoadFile() call. + + gFSLoadAddress = (void *) LOAD_ADDR; + + readFile = bvr->fs_readfile; + + if (readFile != NULL) { + // Read the first 4096 bytes (fat header) + length = readFile(bvr, (char *)filePath, *binary, 0, 0x1000); + if (length > 0) { + if (ThinFatFile(binary, &length) == 0) { + if (length == 0) + return 0; + // We found a fat binary; read only the thin part + length = readFile(bvr, (char *)filePath, + (void *)kLoadAddr, (unsigned long)(*binary) - kLoadAddr, length); + *binary = (void *)kLoadAddr; + } else { + // Not a fat binary; read the rest of the file + length2 = readFile(bvr, (char *)filePath, (void *)(kLoadAddr + length), length, 0); + if (length2 == -1) return -1; + length += length2; + } + } + } else { + length = bvr->fs_loadfile(bvr, (char *)filePath); + if (length > 0) { + ThinFatFile(binary, &length); + } + } + + return length; +} + +#if UNUSED +long GetFSUUID(char *spec, char *uuidStr) +{ + BVRef bvr; + long rval = -1; + const char *devSpec; + + if ((bvr = getBootVolumeRef(spec, &devSpec)) == NULL) + return -1; + + if(bvr->fs_getuuid) + rval = bvr->fs_getuuid(bvr, uuidStr); + + return rval; +} +#endif + +// filesystem-specific getUUID functions call this shared string generator +long CreateUUIDString(uint8_t uubytes[], int nbytes, char *uuidStr) +{ + unsigned fmtbase, fmtidx, i; + uint8_t uuidfmt[] = { 4, 2, 2, 2, 6 }; + char *p = uuidStr; + MD5_CTX md5c; + uint8_t mdresult[16]; + + bzero(mdresult, sizeof(mdresult)); + + // just like AppleFileSystemDriver + MD5Init(&md5c); + MD5Update(&md5c, kFSUUIDNamespaceSHA1, sizeof(kFSUUIDNamespaceSHA1)); + MD5Update(&md5c, uubytes, nbytes); + MD5Final(mdresult, &md5c); + + // this UUID has been made version 3 style (i.e. via namespace) + // see "-uuid-urn-" IETF draft (which otherwise copies byte for byte) + mdresult[6] = 0x30 | ( mdresult[6] & 0x0F ); + mdresult[8] = 0x80 | ( mdresult[8] & 0x3F ); + + + // generate the text: e.g. 5EB1869F-C4FA-3502-BDEB-3B8ED5D87292 + i = 0; fmtbase = 0; + for(fmtidx = 0; fmtidx < sizeof(uuidfmt); fmtidx++) { + for(i=0; i < uuidfmt[fmtidx]; i++) { + uint8_t byte = mdresult[fmtbase+i]; + char nib; + + nib = byte >> 4; + *p = nib + '0'; // 0x4 -> '4' + if(*p > '9') *p = (nib - 9 + ('A'-1)); // 0xB -> 'B' + p++; + + nib = byte & 0xf; + *p = nib + '0'; // 0x4 -> '4' + if(*p > '9') *p = (nib - 9 + ('A'-1)); // 0xB -> 'B' + p++; + + } + fmtbase += i; + if(fmtidx < sizeof(uuidfmt)-1) + *(p++) = '-'; + else + *p = '\0'; + } + + return 0; +} + + +//========================================================================== +// GetDirEntry - LOW-LEVEL FILESYSTEM FUNCTION. +// Fetch the next directory entry for the given directory. + +long GetDirEntry(const char * dirSpec, long long * dirIndex, const char ** name, + long * flags, long * time) +{ + const char * dirPath; + BVRef bvr; + + // Resolve the boot volume from the dir spec. + + if ((bvr = getBootVolumeRef(dirSpec, &dirPath)) == NULL) + return -1; + + // Return 0 on success, or -1 if there are no additional entries. + + return bvr->fs_getdirentry( bvr, + /* dirPath */ (char *)dirPath, + /* dirIndex */ dirIndex, + /* dirEntry */ (char **)name, flags, time, 0, 0 ); +} + +//========================================================================== +// GetFileInfo - LOW-LEVEL FILESYSTEM FUNCTION. +// Get attributes for the specified file. + +static char* gMakeDirSpec; + +long GetFileInfo(const char * dirSpec, const char * name, + long * flags, long * time) +{ + long long index = 0; + const char * entryName; + + if (gMakeDirSpec == 0) + gMakeDirSpec = (char *)malloc(1024); + + if (!dirSpec) { + long idx, len; + + len = strlen(name); + + for (idx = len; idx && (name[idx] != '/' && name[idx] != '\\'); idx--) {} + if (idx == 0) { + if(name[idx] == '/' || name[idx] == '\\') ++name; // todo: ensure other functions handel \ properly + gMakeDirSpec[0] = '/'; + gMakeDirSpec[1] = '\0'; + } else { + idx++; + strncpy(gMakeDirSpec, name, idx); + name += idx; + } + dirSpec = gMakeDirSpec; + } + + while (GetDirEntry(dirSpec, &index, &entryName, flags, time) == 0) + { + if (strcmp(entryName, name) == 0) + return 0; // success + } + return -1; // file not found +} + +long GetFileBlock(const char *fileSpec, unsigned long long *firstBlock) +{ + const char * filePath; + BVRef bvr; + + // Resolve the boot volume from the file spec. + + if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL) { + printf("Boot volume for '%s' is bogus\n", fileSpec); + return -1; + } + + return bvr->fs_getfileblock(bvr, (char *)filePath, firstBlock); +} + +//========================================================================== +// GetFreeFD() + +static int GetFreeFd(void) +{ + int fd; + + // Locate a free descriptor slot. + for (fd = 0; fd < NFILES; fd++) { + if (iob[fd].i_flgs == 0) { + return fd; + } + } + stop("Out of file descriptors"); + // not reached + return -1; +} + +//========================================================================== +// iob_from_fdesc() +// +// Return a pointer to an allocated 'iob' based on the file descriptor +// provided. Returns NULL if the file descriptor given is invalid. + +static struct iob * iob_from_fdesc(int fdesc) +{ + register struct iob * io; + + if (fdesc < 0 || fdesc >= NFILES || + ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) + return NULL; + else + return io; +} + +//========================================================================== +// openmem() + +int openmem(char * buf, int len) +{ + int fdesc; + struct iob * io; + + fdesc = GetFreeFd(); + io = &iob[fdesc]; + bzero(io, sizeof(*io)); + + // Mark the descriptor as taken. Set the F_MEM flag to indicate + // that the file buffer is provided by the caller. + + io->i_flgs = F_ALLOC | F_MEM; + io->i_buf = buf; + io->i_filesize = len; + + return fdesc; +} + +//========================================================================== +// open() - Open the file specified by 'path' for reading. + +static int open_bvr(BVRef bvr, const char *filePath, int flags) +{ + struct iob *io; + int fdesc; + int i; + + if (bvr == NULL) { + return -1; + } + + fdesc = GetFreeFd(); + io = &iob[fdesc]; + bzero(io, sizeof(*io)); + + // Mark the descriptor as taken. + io->i_flgs = F_ALLOC; + + // Find the next available memory block in the download buffer. + io->i_buf = (char *) LOAD_ADDR; + for (i = 0; i < NFILES; i++) { + if ((iob[i].i_flgs != F_ALLOC) || (i == fdesc)) { + continue; + } + io->i_buf = MAX(iob[i].i_filesize + iob[i].i_buf, io->i_buf); + } + + // Load entire file into memory. Unnecessary open() calls must be avoided. + gFSLoadAddress = io->i_buf; + io->i_filesize = bvr->fs_loadfile(bvr, (char *)filePath); + if (io->i_filesize < 0) { + close(fdesc); + return -1; + } + return fdesc; +} + +int open(const char *path, int flags) +{ + const char *filepath; + BVRef bvr; + + // Resolve the boot volume from the file spec. + if ((bvr = getBootVolumeRef(path, &filepath)) != NULL) { + return open_bvr(bvr, filepath, flags); + } + return -1; +} + +int open_bvdev(const char *bvd, const char *path, int flags) +{ + const struct devsw *dp; + const char *cp; + BVRef bvr; + int i; + int len; + int unit; + int partition; + + if ((i = open(path, flags)) >= 0) { + return i; + } + + if (bvd == NULL || (len = strlen(bvd)) < 2) { + return -1; + } + + for (dp=devsw; dp->name; dp++) { + if (bvd[0] == dp->name[0] && bvd[1] == dp->name[1]) { + unit = 0; + partition = 0; + /* get optional unit and partition */ + if (len >= 5 && bvd[2] == '(') { /* min must be present xx(0) */ + cp = &bvd[3]; + i = 0; + while ((cp - path) < len && isdigit(*cp)) { + i = i * 10 + *cp++ - '0'; + unit = i; + } + if (*cp++ == ',') { + i = 0; + while ((cp - path) < len && isdigit(*cp)) { + i = i * 10 + *cp++ - '0'; + partition = i; + } + } + } + // 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); + } + return open_bvr(bvr, path, flags); + } + } + return -1; +} + +//========================================================================== +// close() - Close a file descriptor. + +int close(int fdesc) +{ + struct iob * io; + + if ((io = iob_from_fdesc(fdesc)) == NULL) + return (-1); + + io->i_flgs = 0; + + return 0; +} + +//========================================================================== +// lseek() - Reposition the byte offset of the file descriptor from the +// beginning of the file. Returns the relocated offset. + +int b_lseek(int fdesc, int offset, int ptr) +{ + struct iob * io; + + if ((io = iob_from_fdesc(fdesc)) == NULL) + return (-1); + + io->i_offset = offset; + + return offset; +} + +//========================================================================== +// tell() - Returns the byte offset of the file descriptor. + +int tell(int fdesc) +{ + struct iob * io; + + if ((io = iob_from_fdesc(fdesc)) == NULL) + return 0; + + return io->i_offset; +} + +//========================================================================== +// read() - Read up to 'count' bytes of data from the file descriptor +// into the buffer pointed to by buf. + +int read(int fdesc, 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(io->i_buf + io->i_offset, buf, count); + + io->i_offset += count; + + return count; +} + +//========================================================================== +// 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. + +int file_size(int fdesc) +{ + struct iob * io; + + if ((io = iob_from_fdesc(fdesc)) == 0) + return 0; + + return io->i_filesize; +} + +//========================================================================== + +struct dirstuff * vol_opendir(BVRef bvr, const char * path) +{ + struct dirstuff * dirp = 0; + + dirp = (struct dirstuff *) malloc(sizeof(struct dirstuff)); + if (dirp == NULL) + goto error; + + dirp->dir_path = newString(path); + if (dirp->dir_path == NULL) + goto error; + + dirp->dir_bvr = bvr; + + return dirp; + +error: + closedir(dirp); + return NULL; +} + +//========================================================================== + +struct dirstuff * opendir(const char * path) +{ + struct dirstuff * dirp = 0; + const char * dirPath; + BVRef bvr; + + if ((bvr = getBootVolumeRef(path, &dirPath)) == NULL) + goto error; + + dirp = (struct dirstuff *) malloc(sizeof(struct dirstuff)); + if (dirp == NULL) + goto error; + + dirp->dir_path = newString(dirPath); + if (dirp->dir_path == NULL) + goto error; + + dirp->dir_bvr = bvr; + + return dirp; + +error: + closedir(dirp); + return NULL; +} + +//========================================================================== + +int closedir(struct dirstuff * dirp) +{ + if (dirp) { + if (dirp->dir_path) free(dirp->dir_path); + free(dirp); + } + return 0; +} + +//========================================================================== + +int readdir(struct dirstuff * dirp, const char ** name, long * flags, + long * time) +{ + return dirp->dir_bvr->fs_getdirentry( dirp->dir_bvr, + /* dirPath */ dirp->dir_path, + /* dirIndex */ &dirp->dir_index, + /* dirEntry */ (char **)name, flags, time, + 0, 0); +} + +//========================================================================== + +int readdir_ext(struct dirstuff * dirp, const char ** name, long * flags, + long * time, FinderInfo *finderInfo, long *infoValid) +{ + return dirp->dir_bvr->fs_getdirentry( dirp->dir_bvr, + /* dirPath */ dirp->dir_path, + /* dirIndex */ &dirp->dir_index, + /* dirEntry */ (char **)name, + flags, time, + finderInfo, infoValid); +} + +//========================================================================== + +const char * systemConfigDir() +{ + if (gBootFileType == kNetworkDeviceType) + return ""; + return "/Library/Preferences/SystemConfiguration"; +} + +//========================================================================== + +int gBootFileType; + +void scanBootVolumes( int biosdev, int * count ) +{ + BVRef bvr = 0; + + bvr = diskScanBootVolumes(biosdev, count); + if (bvr == NULL) + { + bvr = nbpScanBootVolumes(biosdev, count); + if (bvr != NULL) + { + gBootFileType = kNetworkDeviceType; + } + } + else + { + gBootFileType = kBlockDeviceType; + } +} + +//========================================================================== + +void scanDisks(int biosdev, int *count) +{ + #define MAX_HDD_COUNT 32 + int bvCount; + int hd = 0; + + // Testing up to MAX_HDD_COUNT hard drives. + while(!testBiosread(0x80 + hd, 0) && hd < MAX_HDD_COUNT) + { + bvCount = 0; + scanBootVolumes(0x80 + hd, &bvCount); + hd++; + } + + // Also scanning CD/DVD drive. + if (biosDevIsCDROM(gBIOSDev)) + { + bvCount = 0; + scanBootVolumes(gBIOSDev, &bvCount); + msglog("biosDevIsCDROM and bvCount=%d\n", bvCount); + } +} + +//========================================================================== + +BVRef selectBootVolume( BVRef chain ) +{ + bool filteredChain = false; + bool foundPrimary = false; + BVRef bvr, bvr1 = 0, bvr2 = 0; + + if (chain->filtered) filteredChain = true; + + if (multiboot_partition_set) + for ( bvr = chain; bvr; bvr = bvr->next ) + if ( bvr->part_no == multiboot_partition && bvr->biosdev == gBIOSDev ) + return bvr; + + /* + * 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. + */ + char *val = XMLDecode(getStringForKey(kDefaultPartition, &bootInfo->chameleonConfig)); + 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 (multiboot_skip_partition_set) { + if (bvr->part_no == multiboot_skip_partition) continue; + } + 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. + */ + if (foundPrimary) + { + for ( bvr = chain; bvr; bvr = bvr->next ) + { + 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; +} + +//========================================================================== + +#define LP '(' +#define RP ')' +int gBIOSDev; + +/*! + This is like boot2's gBootVolume except it is for the internal use of + libsaio to track which volume an unqualified path should be relative to. + This replaces bootInfo->kernDev as the carrier of this information. + */ +static BVRef gRootVolume; + +void setRootVolume(BVRef volume) +{ + gRootVolume = volume; + // Veto non-native FS. Basically that means don't allow the root volume to + // be set to a volume we can't read files from. + if(gRootVolume != NULL && ((gRootVolume->flags & kBVFlagNativeBoot) == 0)) + gRootVolume = NULL; +} + +void setBootGlobals(BVRef chain) +{ + // Record default boot device. + gBootVolume = selectBootVolume(chain); + + // turbo - Save the ORIGINAL boot volume too for loading our mkext + if (!gBIOSBootVolume) gBIOSBootVolume = gBootVolume; + + setRootVolume(gBootVolume); +} + +/*! + Extracts the volume selector from the pathname, returns the selected + BVRef, and sets *outPath to the remainder of the path. + If the path did not include a volume selector then the current volume + is used. When called with a volume selector the current volume + is changed to the selected volume unless the volume selector is + that of a ramdisk. + */ +BVRef getBootVolumeRef( const char * path, const char ** outPath ) +{ + const char * cp; + BVRef bvr = gRootVolume; + int biosdev = gBIOSDev; + + // Search for left parenthesis in the path specification. + + for (cp = path; *cp; cp++) { + if (*cp == LP || *cp == '/') break; + } + + if (*cp != LP) // no left paren found + { + // Path is using the implicit current device so if there is + // no current device, then we must fail. + cp = path; + if ( gRootVolume == NULL ) + return NULL; + } + else if ((cp - path) == 2) // found "xx(" + { + const struct devsw * dp; + const char * xp = path; + int i; + int unit = -1; + int part = -1; + + cp++; + + // Check the 2 character device name pointed by 'xp'. + + for (dp = devsw; dp->name; dp++) + { + if ((xp[0] == dp->name[0]) && (xp[1] == dp->name[1])) + break; // found matching entry + } + if (dp->name == NULL) + { + error("Unknown device '%c%c'\n", xp[0], xp[1]); + return NULL; + } + + // Extract the optional unit number from the specification. + // hd(unit) or hd(unit, part). + + i = 0; + while (*cp >= '0' && *cp <= '9') + { + i = i * 10 + *cp++ - '0'; + unit = i; + } + + // Unit is no longer optional and never really was. + // If the user failed to specify it then the unit number from the previous kernDev + // would have been used which makes little sense anyway. + // For example, if the user did fd()/foobar and the current root device was the + // second hard disk (i.e. unit 1) then fd() would select the second floppy drive! + if(unit == -1) + return NULL; + + // Extract the optional partition number from the specification. + + if (*cp == ',') + part = atoi(++cp); + + // If part is not specified part will be -1 whereas before it would have been + // whatever the last partition was which makes about zero sense if the device + // has been switched. + + // Skip past the right paren. + + for ( ; *cp && *cp != RP; cp++) /* LOOP */; + if (*cp == RP) cp++; + + biosdev = dp->biosdev + unit; + + // 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; + } + else + { + // Bad device specifier, skip past the right paren. + + for ( cp++; *cp && *cp != RP; cp++) /* LOOP */; + if (*cp == RP) cp++; + // If gRootVolume was NULL, then bvr will be NULL as well which + // should be caught by the caller. + } + + // Returns the file path following the device spec. + // e.g. 'hd(1,b)mach_kernel' is reduced to 'mach_kernel'. + + *outPath = cp; + + return bvr; +} + +//========================================================================== +// 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; + + bvr = bvr1 = NULL; + + // 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. + + scanBootVolumes( biosdev, NULL ); + bvrChain = getBVChainForBIOSDev(biosdev); + + // 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; + + *str = '\0'; + + 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/slice/trunkM/i386/libsaio/dram_controllers.h =================================================================== --- branches/slice/trunkM/i386/libsaio/dram_controllers.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/dram_controllers.h (revision 1171) @@ -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/slice/trunkM/i386/libsaio/load.c =================================================================== --- branches/slice/trunkM/i386/libsaio/load.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/load.c (revision 1171) @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 2.0 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * load.c - Functions for decoding a Mach-o Kernel. + * + * Copyright (c) 1998-2003 Apple Computer, Inc. + * + */ + +#include +#include +#include + +#include + +static long DecodeSegment(long cmdBase, unsigned int*load_addr, unsigned int *load_size); +static long DecodeUnixThread(long cmdBase, unsigned int *entry); +static long DecodeSymbolTable(long cmdBase); + + +static unsigned long gBinaryAddress; +bool gHaveKernelCache; /* XXX aserebln: uninitialized? and only set to true, never to false */ +cpu_type_t archCpuType=CPU_TYPE_I386; + +// Public Functions + +long ThinFatFile(void **binary, unsigned long *length) +{ + unsigned long nfat, swapped, size = 0; + struct fat_header *fhp = (struct fat_header *)*binary; + struct fat_arch *fap = + (struct fat_arch *)((unsigned long)*binary + sizeof(struct fat_header)); + cpu_type_t fapcputype; + uint32_t fapoffset; + uint32_t fapsize; + + if (fhp->magic == FAT_MAGIC) { + nfat = fhp->nfat_arch; + swapped = 0; + } else if (fhp->magic == FAT_CIGAM) { + nfat = OSSwapInt32(fhp->nfat_arch); + swapped = 1; + } else { + return -1; + } + + for (; nfat > 0; nfat--, fap++) { + if (swapped) { + fapcputype = OSSwapInt32(fap->cputype); + fapoffset = OSSwapInt32(fap->offset); + fapsize = OSSwapInt32(fap->size); + } + else + { + fapcputype = fap->cputype; + fapoffset = fap->offset; + fapsize = fap->size; + } + + if (fapcputype == archCpuType) { + *binary = (void *) ((unsigned long)*binary + fapoffset); + size = fapsize; + break; + } + } + + if (length != 0) *length = size; + + return 0; +} + +long DecodeMachO(void *binary, entry_t *rentry, char **raddr, int *rsize) +{ + struct mach_header *mH; + unsigned long ncmds, cmdBase, cmd, cmdsize, cmdstart; + // long headerBase, headerAddr, headerSize; + unsigned int vmaddr = ~0; + unsigned int vmend = 0; + unsigned long cnt; + long ret = -1; + unsigned int entry = 0; + + gBinaryAddress = (unsigned long)binary; + + mH = (struct mach_header *)(gBinaryAddress); + switch (archCpuType) + { + case CPU_TYPE_I386: + if (mH->magic != MH_MAGIC) { + error("Mach-O file has bad magic number\n"); + return -1; + } + cmdstart = (unsigned long)gBinaryAddress + sizeof(struct mach_header); + break; + case CPU_TYPE_X86_64: + if (mH->magic != MH_MAGIC_64 && mH->magic == MH_MAGIC) + return -1; + if (mH->magic != MH_MAGIC_64) { + error("Mach-O file has bad magic number\n"); + return -1; + } + cmdstart = (unsigned long)gBinaryAddress + sizeof(struct mach_header_64); + break; + default: + error("Unknown CPU type\n"); + return -1; + } + + cmdBase = cmdstart; + +#if DEBUG + printf("magic: %x\n", (unsigned)mH->magic); + printf("cputype: %x\n", (unsigned)mH->cputype); + printf("cpusubtype: %x\n", (unsigned)mH->cpusubtype); + printf("filetype: %x\n", (unsigned)mH->filetype); + printf("ncmds: %x\n", (unsigned)mH->ncmds); + printf("sizeofcmds: %x\n", (unsigned)mH->sizeofcmds); + printf("flags: %x\n", (unsigned)mH->flags); + getchar(); +#endif + + ncmds = mH->ncmds; + + for (cnt = 0; cnt < ncmds; cnt++) { + cmd = ((long *)cmdBase)[0]; + cmdsize = ((long *)cmdBase)[1]; + unsigned int load_addr; + unsigned int load_size; + + switch (cmd) { + case LC_SEGMENT_64: + case LC_SEGMENT: + ret = DecodeSegment(cmdBase, &load_addr, &load_size); + if (ret == 0 && load_size != 0 && load_addr >= KERNEL_ADDR) { + vmaddr = MIN(vmaddr, load_addr); + vmend = MAX(vmend, load_addr + load_size); + } + break; + + case LC_UNIXTHREAD: + ret = DecodeUnixThread(cmdBase, &entry); + break; + + case LC_SYMTAB: + break; + + default: +#if NOTDEF + printf("Ignoring cmd type %d.\n", (unsigned)cmd); +#endif + break; + } + + if (ret != 0) return -1; + + cmdBase += cmdsize; + } + + *rentry = (entry_t)( (unsigned long) entry & 0x3fffffff ); + *rsize = vmend - vmaddr; + *raddr = (char *)vmaddr; + + cmdBase = cmdstart; + for (cnt = 0; cnt < ncmds; cnt++) { + cmd = ((long *)cmdBase)[0]; + cmdsize = ((long *)cmdBase)[1]; + + if(cmd==LC_SYMTAB) + if (DecodeSymbolTable(cmdBase)!=0) + return -1; + + cmdBase += cmdsize; + } + + return ret; +} + +// Private Functions + +static long DecodeSegment(long cmdBase, unsigned int *load_addr, unsigned int *load_size) +{ + unsigned long vmaddr, fileaddr; + long vmsize, filesize; + char *segname; + + if (((long *)cmdBase)[0]==LC_SEGMENT_64) + { + struct segment_command_64 *segCmd; + + segCmd = (struct segment_command_64 *)cmdBase; + + vmaddr = (segCmd->vmaddr & 0x3fffffff); + vmsize = segCmd->vmsize; + fileaddr = (gBinaryAddress + segCmd->fileoff); + filesize = segCmd->filesize; + + segname=segCmd->segname; + +#ifdef DEBUG + printf("segname: %s, vmaddr: %x, vmsize: %x, fileoff: %x, filesize: %x, nsects: %d, flags: %x.\n", + segCmd->segname, (unsigned)vmaddr, (unsigned)vmsize, (unsigned)fileaddr, (unsigned)filesize, + (unsigned) segCmd->nsects, (unsigned)segCmd->flags); + getchar(); +#endif + } + else + { + struct segment_command *segCmd; + + segCmd = (struct segment_command *)cmdBase; + + vmaddr = (segCmd->vmaddr & 0x3fffffff); + vmsize = segCmd->vmsize; + fileaddr = (gBinaryAddress + segCmd->fileoff); + filesize = segCmd->filesize; + + segname=segCmd->segname; + +#ifdef DEBUG + printf("segname: %s, vmaddr: %x, vmsize: %x, fileoff: %x, filesize: %x, nsects: %d, flags: %x.\n", + segCmd->segname, (unsigned)vmaddr, (unsigned)vmsize, (unsigned)fileaddr, (unsigned)filesize, + (unsigned) segCmd->nsects, (unsigned)segCmd->flags); + getchar(); +#endif + } + + if (vmsize == 0 || filesize == 0) { + *load_addr = ~0; + *load_size = 0; + return 0; + } + + if (! ((vmaddr >= KERNEL_ADDR && + (vmaddr + vmsize) <= (KERNEL_ADDR + KERNEL_LEN)) || + (vmaddr >= HIB_ADDR && + (vmaddr + vmsize) <= (HIB_ADDR + HIB_LEN)))) { + stop("Kernel overflows available space"); + } + + if (vmsize && ((strcmp(segname, "__PRELINK_INFO") == 0) || (strcmp(segname, "__PRELINK") == 0))) + gHaveKernelCache = true; + + // Copy from file load area. + if (vmsize>0 && filesize>0) + bcopy((char *)fileaddr, (char *)vmaddr, vmsize>filesize?filesize:vmsize); + + // Zero space at the end of the segment. + if (vmsize > filesize) + bzero((char *)(vmaddr + filesize), vmsize - filesize); + + *load_addr = vmaddr; + *load_size = vmsize; + + return 0; +} + +static long DecodeUnixThread(long cmdBase, unsigned int *entry) +{ + switch (archCpuType) + { + case CPU_TYPE_I386: + { + i386_thread_state_t *i386ThreadState; + + i386ThreadState = (i386_thread_state_t *) + (cmdBase + sizeof(struct thread_command) + 8); + + *entry = i386ThreadState->eip; + return 0; + } + + case CPU_TYPE_X86_64: + { + x86_thread_state64_t *x86_64ThreadState; + + x86_64ThreadState = (x86_thread_state64_t *) + (cmdBase + sizeof(struct thread_command) + 8); + + *entry = x86_64ThreadState->rip; + return 0; + } + + default: + error("Unknown CPU type\n"); + return -1; + } +} + +static long DecodeSymbolTable(long cmdBase) +{ + struct symtab_command *symTab, *symTableSave; + long tmpAddr, symsSize, totalSize; + long gSymbolTableAddr; + long gSymbolTableSize; + + symTab = (struct symtab_command *)cmdBase; + +#if DEBUG + printf("symoff: %x, nsyms: %x, stroff: %x, strsize: %x\n", + symTab->symoff, symTab->nsyms, symTab->stroff, symTab->strsize); + getchar(); +#endif + + symsSize = symTab->stroff - symTab->symoff; + totalSize = symsSize + symTab->strsize; + + gSymbolTableSize = totalSize + sizeof(struct symtab_command); + gSymbolTableAddr = AllocateKernelMemory(gSymbolTableSize); + // Add the SymTab to the memory-map. + AllocateMemoryRange("Kernel-__SYMTAB", gSymbolTableAddr, gSymbolTableSize, -1); + + symTableSave = (struct symtab_command *)gSymbolTableAddr; + tmpAddr = gSymbolTableAddr + sizeof(struct symtab_command); + + symTableSave->symoff = tmpAddr; + symTableSave->nsyms = symTab->nsyms; + symTableSave->stroff = tmpAddr + symsSize; + symTableSave->strsize = symTab->strsize; + + bcopy((char *)(gBinaryAddress + symTab->symoff), + (char *)tmpAddr, totalSize); + return 0; +} Index: branches/slice/trunkM/i386/libsaio/nbp.c =================================================================== --- branches/slice/trunkM/i386/libsaio/nbp.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/nbp.c (revision 1171) @@ -0,0 +1,145 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include "libsaio.h" + +/* This NBP code is pretty useless because it just blindly calls INT 2B. + Presumably INT 2B was implemented by some first-stage bootloader that + is long gone. + + One good reason to disable this is that nbpScanBootVolumes always + succeeds. The scanBootVolumes function thus never fails because + it always falls back to NBP. This is a problem because there is + other code in the booter (for example, in open) which needs to + fail instead of attempting to use this NBP which will often + hang the machine. + */ +#ifndef NBP_SUPPORT +#define NBP_SUPPORT 0 +#endif + +#if NBP_SUPPORT + +/* + * Convert zero-based linear address to far pointer. + */ +#define GET_FP(x) ( (((x) & 0xffff0000) << (16 - 4)) | ((x) & 0xffff) ) + +/*========================================================================== + * Issue a command to the network loader. + * + * The 'cmd' command structure should be allocated on the stack to + * ensure that it resides within the addressable range for the + * network loader, which runs in real mode. + */ +static UInt32 nbp(nbpCommandCode_t code, nbpCommand_u * cmd) +{ + loader(code, GET_FP((UInt32) cmd)); + + // Must re-enable the A20 address line, the PXE firmware will + // disable the A20 line control. + // + enableA20(); + + return cmd->header.status; +} + +/*========================================================================== + * Unload Base Code Stack command. + */ +UInt32 nbpUnloadBaseCode() +{ + return nbp(nbpCommandUnloadBaseCode, (nbpCommand_u *) 0); +} + +/*========================================================================== + * TFTP Read File command. + */ +static long NBPLoadFile(CICell ih, char * filePath) +{ + nbpCommandTFTPReadFile_s cmd; + UInt32 ret; + + strcpy((char *)cmd.filename, filePath); + cmd.status = nbpStatusFailed; + cmd.bufferSize = TFTP_LEN; + cmd.buffer = TFTP_ADDR; + + verbose("Loading file: %s\n", filePath); + + ret = nbp(nbpCommandTFTPReadFile, (nbpCommand_u *) &cmd); + + return (ret == nbpStatusSuccess) ? (long)cmd.bufferSize : -1; +} + +/*========================================================================== + * GetDirEntry is not supported. + */ +static long NBPGetDirEntry(CICell ih, char * dirPath, long long * dirIndex, + char ** name, long * flags, long * time, + FinderInfo * finderInfo, long * infoValid) +{ + return -1; +} + +//========================================================================== + +static void NBPGetDescription(CICell ih, char * str, long strMaxLen) +{ + sprintf( str, "Ethernet PXE Client" ); +} + +//========================================================================== + +BVRef nbpScanBootVolumes( int biosdev, int * countPtr ) +{ + static BVRef gNetBVR = NULL; + + if ( countPtr ) *countPtr = 1; + + if ( !gNetBVR ) + { + gNetBVR = malloc( sizeof(*gNetBVR) ); + if ( gNetBVR ) + { + bzero(gNetBVR, sizeof(*gNetBVR)); + gNetBVR->biosdev = biosdev; + gNetBVR->flags = kBVFlagPrimary | kBVFlagNativeBoot; + gNetBVR->description = NBPGetDescription; + gNetBVR->fs_loadfile = NBPLoadFile; + gNetBVR->fs_getdirentry = NBPGetDirEntry; + } + } + return gNetBVR; +} +#else +BVRef nbpScanBootVolumes( int biosdev, int * countPtr ) +{ + return NULL; +} +UInt32 nbpUnloadBaseCode() +{ + return 0; +} +#endif Index: branches/slice/trunkM/i386/libsaio/ntfs.h =================================================================== --- branches/slice/trunkM/i386/libsaio/ntfs.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/ntfs.h (revision 1171) @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 2.0 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +extern void NTFSGetDescription(CICell ih, char *str, long strMaxLen); +extern bool NTFSProbe (const void *buf); +extern long NTFSGetUUID(CICell ih, char *uuidStr); Index: branches/slice/trunkM/i386/libsaio/nvidia.h =================================================================== --- branches/slice/trunkM/i386/libsaio/nvidia.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/nvidia.h (revision 1171) @@ -0,0 +1,135 @@ +/* + * NVidia injector + * + * Copyright (C) 2009 Jasmin Fazlic, iNDi + * + * NVidia injector 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 3 of the License, or + * (at your option) any later version. + * + * NVidia driver and injector 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 NVidia injector. If not, see . + */ + /* + * Alternatively you can choose to comply with APSL + */ + +/* + * DCB-Table parsing is based on software (nouveau driver) originally distributed under following license: + * + * + * Copyright 2005-2006 Erik Waling + * Copyright 2006 Stephane Marchesin + * Copyright 2007-2009 Stuart Bennett + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __LIBSAIO_NVIDIA_H +#define __LIBSAIO_NVIDIA_H + +bool setup_nvidia_devprop(pci_dt_t *nvda_dev); + +struct nv_chipsets_t { + unsigned device; + char *name; +}; + +#define DCB_MAX_NUM_ENTRIES 16 +#define DCB_MAX_NUM_I2C_ENTRIES 16 + +#define DCB_LOC_ON_CHIP 0 + +struct bios { + uint16_t signature; /* 0x55AA */ + 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 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) +#define NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED (1 << 0) + +#define REG8(reg) ((volatile uint8_t *)regs)[(reg)] +#define REG16(reg) ((volatile uint16_t *)regs)[(reg) >> 1] +#define REG32(reg) ((volatile uint32_t *)regs)[(reg) >> 2] + +#define NV_ARCH_03 0x03 +#define NV_ARCH_04 0x04 +#define NV_ARCH_10 0x10 +#define NV_ARCH_20 0x20 +#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 +#define CHIPSET_NV10 0x0100 +#define CHIPSET_NV11 0x0110 +#define CHIPSET_NV15 0x0150 +#define CHIPSET_NV17 0x0170 +#define CHIPSET_NV18 0x0180 +#define CHIPSET_NFORCE 0x01A0 +#define CHIPSET_NFORCE2 0x01F0 +#define CHIPSET_NV20 0x0200 +#define CHIPSET_NV25 0x0250 +#define CHIPSET_NV28 0x0280 +#define CHIPSET_NV30 0x0300 +#define CHIPSET_NV31 0x0310 +#define CHIPSET_NV34 0x0320 +#define CHIPSET_NV35 0x0330 +#define CHIPSET_NV36 0x0340 +#define CHIPSET_NV40 0x0040 +#define CHIPSET_NV41 0x00C0 +#define CHIPSET_NV43 0x0140 +#define CHIPSET_NV44 0x0160 +#define CHIPSET_NV44A 0x0220 +#define CHIPSET_NV45 0x0210 +#define CHIPSET_NV50 0x0190 +#define CHIPSET_NV84 0x0400 +#define CHIPSET_MISC_BRIDGED 0x00F0 +#define CHIPSET_G70 0x0090 +#define CHIPSET_G71 0x0290 +#define CHIPSET_G72 0x01D0 +#define CHIPSET_G73 0x0390 + +// integrated GeForces (6100, 6150) +#define CHIPSET_C51 0x0240 + +// variant of C51, seems based on a G70 design +#define CHIPSET_C512 0x03D0 +#define CHIPSET_G73_BRIDGED 0x02E0 + +#endif /* !__LIBSAIO_NVIDIA_H */ Index: branches/slice/trunkM/i386/libsaio/ufs_byteorder.h =================================================================== --- branches/slice/trunkM/i386/libsaio/ufs_byteorder.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/ufs_byteorder.h (revision 1171) @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1992 NeXT Computer, Inc. + * + * UFS byte swapping routines to make a big endian file system useful on a + * little endian machine. + * + * HISTORY + * + * 8 Jul 1992 Brian Pinkerton at NeXT + * Created. + */ + +#ifndef __LIBSAIO_UFS_BYTEORDER_H +#define __LIBSAIO_UFS_BYTEORDER_H + +//#include +#include +#include +#include +#include +#include + +void byte_swap_ints(unsigned int *array, int count); +void byte_swap_shorts(unsigned short *array, int count); +void byte_swap_longlongs(unsigned long long *array, int count); + +void byte_swap_superblock(struct fs *sb); +void byte_swap_dinode_in(struct dinode *di); +void byte_swap_dir_block_in(char *addr, int count); +void byte_swap_inode_in(struct dinode *dc, struct dinode *ic); + +#endif /* !__LIBSAIO_UFS_BYTEORDER_H */ Index: branches/slice/trunkM/i386/libsaio/acpi.h =================================================================== --- branches/slice/trunkM/i386/libsaio/acpi.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/acpi.h (revision 1171) @@ -0,0 +1,153 @@ +#ifndef __LIBSAIO_ACPI_H +#define __LIBSAIO_ACPI_H + +#define ACPI_RANGE_START (0x0E0000) +#define ACPI_RANGE_END (0x0FFFFF) + +#define UINT64_LE_FROM_CHARS(a,b,c,d,e,f,g,h) \ +( ((uint64_t)h << 56) \ +| ((uint64_t)g << 48) \ +| ((uint64_t)f << 40) \ +| ((uint64_t)e << 32) \ +| ((uint64_t)d << 24) \ +| ((uint64_t)c << 16) \ +| ((uint64_t)b << 8) \ +| ((uint64_t)a << 0) \ +) + +#define ACPI_SIGNATURE_UINT64_LE UINT64_LE_FROM_CHARS('R','S','D',' ','P','T','R',' ') + +/* Per ACPI 3.0a spec */ + +// TODO Migrate +struct acpi_2_rsdp { + char Signature[8]; + uint8_t Checksum; + char OEMID[6]; + uint8_t Revision; + uint32_t RsdtAddress; + uint32_t Length; + uint64_t XsdtAddress; + uint8_t ExtendedChecksum; + char Reserved[3]; +} __attribute__((packed)); + +// TODO Migrate +struct acpi_2_rsdt { + 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_xsdt { + 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_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; + uint8_t Revision; + uint8_t Checksum; + char OEMID[6]; + char OEMTableId[8]; + uint32_t OEMRevision; + uint32_t CreatorId; + uint32_t CreatorRevision; + uint32_t FIRMWARE_CTRL; + uint32_t DSDT; + uint8_t Model; // JrCs + uint8_t PM_Profile; // JrCs + 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; + uint8_t Reset_SpaceID; + uint8_t Reset_BitWidth; + uint8_t Reset_BitOffset; + uint8_t Reset_AccessWidth; + uint64_t Reset_Address; + uint8_t Reset_Value; + uint8_t Reserved[3]; + + uint64_t X_FIRMWARE_CTRL; + uint64_t X_DSDT; +/* End Asere */ + /*We absolutely don't care about theese fields*/ + uint8_t notimp2[96]; +} __attribute__((packed)); + +#endif /* !__LIBSAIO_ACPI_H */ Index: branches/slice/trunkM/i386/libsaio/sl.h =================================================================== --- branches/slice/trunkM/i386/libsaio/sl.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/sl.h (revision 1171) @@ -0,0 +1,67 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __LIBSAIO_SL_H +#define __LIBSAIO_SL_H + +#include +#include +#include +#include "libsaio.h" + +#define SWAP_BE16(x) OSSwapBigToHostInt16(x) +#define SWAP_LE16(x) OSSwapLittleToHostInt16(x) +#define SWAP_BE32(x) OSSwapBigToHostInt32(x) +#define SWAP_LE32(x) OSSwapLittleToHostInt32(x) +#define SWAP_BE64(x) OSSwapBigToHostInt64(x) +#define SWAP_LE64(x) OSSwapLittleToHostInt64(x) + +// File Permissions and Types +enum { + kPermOtherExecute = 1 << 0, + kPermOtherWrite = 1 << 1, + kPermOtherRead = 1 << 2, + kPermGroupExecute = 1 << 3, + kPermGroupWrite = 1 << 4, + kPermGroupRead = 1 << 5, + kPermOwnerExecute = 1 << 6, + kPermOwnerWrite = 1 << 7, + kPermOwnerRead = 1 << 8, + kPermMask = 0x1FF, + kOwnerNotRoot = 1 << 9, + kFileTypeUnknown = 0x0 << 16, + kFileTypeFlat = 0x1 << 16, + kFileTypeDirectory = 0x2 << 16, + kFileTypeLink = 0x3 << 16, + kFileTypeMask = 0x3 << 16 +}; + +#define Seek(c, p) diskSeek(c, p); +#define Read(c, a, l) diskRead(c, a, l); + +extern void * gFSLoadAddress; +extern cpu_type_t archCpuType; +cpu_type_t detectCpuType (); + +#endif /* !__LIBSAIO_SL_H */ Index: branches/slice/trunkM/i386/libsaio/platform.c =================================================================== --- branches/slice/trunkM/i386/libsaio/platform.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/platform.c (revision 1171) @@ -0,0 +1,73 @@ +/* + * platform.c + * + * AsereBLN: cleanup + */ + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "pci.h" +#include "platform.h" +#include "cpu.h" +#include "spd.h" +#include "dram_controllers.h" + +#ifndef DEBUG_PLATFORM +#define DEBUG_PLATFORM 0 +#endif + +#if DEBUG_PLATFORM +#define DBG(x...) verbose(x) +#else +#define DBG(x...) +#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) */ +inline bool platformCPUFeature(uint32_t feature) +{ + return (Platform->CPU.Features & feature); +} + +/** scan mem for memory autodection purpose */ +void scan_mem() { + static bool done = false; + if (done) return; + + /* our code only works on Intel chipsets so make sure here */ + if (pci_config_read16(PCIADDR(0, 0x00, 0), 0x00) != 0x8086) + bootInfo->memDetect = false; + else + bootInfo->memDetect = true; + /* manually */ + getBoolForKey(kUseMemDetect, &bootInfo->memDetect, &bootInfo->chameleonConfig); + + if (bootInfo->memDetect) { + if (dram_controller_dev != NULL) { + scan_dram_controller(dram_controller_dev); // Rek: pci dev ram controller direct and fully informative scan ... + } + scan_spd(Platform); + } + done = true; +} + +/** + Scan platform hardware information, called by the main entry point (common_boot() ) + _before_ bootConfig xml parsing settings are loaded +*/ +void scan_platform(void) +{ + Platform = malloc(sizeof(PlatformInfo_t)); + memset(Platform, 0, sizeof(PlatformInfo_t)); + gPlatform = (void*)Platform; +// BootOrder = malloc(sizeof(BLESS_EFI_LOAD_OPTION)); +// memset(BootOrder, 0, sizeof(BLESS_EFI_LOAD_OPTION)); +// gBootOrder = (void*)BootOrder; + + build_pci_dt(); + scan_cpu(Platform); + //scan_mem(); Rek: called after pci devs init in fake_efi now ... +} Index: branches/slice/trunkM/i386/libsaio/cpu.c =================================================================== --- branches/slice/trunkM/i386/libsaio/cpu.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/cpu.c (revision 1171) @@ -0,0 +1,415 @@ +/* + * Copyright 2008 Islam Ahmed Zaid. All rights reserved. + * AsereBLN: 2009: cleanup and bugfix + */ + +#include "libsaio.h" +#include "platform.h" +//#include "mem.h" +#include "smbios_getters.h" +#include "cpu.h" +#include "bootstruct.h" +#include "boot.h" + +#ifndef DEBUG_CPU +#define DEBUG_CPU 0 +#endif + +#if DEBUG_CPU +#define DBG(x...) printf(x) +#else +#define DBG(x...) msglog(x) +#endif + +/* + * DFE: Measures the TSC frequency in Hz (64-bit) using the ACPI PM timer + */ +static uint64_t measure_tsc_frequency(void) +{ + uint64_t tscStart; + uint64_t tscEnd; + uint64_t tscDelta = 0xffffffffffffffffULL; + unsigned long pollCount; + uint64_t retval = 0; + int i; + + /* Time how many TSC ticks elapse in 30 msec using the 8254 PIT + * counter 2. We run this loop 3 times to make sure the cache + * is hot and we take the minimum delta from all of the runs. + * That is to say that we're biased towards measuring the minimum + * number of TSC ticks that occur while waiting for the timer to + * expire. That theoretically helps avoid inconsistencies when + * running under a VM if the TSC is not virtualized and the host + * steals time. The TSC is normally virtualized for VMware. + */ + for(i = 0; i < 10; ++i) + { + enable_PIT2(); + set_PIT2_mode0(CALIBRATE_LATCH); + tscStart = rdtsc64(); + pollCount = poll_PIT2_gate(); + tscEnd = rdtsc64(); + /* The poll loop must have run at least a few times for accuracy */ + if(pollCount <= 1) + continue; + /* The TSC must increment at LEAST once every millisecond. We + * should have waited exactly 30 msec so the TSC delta should + * be >= 30. Anything less and the processor is way too slow. + */ + if((tscEnd - tscStart) <= CALIBRATE_TIME_MSEC) + continue; + // tscDelta = MIN(tscDelta, (tscEnd - tscStart)) + if( (tscEnd - tscStart) < tscDelta ) + tscDelta = tscEnd - tscStart; + } + /* tscDelta is now the least number of TSC ticks the processor made in + * a timespan of 0.03 s (e.g. 30 milliseconds) + * Linux thus divides by 30 which gives the answer in kiloHertz because + * 1 / ms = kHz. But we're xnu and most of the rest of the code uses + * Hz so we need to convert our milliseconds to seconds. Since we're + * dividing by the milliseconds, we simply multiply by 1000. + */ + + /* Unlike linux, we're not limited to 32-bit, but we do need to take care + * that we're going to multiply by 1000 first so we do need at least some + * arithmetic headroom. For now, 32-bit should be enough. + * Also unlike Linux, our compiler can do 64-bit integer arithmetic. + */ + if(tscDelta > (1ULL<<32)) + retval = 0; + else + { + retval = tscDelta * 1000 / 30; + } + disable_PIT2(); + return retval; +} + +/* + * Calculates the FSB and CPU frequencies using specific MSRs for each CPU + * - multi. is read from a specific MSR. In the case of Intel, there is: + * a max multi. (used to calculate the FSB freq.), + * and a current multi. (used to calculate the CPU freq.) + * - fsbFrequency = tscFrequency / multi + * - cpuFrequency = fsbFrequency * multi + */ + +void scan_cpu(PlatformInfo_t *p) +{ + uint64_t tscFrequency, fsbFrequency, cpuFrequency; + uint64_t msr, flex_ratio; + uint8_t maxcoef, maxdiv, currcoef, bus_ratio_max, currdiv; + const char *newratio; + int len, myfsb; + uint8_t bus_ratio_min; + uint32_t max_ratio, min_ratio; + + max_ratio = min_ratio = myfsb = bus_ratio_min = 0; + maxcoef = maxdiv = bus_ratio_max = currcoef = currdiv = 0; + + /* get cpuid values */ + do_cpuid(0x00000000, p->CPU.CPUID[CPUID_0]); + do_cpuid(0x00000001, p->CPU.CPUID[CPUID_1]); + do_cpuid(0x00000002, p->CPU.CPUID[CPUID_2]); + do_cpuid(0x00000003, p->CPU.CPUID[CPUID_3]); + do_cpuid2(0x00000004, 0, p->CPU.CPUID[CPUID_4]); + do_cpuid(0x80000000, p->CPU.CPUID[CPUID_80]); + if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 1) { + do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]); + } +#if DEBUG_CPU + { + int i; + printf("CPUID Raw Values:\n"); + for (i=0; iCPU.CPUID[i][0], p->CPU.CPUID[i][1], + p->CPU.CPUID[i][2], p->CPU.CPUID[i][3]); + } + } +#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); + p->CPU.ExtFamily = bitfield(p->CPU.CPUID[CPUID_1][0], 27, 20); + + p->CPU.Model += (p->CPU.ExtModel << 4); + + if (p->CPU.Vendor == 0x756E6547 /* Intel */ && + p->CPU.Family == 0x06 && + p->CPU.Model >= CPUID_MODEL_NEHALEM && + p->CPU.Model != CPUID_MODEL_ATOM // MSR is *NOT* available on the Intel Atom CPU + ){ + msr = rdmsr64(MSR_CORE_THREAD_COUNT); // Undocumented MSR in Nehalem and newer CPUs + p->CPU.NoCores = bitfield((uint32_t)msr, 31, 16); // Using undocumented MSR to get actual values + p->CPU.NoThreads = bitfield((uint32_t)msr, 15, 0); // Using undocumented MSR to get actual values + } else { + p->CPU.NoThreads = bitfield(p->CPU.CPUID[CPUID_1][1], 23, 16); // Use previous method for Cores and Threads + p->CPU.NoCores = bitfield(p->CPU.CPUID[CPUID_4][0], 31, 26) + 1; + } + + /* 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 NULL 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; + } + if ((bit(25) & p->CPU.CPUID[CPUID_1][3]) != 0) { + p->CPU.Features |= CPU_FEATURE_SSE; + } + if ((bit(26) & p->CPU.CPUID[CPUID_1][3]) != 0) { + p->CPU.Features |= CPU_FEATURE_SSE2; + } + if ((bit(0) & p->CPU.CPUID[CPUID_1][2]) != 0) { + p->CPU.Features |= CPU_FEATURE_SSE3; + } + if ((bit(19) & p->CPU.CPUID[CPUID_1][2]) != 0) { + p->CPU.Features |= CPU_FEATURE_SSE41; + } + if ((bit(20) & p->CPU.CPUID[CPUID_1][2]) != 0) { + p->CPU.Features |= CPU_FEATURE_SSE42; + } + 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; + } + + tscFrequency = measure_tsc_frequency(); + fsbFrequency = 0; + cpuFrequency = 0; + + if ((p->CPU.Vendor == 0x756E6547 /* Intel */) && ((p->CPU.Family == 0x06) || (p->CPU.Family == 0x0f))) { + int intelCPU = p->CPU.Model; + 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 == CPU_MODEL_NEHALEM || + p->CPU.Model == CPU_MODEL_FIELDS || + p->CPU.Model == CPU_MODEL_DALES || + p->CPU.Model == CPU_MODEL_DALES_32NM || + p->CPU.Model == CPU_MODEL_WESTMERE || + p->CPU.Model == CPU_MODEL_NEHALEM_EX || + p->CPU.Model == CPU_MODEL_WESTMERE_EX || + p->CPU.Model == CPU_MODEL_SANDY || + p->CPU.Model == CPU_MODEL_SANDY_XEON)) { + msr = rdmsr64(MSR_PLATFORM_INFO); + DBG("msr(0x%04x): platform_info %08x-%08x\n", MSR_PLATFORM_INFO, + (msr >> 32) & 0xffffffff, msr & 0xffffffff); + bus_ratio_max = (msr >> 8) & 0xff; + bus_ratio_min = (msr >> 40) & 0xff; //valv: not sure about this one (Remarq.1) + msr = rdmsr64(MSR_FLEX_RATIO); + DBG("msr(0x%04x): flex_ratio %08x\n", MSR_FLEX_RATIO, msr & 0xffffffff); + if ((msr >> 16) & 0x01) { + flex_ratio = (msr >> 8) & 0xff; + /* bcc9: at least on the gigabyte h67ma-ud2h, + where the cpu multipler can't be changed to + allow overclocking, the flex_ratio msr has unexpected (to OSX) + contents. These contents cause mach_kernel to + fail to compute the bus ratio correctly, instead + causing the system to crash since tscGranularity + is inadvertently set to 0. + */ + if (flex_ratio == 0) { + /* Clear bit 16 (evidently the + presence bit) */ + wrmsr64(MSR_FLEX_RATIO, (msr & 0xFFFFFFFFFFFEFFFFULL)); + msr = rdmsr64(MSR_FLEX_RATIO); + verbose("Unusable flex ratio detected. Patched MSR now %08x\n", msr & 0xffffffff); + } else { + if (bus_ratio_max > flex_ratio) { + bus_ratio_max = flex_ratio; + } + } + } + + if (bus_ratio_max) { + fsbFrequency = (tscFrequency / bus_ratio_max); + } + //valv: Turbo Ratio Limit + if ((intelCPU != 0x2e) && (intelCPU != 0x2f)) { + msr = rdmsr64(MSR_TURBO_RATIO_LIMIT); + cpuFrequency = bus_ratio_max * fsbFrequency; + max_ratio = bus_ratio_max * 10; + } else { + cpuFrequency = tscFrequency; + } + if ((getValueForKey(kbusratio, &newratio, &len, &bootInfo->chameleonConfig)) && (len <= 4)) { + max_ratio = atoi(newratio); + max_ratio = (max_ratio * 10); + if (len >= 3) max_ratio = (max_ratio + 5); + + verbose("Bus-Ratio: min=%d, max=%s\n", bus_ratio_min, newratio); + + // extreme overclockers may love 320 ;) + if ((max_ratio >= min_ratio) && (max_ratio <= 320)) { + cpuFrequency = (fsbFrequency * max_ratio) / 10; + if (len >= 3) maxdiv = 1; + else maxdiv = 0; + } else { + max_ratio = (bus_ratio_max * 10); + } + } + //valv: to be uncommented if Remarq.1 didn't stick + /*if(bus_ratio_max > 0) bus_ratio = flex_ratio;*/ + p->CPU.MaxRatio = max_ratio; + p->CPU.MinRatio = min_ratio; + + myfsb = fsbFrequency / 1000000; + verbose("Sticking with [BCLK: %dMhz, Bus-Ratio: %d]\n", myfsb, max_ratio); + currcoef = bus_ratio_max; + } else { + 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*/ + maxdiv = (msr >> 46) & 0x01; + /* Non-integer bus ratio for the current-multi (undocumented)*/ + currdiv = (msr >> 14) & 0x01; + + if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0e) || (p->CPU.Family == 0x0f)) // This will always be model >= 3 + { + /* On these models, maxcoef defines TSC freq */ + maxcoef = (msr >> 40) & 0x1f; + } else { + /* On lower models, currcoef defines TSC freq */ + /* XXX */ + maxcoef = currcoef; + } + + if (maxcoef) { + if (maxdiv) { + fsbFrequency = ((tscFrequency * 2) / ((maxcoef * 2) + 1)); + } else { + fsbFrequency = (tscFrequency / maxcoef); + } + if (currdiv) { + cpuFrequency = (fsbFrequency * ((currcoef * 2) + 1) / 2); + } else { + cpuFrequency = (fsbFrequency * currcoef); + } + DBG("max: %d%s current: %d%s\n", maxcoef, maxdiv ? ".5" : "",currcoef, currdiv ? ".5" : ""); + } + } + } + /* Mobile CPU ? */ +//Slice + msr = rdmsr64(MSR_IA32_PLATFORM_ID); + DBG("msr(0x%04x): MSR_IA32_PLATFORM_ID 0x%08x\n", MSR_IA32_PLATFORM_ID, msr & 0xffffffff); //__LINE__ - source line number :) + if (!scanDMI() && msr) { + p->CPU.Mobile = FALSE; + switch (p->CPU.Model) { + case 0x0D: + p->CPU.Mobile = TRUE; // CPU_FEATURE_MOBILE; + break; + case 0x0F: + p->CPU.Mobile = FALSE; // CPU_FEATURE_MOBILE; + break; + case 0x02: + case 0x03: + case 0x04: + case 0x06: + p->CPU.Mobile = (rdmsr64(MSR_P4_EBC_FREQUENCY_ID) && (1 << 21)); + break; + default: + p->CPU.Mobile = (rdmsr64(MSR_IA32_PLATFORM_ID) && (1<<28)); + break; + } + if (p->CPU.Mobile) { + p->CPU.Features |= CPU_FEATURE_MOBILE; + } + } + DBG("CPU is %s\n", p->CPU.Mobile?"Mobile":"Desktop"); + + } +#if 0 + else if((p->CPU.Vendor == 0x68747541 /* AMD */) && (p->CPU.Family == 0x0f)) { + if(p->CPU.ExtFamily == 0x00 /* K8 */) { + msr = rdmsr64(K8_FIDVID_STATUS); + currcoef = (msr & 0x3f) / 2 + 4; + currdiv = (msr & 0x01) * 2; + } else if(p->CPU.ExtFamily >= 0x01 /* K10+ */) { + msr = rdmsr64(K10_COFVID_STATUS); + if(p->CPU.ExtFamily == 0x01 /* K10 */) + currcoef = (msr & 0x3f) + 0x10; + else /* K11+ */ + currcoef = (msr & 0x3f) + 0x08; + currdiv = (2 << ((msr >> 6) & 0x07)); + } + + if (currcoef) { + if (currdiv) { + fsbFrequency = ((tscFrequency * currdiv) / currcoef); + DBG("%d.%d\n", currcoef / currdiv, ((currcoef % currdiv) * 100) / currdiv); + } else { + fsbFrequency = (tscFrequency / currcoef); + DBG("%d\n", currcoef); + } + fsbFrequency = (tscFrequency / currcoef); + cpuFrequency = tscFrequency; + } + } + + if (!fsbFrequency) { + fsbFrequency = (DEFAULT_FSB * 1000); + cpuFrequency = tscFrequency; + DBG("0 ! using the default value for FSB !\n"); + } +#endif + + p->CPU.MaxCoef = maxcoef; + p->CPU.MaxDiv = maxdiv; + p->CPU.CurrCoef = currcoef; + p->CPU.CurrDiv = currdiv; + p->CPU.TSCFrequency = tscFrequency; + p->CPU.FSBFrequency = fsbFrequency; + p->CPU.CPUFrequency = cpuFrequency; + DBG("CPU: Brand: %s\n", p->CPU.BrandString); + 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/Turbo: 0x%x/0x%x/0x%x\n", p->CPU.MaxCoef, p->CPU.CurrCoef, p->CPU.MaxCoef+1); + DBG("CPU: MaxDiv/CurrDiv: 0x%x/0x%x\n", p->CPU.MaxDiv?2:1, p->CPU.CurrDiv?2:1); + DBG("CPU: TSCFreq: %dMHz\n", p->CPU.TSCFrequency / 1000000); + DBG("CPU: FSBFreq: %dMHz\n", p->CPU.FSBFrequency / 1000000); + 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/slice/trunkM/i386/libsaio/platform.h =================================================================== --- branches/slice/trunkM/i386/libsaio/platform.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/platform.h (revision 1171) @@ -0,0 +1,172 @@ +/* + * platform.h + * AsereBLN: reworked and extended + * + */ + +#ifndef __LIBSAIO_PLATFORM_H +#define __LIBSAIO_PLATFORM_H + +#include "libsaio.h" + +extern bool platformCPUFeature(uint32_t); +extern void scan_platform(void); +extern void dumpPhysAddr(const char * title, void * a, int len); +extern void scan_cpu(); + +#define bit(n) (1UL << (n)) +#define bitmask(h,l) ((bit(h)|(bit(h)-1)) & ~(bit(l)-1)) +#define bitfield(x,h,l) (((x) & bitmask(h,l)) >> l) + + +/* CPUID index into cpuid_raw */ +#define CPUID_0 0 +#define CPUID_1 1 +#define CPUID_2 2 +#define CPUID_3 3 +#define CPUID_4 4 +#define CPUID_80 5 +#define CPUID_81 6 +#define CPUID_MAX 7 + +#define CPU_MODEL_PENTIUM_M 0x0D +#define CPU_MODEL_YONAH 0x0E // Sossaman, Yonah +#define CPU_MODEL_MEROM 0x0F // Allendale, Conroe, Kentsfield, Woodcrest, Clovertown, Tigerton, Merom +#define CPU_MODEL_PENRYN 0x17 // Wolfdale, Yorkfield, Harpertown, Penryn +#define CPU_MODEL_NEHALEM 0x1A // Bloomfield. Nehalem-EP, Nehalem-WS, Gainestown +#define CPU_MODEL_ATOM 0x1C // Atom +#define CPU_MODEL_FIELDS 0x1E // Lynnfield, Clarksfield, Jasper Forest +#define CPU_MODEL_DALES 0x1F // Havendale, Auburndale +#define CPU_MODEL_DALES_32NM 0x25 // Clarkdale, Arrandale +#define CPU_MODEL_SANDY 0x2A // Sandy Bridge +#define CPU_MODEL_WESTMERE 0x2C // Gulftown, Westmere-EP, Westmere-WS +#define CPU_MODEL_SANDY_XEON 0x2D // Sandy Bridge Xeon +#define CPU_MODEL_NEHALEM_EX 0x2E // Beckton +#define CPU_MODEL_WESTMERE_EX 0x2F + +/* CPU Features */ +#define CPU_FEATURE_MMX 0x00000001 // MMX Instruction Set +#define CPU_FEATURE_SSE 0x00000002 // SSE Instruction Set +#define CPU_FEATURE_SSE2 0x00000004 // SSE2 Instruction Set +#define CPU_FEATURE_SSE3 0x00000008 // SSE3 Instruction Set +#define CPU_FEATURE_SSE41 0x00000010 // SSE41 Instruction Set +#define CPU_FEATURE_SSE42 0x00000020 // SSE42 Instruction Set +#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 +//Slice - just use Platform->CPU.Mobile +#define MEGA 1000000LL + +/* SMBIOS Memory Types */ +#define SMB_MEM_TYPE_UNDEFINED 0 +#define SMB_MEM_TYPE_OTHER 1 +#define SMB_MEM_TYPE_UNKNOWN 2 +#define SMB_MEM_TYPE_DRAM 3 +#define SMB_MEM_TYPE_EDRAM 4 +#define SMB_MEM_TYPE_VRAM 5 +#define SMB_MEM_TYPE_SRAM 6 +#define SMB_MEM_TYPE_RAM 7 +#define SMB_MEM_TYPE_ROM 8 +#define SMB_MEM_TYPE_FLASH 9 +#define SMB_MEM_TYPE_EEPROM 10 +#define SMB_MEM_TYPE_FEPROM 11 +#define SMB_MEM_TYPE_EPROM 12 +#define SMB_MEM_TYPE_CDRAM 13 +#define SMB_MEM_TYPE_3DRAM 14 +#define SMB_MEM_TYPE_SDRAM 15 +#define SMB_MEM_TYPE_SGRAM 16 +#define SMB_MEM_TYPE_RDRAM 17 +#define SMB_MEM_TYPE_DDR 18 +#define SMB_MEM_TYPE_DDR2 19 +#define SMB_MEM_TYPE_FBDIMM 20 +#define SMB_MEM_TYPE_DDR3 24 // Supported in 10.5.6+ AppleSMBIOS + +/* Memory Configuration Types */ +#define SMB_MEM_CHANNEL_UNKNOWN 0 +#define SMB_MEM_CHANNEL_SINGLE 1 +#define SMB_MEM_CHANNEL_DUAL 2 +#define SMB_MEM_CHANNEL_TRIPLE 3 + +/* Maximum number of ram slots */ +#define MAX_RAM_SLOTS 8 +#define RAM_SLOT_ENUMERATOR {0, 2, 4, 1, 3, 5, 6, 8, 10, 7, 9, 11} + +/* Maximum number of SPD bytes */ +#define MAX_SPD_SIZE 256 + +/* Size of SMBIOS UUID in bytes */ +#define UUID_LEN 16 + +typedef struct _RamSlotInfo_t { + 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; +} RamSlotInfo_t; + +typedef struct _PlatformInfo_t { + struct PCI { + uint8_t NoDevices; // No of PCI devices + } PCI; + 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 + uint32_t ExtFamily; // Extended Family + uint32_t NoCores; // No Cores per Package + uint32_t NoThreads; // Threads per Package + uint8_t MaxCoef; // Max Multiplier + uint8_t MaxDiv; // Possible 0,5 + uint8_t MinCoef; // Min Multiplier + uint8_t CurrCoef; // Current Multiplier + uint8_t CurrDiv; + float MaxRatio; // non-integer ratio + float MinRatio; + float CurrRatio; + uint64_t TSCFrequency; // TSC Frequency Hz + uint64_t FSBFrequency; // FSB Frequency Hz + uint64_t CPUFrequency; // CPU Frequency Hz + bool Mobile; // Mobile CPU + char BrandString[48]; // 48 Byte Branding String + uint32_t CPUID[CPUID_MAX][4]; // CPUID 0..4, 80..81 Raw Values + } CPU; + + struct RAM { + 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 + char BrandString[48]; // Branding String Memory Controller + RamSlotInfo_t DIMM[MAX_RAM_SLOTS]; // Information about each slot + } RAM; + + struct DMI { + int MaxMemorySlots; // number of memory slots populated by SMBIOS + int CntMemorySlots; // number of memory slots counted + int MemoryModules; // number of memory modules installed + int DIMM[MAX_RAM_SLOTS]; // Information and SPD mapping for each slot + } DMI; + + uint8_t Type; // System Type: 1=Desktop, 2=Portable... according ACPI2.0 (FACP: PM_Profile) + uint8_t *UUID; +} PlatformInfo_t; + +extern PlatformInfo_t* Platform; + +#endif /* !__LIBSAIO_PLATFORM_H */ Index: branches/slice/trunkM/i386/libsaio/disk.c =================================================================== --- branches/slice/trunkM/i386/libsaio/disk.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/disk.c (revision 1171) @@ -0,0 +1,2024 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Mach Operating System + * Copyright (c) 1990 Carnegie-Mellon University + * Copyright (c) 1989 Carnegie-Mellon University + * All rights reserved. The CMU software License Agreement specifies + * the terms and conditions for use and redistribution. + */ + +/* + * INTEL CORPORATION PROPRIETARY INFORMATION + * + * This software is supplied under the terms of a license agreement or + * nondisclosure agreement with Intel Corporation and may not be copied + * nor disclosed except in accordance with the terms of that agreement. + * + * Copyright 1988, 1989 Intel Corporation + */ + +/* + * Copyright 1993 NeXT Computer, Inc. + * All rights reserved. + */ + +/* + * Copyright 2007 VMware Inc. + * "Preboot" ramdisk support added by David Elliott + * GPT support added by David Elliott. Based on IOGUIDPartitionScheme.cpp. + */ + +//Azi: style the rest later... + +// Allow UFS_SUPPORT to be overridden with preprocessor option. +#ifndef UFS_SUPPORT +// zef: Disabled UFS support +#define UFS_SUPPORT 0 +#endif + +#if UFS_SUPPORT +#include "ufs.h" +#endif +#include +#include +#include +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "memory.h" +#include "fdisk.h" +#include "hfs.h" +#include "ntfs.h" +#include "msdos.h" +#include "ext2fs.h" +#include "xml.h" +#include "disk.h" +// For EFI_GUID +#include "efi.h" +#include "efi_tables.h" + +typedef struct gpt_hdr gpt_hdr; +typedef struct gpt_ent gpt_ent; + +#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 */ +#define UFS_FRONT_PORCH 0 +#define kAPMSector 2 /* Sector number of Apple partition map */ +#define kAPMCDSector 8 /* Translated sector of Apple partition map on a CD */ + +/* + * IORound and IOTrunc convenience functions, in the spirit + * of vm's round_page() and trunc_page(). + */ +#define IORound(value,multiple) \ + ((((value) + (multiple) - 1) / (multiple)) * (multiple)) + +#define IOTrunc(value,multiple) \ + (((value) / (multiple)) * (multiple)); + +/* + * trackbuf points to the start of the track cache. Biosread() + * will store the sectors read from disk to this memory area. + * + * biosbuf points to a sector within the track cache, and is + * updated by Biosread(). + */ +static char * const trackbuf = (char *) ptov(BIOS_ADDR); +static char * biosbuf; + +/* + * Map a disk drive to bootable volumes contained within. + */ +struct DiskBVMap { + int biosdev; // BIOS device number (unique) + BVRef bvr; // chain of boot volumes on the disk + int bvrcnt; // number of boot volumes + struct DiskBVMap * next; // linkage to next mapping +}; + +static struct DiskBVMap * gDiskBVMap = NULL; +static struct disk_blk0 * gBootSector = NULL; + +// Function pointers to be filled in if ramdisks are available: +int (*p_ramdiskReadBytes)( int biosdev, unsigned int blkno, + unsigned int byteoff, + unsigned int byteCount, void * buffer ) = NULL; +int (*p_get_ramdisk_info)(int biosdev, struct driveInfo *dip) = NULL; + + +extern void spinActivityIndicator(int sectors); + +//========================================================================== + +static int getDriveInfo( int biosdev, struct driveInfo *dip ) +{ + static struct driveInfo cached_di; + int cc; + + // Real BIOS devices are 8-bit, so anything above that is for internal use. + // Don't cache ramdisk drive info since it doesn't require several BIOS + // calls and is thus not worth it. + if(biosdev >= 0x100) + { + if(p_get_ramdisk_info != NULL) + cc = (*p_get_ramdisk_info)(biosdev, dip); + else + cc = -1; + if(cc < 0) + { + dip->valid = 0; + return -1; + } + else + return 0; + } + + if ( !cached_di.valid || biosdev != cached_di.biosdev ) + { + cc = get_drive_info(biosdev, &cached_di); + if (cc < 0) { + cached_di.valid = 0; + DEBUG_DISK(("get_drive_info returned error\n")); + return (-1); // BIOS call error + } + } + + bcopy(&cached_di, dip, sizeof(cached_di)); + + return 0; +} + +//========================================================================== +// Maps (E)BIOS return codes to message strings. + +struct NamedValue { + unsigned char value; + const char * name; +}; + +static const char * getNameForValue( const struct NamedValue * nameTable, + unsigned char value ) +{ + const struct NamedValue * np; + + for ( np = nameTable; np->value; np++) + if (np->value == value) + return np->name; + + return NULL; +} + +#define ECC_CORRECTED_ERR 0x11 + +static const struct NamedValue bios_errors[] = { + { 0x10, "Media error" }, + { 0x11, "Corrected ECC error" }, + { 0x20, "Controller or device error" }, + { 0x40, "Seek failed" }, + { 0x80, "Device timeout" }, + { 0xAA, "Drive not ready" }, + { 0x00, 0 } +}; + +static const char * bios_error(int errnum) +{ + static char errorstr[] = "Error 0x00"; + const char * errname; + + errname = getNameForValue( bios_errors, errnum ); + if ( errname ) return errname; + + sprintf(errorstr, "Error 0x%02x", errnum); + return errorstr; // No string, print error code only +} + +//========================================================================== +// Use BIOS INT13 calls to read the sector specified. This function will +// also perform read-ahead to cache a few subsequent sector to the sector +// cache. +// +// Return: +// 0 on success, or an error code from INT13/F2 or INT13/F42 BIOS call. + +static bool cache_valid = false; + +static int Biosread( int biosdev, unsigned long long secno ) +{ + static int xbiosdev, xcyl, xhead; + static unsigned int xsec, xnsecs; + struct driveInfo di; + + int rc = -1; + int cyl, head, sec; + int tries = 0; + int bps, divisor; + + if (getDriveInfo(biosdev, &di) < 0) { + return -1; + } + if (di.no_emulation) { + /* Always assume 2k block size; BIOS may lie about geometry */ + bps = 2048; + } else { + bps = di.di.params.phys_nbps; + if (bps == 0) { + return -1; + } + } + divisor = bps / BPS; + + DEBUG_DISK(("Biosread dev %x sec %d bps %d\n", biosdev, secno, bps)); + + // To read the disk sectors, use EBIOS if we can. Otherwise, + // revert to the standard BIOS calls. + + if ((biosdev >= kBIOSDevTypeHardDrive) && + (di.uses_ebios & EBIOS_FIXED_DISK_ACCESS)) + { + if (cache_valid && + (biosdev == xbiosdev) && + (secno >= xsec) && + ((unsigned int)secno < (xsec + xnsecs))) + { + biosbuf = trackbuf + (BPS * (secno - xsec)); + return 0; + } + + xnsecs = N_CACHE_SECS; + xsec = (secno / divisor) * divisor; + cache_valid = false; + + while ((rc = ebiosread(biosdev, secno / divisor, xnsecs / divisor)) && (++tries < 5)) + { + if (rc == ECC_CORRECTED_ERR) { + /* Ignore corrected ECC errors */ + rc = 0; + break; + } + error(" EBIOS read error: %s\n", bios_error(rc), rc); + error(" Block 0x%x Sectors %d\n", secno, xnsecs); + sleep(1); + } + } + else + { + /* spc = spt * heads */ + int spc = (di.di.params.phys_spt * di.di.params.phys_heads); + cyl = secno / spc; + head = (secno % spc) / di.di.params.phys_spt; + sec = secno % di.di.params.phys_spt; + + if (cache_valid && + (biosdev == xbiosdev) && + (cyl == xcyl) && + (head == xhead) && + ((unsigned int)sec >= xsec) && + ((unsigned int)sec < (xsec + xnsecs))) + { + // this sector is in trackbuf cache + biosbuf = trackbuf + (BPS * (sec - xsec)); + return 0; + } + + // Cache up to a track worth of sectors, but do not cross a + // track boundary. + + xcyl = cyl; + xhead = head; + xsec = sec; + xnsecs = ((unsigned int)(sec + N_CACHE_SECS) > di.di.params.phys_spt) ? (di.di.params.phys_spt - sec) : N_CACHE_SECS; + cache_valid = false; + + while ((rc = biosread(biosdev, cyl, head, sec, xnsecs)) && + (++tries < 5)) + { + if (rc == ECC_CORRECTED_ERR) { + /* Ignore corrected ECC errors */ + rc = 0; + break; + } + error(" BIOS read error: %s\n", bios_error(rc), rc); + error(" Block %d, Cyl %d Head %d Sector %d\n", + secno, cyl, head, sec); + sleep(1); + } + } + + // If the BIOS reported success, mark the sector cache as valid. + + if (rc == 0) { + cache_valid = true; + } + biosbuf = trackbuf + (secno % divisor) * BPS; + xbiosdev = biosdev; + + spinActivityIndicator(xnsecs); + + return rc; +} + +//========================================================================== + +int testBiosread( int biosdev, unsigned long long secno ) +{ + return Biosread(biosdev, secno); +} + +//========================================================================== + +static int readBytes( int biosdev, unsigned long long blkno, + unsigned int byteoff, + unsigned int byteCount, void * buffer ) +{ + // ramdisks require completely different code for reading. + if(p_ramdiskReadBytes != NULL && biosdev >= 0x100) + return (*p_ramdiskReadBytes)(biosdev, blkno, byteoff, byteCount, buffer); + + char * cbuf = (char *) buffer; + int error; + int copy_len; + + DEBUG_DISK(("%s: dev %x block %x [%d] -> 0x%x...", __FUNCTION__, + biosdev, blkno, byteCount, (unsigned)cbuf)); + + for ( ; byteCount; cbuf += copy_len, blkno++ ) + { + error = Biosread( biosdev, blkno ); + if ( error ) + { + DEBUG_DISK(("error\n")); + return (-1); + } + + copy_len = ((byteCount + byteoff) > BPS) ? (BPS - byteoff) : byteCount; + bcopy( biosbuf + byteoff, cbuf, copy_len ); + byteCount -= copy_len; + byteoff = 0; + } + + DEBUG_DISK(("done\n")); + + return 0; +} + +//========================================================================== + +static int isExtendedFDiskPartition( const struct fdisk_part * part ) +{ + static unsigned char extParts[] = + { + 0x05, /* Extended */ + 0x0f, /* Win95 extended */ + 0x85, /* Linux extended */ + }; + + unsigned int i; + + for (i = 0; i < sizeof(extParts)/sizeof(extParts[0]); i++) + { + if (extParts[i] == part->systid) return 1; + } + return 0; +} + +//========================================================================== + +static int getNextFDiskPartition( int biosdev, int * partno, + const struct fdisk_part ** outPart ) +{ + static int sBiosdev = -1; + static int sNextPartNo; + static unsigned int sFirstBase; + static unsigned int sExtBase; + static unsigned int sExtDepth; + static struct fdisk_part * sExtPart; + struct fdisk_part * part; + + if ( sBiosdev != biosdev || *partno < 0 ) + { + // Fetch MBR. + if ( readBootSector( biosdev, DISK_BLK0, 0 ) ) return 0; + + sBiosdev = biosdev; + sNextPartNo = 0; + sFirstBase = 0; + sExtBase = 0; + sExtDepth = 0; + sExtPart = NULL; + } + + while (1) + { + part = NULL; + + if ( sNextPartNo < FDISK_NPART ) + { + part = (struct fdisk_part *) gBootSector->parts[sNextPartNo]; + } + else if ( sExtPart ) + { + unsigned int blkno = sExtPart->relsect + sFirstBase; + + // Save the block offset of the first extended partition. + + if (sExtDepth == 0) { + sFirstBase = blkno; + } + sExtBase = blkno; + + // Load extended partition table. + + if ( readBootSector( biosdev, blkno, 0 ) == 0 ) + { + sNextPartNo = 0; + sExtDepth++; + sExtPart = NULL; + continue; + } + // Fall through to part == NULL + } + + if ( part == NULL ) break; // Reached end of partition chain. + + // Advance to next partition number. + + sNextPartNo++; + + if ( isExtendedFDiskPartition(part) ) + { + sExtPart = part; + continue; + } + + // Skip empty slots. + + if ( part->systid == 0x00 ) + { + continue; + } + + // Change relative offset to an absolute offset. + part->relsect += sExtBase; + + *outPart = part; + *partno = sExtDepth ? (int)(sExtDepth + FDISK_NPART) : sNextPartNo; + + break; + } + + return (part != NULL); +} + +//========================================================================== + +static BVRef newFDiskBVRef( int biosdev, int partno, unsigned int blkoff, + const struct fdisk_part * part, + FSInit initFunc, FSLoadFile loadFunc, + FSReadFile readFunc, + FSGetDirEntry getdirFunc, + FSGetFileBlock getBlockFunc, + FSGetUUID getUUIDFunc, + BVGetDescription getDescriptionFunc, + BVFree bvFreeFunc, + int probe, int type, unsigned int bvrFlags ) +{ + BVRef bvr = (BVRef) malloc( sizeof(*bvr) ); + if ( bvr ) + { + bzero(bvr, sizeof(*bvr)); + + bvr->biosdev = biosdev; + bvr->part_no = partno; + bvr->part_boff = blkoff; + bvr->part_type = part->systid; + bvr->fs_loadfile = loadFunc; + bvr->fs_readfile = readFunc; + bvr->fs_getdirentry = getdirFunc; + bvr->fs_getfileblock= getBlockFunc; + bvr->fs_getuuid = getUUIDFunc; + bvr->description = getDescriptionFunc; + bvr->type = type; + bvr->bv_free = bvFreeFunc; + + if ((part->bootid & FDISK_ACTIVE) && (part->systid == FDISK_HFS)) + bvr->flags |= kBVFlagPrimary; + + // Probe the filesystem. + + if ( initFunc ) + { + bvr->flags |= kBVFlagNativeBoot; + + if ( probe && initFunc( bvr ) != 0 ) + { + // filesystem probe failed. + + DEBUG_DISK(("%s: failed probe on dev %x part %d\n", + __FUNCTION__, biosdev, partno)); + + (*bvr->bv_free)(bvr); + bvr = NULL; + } + if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 ) + { + bvr->flags |= kBVFlagBootable; + } + } + else if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 ) + { + bvr->flags |= kBVFlagForeignBoot; + } + else + { + (*bvr->bv_free)(bvr); + bvr = NULL; + } + } + if (bvr) bvr->flags |= bvrFlags; + return bvr; +} + +//========================================================================== + +BVRef newAPMBVRef( int biosdev, int partno, unsigned int blkoff, + const DPME * part, + FSInit initFunc, FSLoadFile loadFunc, + FSReadFile readFunc, + FSGetDirEntry getdirFunc, + FSGetFileBlock getBlockFunc, + FSGetUUID getUUIDFunc, + BVGetDescription getDescriptionFunc, + BVFree bvFreeFunc, + int probe, int type, unsigned int bvrFlags ) +{ + BVRef bvr = (BVRef) malloc( sizeof(*bvr) ); + if ( bvr ) + { + bzero(bvr, sizeof(*bvr)); + + bvr->biosdev = biosdev; + bvr->part_no = partno; + bvr->part_boff = blkoff; + bvr->fs_loadfile = loadFunc; + bvr->fs_readfile = readFunc; + bvr->fs_getdirentry = getdirFunc; + bvr->fs_getfileblock= getBlockFunc; + bvr->fs_getuuid = getUUIDFunc; + bvr->description = getDescriptionFunc; + bvr->type = type; + bvr->bv_free = bvFreeFunc; + strlcpy(bvr->name, part->dpme_name, DPISTRLEN); + strlcpy(bvr->type_name, part->dpme_type, DPISTRLEN); + + /* + if ( part->bootid & FDISK_ACTIVE ) + bvr->flags |= kBVFlagPrimary; + */ + + // Probe the filesystem. + + if ( initFunc ) + { + bvr->flags |= kBVFlagNativeBoot | kBVFlagBootable | kBVFlagSystemVolume; + + if ( probe && initFunc( bvr ) != 0 ) + { + // filesystem probe failed. + + DEBUG_DISK(("%s: failed probe on dev %x part %d\n", + __FUNCTION__, biosdev, partno)); + + (*bvr->bv_free)(bvr); + bvr = NULL; + } + } + /* + else if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 ) + { + bvr->flags |= kBVFlagForeignBoot; + } + */ + else + { + (*bvr->bv_free)(bvr); + bvr = NULL; + } + } + if (bvr) bvr->flags |= bvrFlags; + return bvr; +} + +//========================================================================== + +// GUID's in LE form: +// HFS+ partition - 48465300-0000-11AA-AA11-00306543ECAC +EFI_GUID const GPT_HFS_GUID = { 0x48465300, 0x0000, 0x11AA, { 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC } }; + +// turbo - Apple Boot Partition - 426F6F74-0000-11AA-AA11-00306543ECAC +EFI_GUID const GPT_BOOT_GUID = { 0x426F6F74, 0x0000, 0x11AA, { 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC } }; + +// turbo - or an EFI System Partition - C12A7328-F81F-11D2-BA4B-00A0C93EC93B +EFI_GUID const GPT_EFISYS_GUID = { 0xC12A7328, 0xF81F, 0x11D2, { 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B } }; + +// zef - Basic Data Partition - EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 for foreign OS support +EFI_GUID const GPT_BASICDATA_GUID = { 0xEBD0A0A2, 0xB9E5, 0x4433, { 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7 } }; + +// Microsoft Reserved Partition - E3C9E316-0B5C-4DB8-817DF92DF00215AE +EFI_GUID const GPT_BASICDATA2_GUID = { 0xE3C9E316, 0x0B5C, 0x4DB8, { 0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE } }; + + +BVRef newGPTBVRef( int biosdev, int partno, unsigned int blkoff, + const gpt_ent * part, + FSInit initFunc, FSLoadFile loadFunc, + FSReadFile readFunc, + FSGetDirEntry getdirFunc, + FSGetFileBlock getBlockFunc, + FSGetUUID getUUIDFunc, + BVGetDescription getDescriptionFunc, + BVFree bvFreeFunc, + int probe, int type, unsigned int bvrFlags ) +{ + BVRef bvr = (BVRef) malloc( sizeof(*bvr) ); + if ( bvr ) + { + bzero(bvr, sizeof(*bvr)); + + bvr->biosdev = biosdev; + bvr->part_no = partno; + bvr->part_boff = blkoff; + bvr->fs_loadfile = loadFunc; + bvr->fs_readfile = readFunc; + bvr->fs_getdirentry = getdirFunc; + bvr->fs_getfileblock= getBlockFunc; + bvr->fs_getuuid = getUUIDFunc; + bvr->description = getDescriptionFunc; + bvr->type = type; + bvr->bv_free = bvFreeFunc; + // FIXME: UCS-2 -> UTF-8 the name + strlcpy(bvr->name, "----", DPISTRLEN); + if ( (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const*)part->ent_type) == 0) || + (efi_guid_compare(&GPT_HFS_GUID, (EFI_GUID const*)part->ent_type) == 0) ) + strlcpy(bvr->type_name, "GPT HFS+", DPISTRLEN); + else + strlcpy(bvr->type_name, "GPT Unknown", DPISTRLEN); + + /* + if ( part->bootid & FDISK_ACTIVE ) + bvr->flags |= kBVFlagPrimary; + */ + + // Probe the filesystem. + + if ( initFunc ) + { + bvr->flags |= kBVFlagNativeBoot; + + if ( probe && initFunc( bvr ) != 0 ) + { + // filesystem probe failed. + + DEBUG_DISK(("%s: failed probe on dev %x part %d\n", + __FUNCTION__, biosdev, partno)); + + (*bvr->bv_free)(bvr); + bvr = NULL; + } + if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 ) + { + bvr->flags |= kBVFlagBootable; + } + } + else if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 ) + { + bvr->flags |= kBVFlagForeignBoot; + } + else + { + (*bvr->bv_free)(bvr); + bvr = NULL; + } + } + if (bvr) bvr->flags |= bvrFlags; + return bvr; +} + +//========================================================================== + +/* A note on partition numbers: + * IOKit makes the primary partitions numbers 1-4, and then + * extended partitions are numbered consecutively 5 and up. + * So, for example, if you have two primary partitions and + * one extended partition they will be numbered 1, 2, 5. + */ + +static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) +{ + const struct fdisk_part * part; + struct DiskBVMap * map; + int partno = -1; + BVRef bvr; +#if UFS_SUPPORT + BVRef booterUFS = NULL; +#endif + int spc; + struct driveInfo di; + boot_drive_info_t *dp; + + /* Initialize disk info */ + if (getDriveInfo(biosdev, &di) != 0) { + return NULL; + } + dp = &di.di; + spc = (dp->params.phys_spt * dp->params.phys_heads); + if (spc == 0) { + /* This is probably a CD-ROM; punt on the geometry. */ + spc = 1; + } + + do { + // Create a new mapping. + + map = (struct DiskBVMap *) malloc( sizeof(*map) ); + if ( map ) + { + map->biosdev = biosdev; + map->bvr = NULL; + map->bvrcnt = 0; + map->next = gDiskBVMap; + gDiskBVMap = map; + + // Create a record for each partition found on the disk. + + while ( getNextFDiskPartition( biosdev, &partno, &part ) ) + { + DEBUG_DISK(("%s: part %d [%x]\n", __FUNCTION__, + partno, part->systid)); + bvr = 0; + + switch ( part->systid ) + { +#if UFS_SUPPORT + case FDISK_UFS: + bvr = newFDiskBVRef( + biosdev, partno, + part->relsect + UFS_FRONT_PORCH/BPS, + part, + UFSInitPartition, + UFSLoadFile, + UFSReadFile, + UFSGetDirEntry, + UFSGetFileBlock, + UFSGetUUID, + UFSGetDescription, + UFSFree, + 0, + kBIOSDevTypeHardDrive, 0); + break; +#endif + + case FDISK_HFS: + bvr = newFDiskBVRef( + biosdev, partno, + part->relsect, + part, + HFSInitPartition, + HFSLoadFile, + HFSReadFile, + HFSGetDirEntry, + HFSGetFileBlock, + HFSGetUUID, + HFSGetDescription, + HFSFree, + 0, + kBIOSDevTypeHardDrive, 0); + break; + + // turbo - we want the booter type scanned also + case FDISK_BOOTER: + if (part->bootid & FDISK_ACTIVE) + gBIOSBootVolume = newFDiskBVRef( + biosdev, partno, + part->relsect, + part, + HFSInitPartition, + HFSLoadFile, + HFSReadFile, + HFSGetDirEntry, + HFSGetFileBlock, + HFSGetUUID, + HFSGetDescription, + HFSFree, + 0, + kBIOSDevTypeHardDrive, 0); + break; + +#if UFS_SUPPORT + case FDISK_BOOTER: + booterUFS = newFDiskBVRef( + biosdev, partno, + ((part->relsect + spc - 1) / spc) * spc, + part, + UFSInitPartition, + UFSLoadFile, + UFSReadFile, + UFSGetDirEntry, + UFSGetFileBlock, + UFSGetUUID, + UFSGetDescription, + UFSFree, + 0, + kBIOSDevTypeHardDrive, 0); + break; +#endif + + case FDISK_FAT32: + case FDISK_DOS12: + case FDISK_DOS16S: + case FDISK_DOS16B: + case FDISK_SMALLFAT32: + case FDISK_DOS16SLBA: + bvr = newFDiskBVRef( + biosdev, partno, + part->relsect, + part, + MSDOSInitPartition, + MSDOSLoadFile, + MSDOSReadFile, + MSDOSGetDirEntry, + MSDOSGetFileBlock, + MSDOSGetUUID, + MSDOSGetDescription, + MSDOSFree, + 0, + kBIOSDevTypeHardDrive, 0); + break; + + case FDISK_NTFS: + bvr = newFDiskBVRef( + biosdev, partno, + part->relsect, + part, + 0, 0, 0, 0, 0, + NTFSGetUUID, + NTFSGetDescription, + (BVFree)free, + 0, kBIOSDevTypeHardDrive, 0); + break; + + case FDISK_LINUX: + bvr = newFDiskBVRef( + biosdev, partno, + part->relsect, + part, + 0, 0, 0, 0, 0, 0, + EX2GetDescription, + (BVFree)free, + 0, kBIOSDevTypeHardDrive, 0); + break; + + default: + bvr = newFDiskBVRef( + biosdev, partno, + part->relsect, + part, + 0, 0, 0, 0, 0, 0, 0, + (BVFree)free, + 0, + kBIOSDevTypeHardDrive, 0); + break; + } + + if ( bvr ) + { + bvr->next = map->bvr; + map->bvr = bvr; + map->bvrcnt++; + } + } + +#if UFS_SUPPORT + // Booting from a CD with an UFS filesystem embedded + // in a booter partition. + + if ( booterUFS ) + { + if ( map->bvrcnt == 0 ) + { + map->bvr = booterUFS; + map->bvrcnt++; + } + else free( booterUFS ); + } +#endif + } + } while (0); + + /* + * If no FDisk partition, then we will check for + * an Apple partition map elsewhere. + */ +#if UNUSED + if (map->bvrcnt == 0) { + static struct fdisk_part cdpart; + cdpart.systid = 0xCD; + + /* Let's try assuming we are on a hybrid HFS/ISO9660 CD. */ + bvr = newFDiskBVRef( + biosdev, 0, + 0, + &cdpart, + HFSInitPartition, + HFSLoadFile, + HFSReadFile, + HFSGetDirEntry, + HFSGetFileBlock, + HFSGetUUID, + 0, + kBIOSDevTypeHardDrive); + bvr->next = map->bvr; + map->bvr = bvr; + map->bvrcnt++; + } +#endif + // Actually this should always be true given the above code + if(map == gDiskBVMap) + { + // Don't leave a null map in the chain + if(map->bvrcnt == 0 && map->bvr == NULL) + { + gDiskBVMap = map->next; + free(map); + map = NULL; + } + } + + if (countPtr) *countPtr = map ? map->bvrcnt : 0; + + return map ? map->bvr : NULL; +} + +//========================================================================== + +static BVRef diskScanAPMBootVolumes( int biosdev, int * countPtr ) +{ + struct DiskBVMap * map; + struct Block0 *block0_p; + unsigned int blksize; + unsigned int factor; + void *buffer = malloc(BPS); + + /* Check for alternate block size */ + if (readBytes( biosdev, 0, 0, BPS, buffer ) != 0) { + return NULL; + } + block0_p = buffer; + if (OSSwapBigToHostInt16(block0_p->sbSig) == BLOCK0_SIGNATURE) { + blksize = OSSwapBigToHostInt16(block0_p->sbBlkSize); + if (blksize != BPS) { + free(buffer); + buffer = malloc(blksize); + } + factor = blksize / BPS; + } else { + blksize = BPS; + factor = 1; + } + + do { + // Create a new mapping. + + map = (struct DiskBVMap *) malloc( sizeof(*map) ); + if ( map ) + { + int error; + DPME *dpme_p = (DPME *)buffer; + UInt32 i, npart = UINT_MAX; + BVRef bvr; + + map->biosdev = biosdev; + map->bvr = NULL; + map->bvrcnt = 0; + map->next = gDiskBVMap; + gDiskBVMap = map; + + for (i=0; idpme_signature) != DPME_SIGNATURE) { + break; + } + + if (i==0) { + npart = OSSwapBigToHostInt32(dpme_p->dpme_map_entries); + } + /* + printf("name = %s, %s%s %d -> %d [%d -> %d] {%d}\n", + dpme.dpme_name, dpme.dpme_type, (dpme.dpme_flags & DPME_FLAGS_BOOTABLE) ? "(bootable)" : "", + dpme.dpme_pblock_start, dpme.dpme_pblocks, + dpme.dpme_lblock_start, dpme.dpme_lblocks, + dpme.dpme_boot_block); + */ + + if (strcmp(dpme_p->dpme_type, "Apple_HFS") == 0) { + bvr = newAPMBVRef(biosdev, + i, + OSSwapBigToHostInt32(dpme_p->dpme_pblock_start) * factor, + dpme_p, + HFSInitPartition, + HFSLoadFile, + HFSReadFile, + HFSGetDirEntry, + HFSGetFileBlock, + HFSGetUUID, + HFSGetDescription, + HFSFree, + 0, + kBIOSDevTypeHardDrive, 0); + bvr->next = map->bvr; + map->bvr = bvr; + map->bvrcnt++; + } + } + } + } while (0); + + free(buffer); + + if (countPtr) *countPtr = map ? map->bvrcnt : 0; + + return map ? map->bvr : NULL; +} + +//========================================================================== + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/* + * Trying to figure out the filsystem type of a given partition. + */ +static int probeFileSystem(int biosdev, unsigned int blkoff) +{ + // detected filesystem type; + int result = -1; + int fatbits; + + // Allocating buffer for 4 sectors. + const void * probeBuffer = malloc(PROBEFS_SIZE); + if (probeBuffer == NULL) + goto exit; + + // Reading first 4 sectors of current partition + int error = readBytes(biosdev, blkoff, 0, PROBEFS_SIZE, (void *)probeBuffer); + if (error) + goto exit; + + if (HFSProbe(probeBuffer)) + result = FDISK_HFS; + else if (EX2Probe(probeBuffer)) + result = FDISK_LINUX; + else if (NTFSProbe(probeBuffer)) + result = FDISK_NTFS; + else if (fatbits=MSDOSProbe(probeBuffer)) + { + switch (fatbits) + { + case 32: + default: + result = FDISK_FAT32; + break; + case 16: + result = FDISK_DOS16B; + break; + case 12: + result = FDISK_DOS12; + break; + } + } + else + // Couldn't detect filesystem type + result = 0; + +exit: + if (probeBuffer != NULL) free((void *)probeBuffer); + return result; +} + +static bool isPartitionUsed(gpt_ent * partition) +{ + // + // Ask whether the given partition is used. + // + + return efi_guid_is_null((EFI_GUID const*)partition->ent_type) ? false : true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +static BVRef diskScanGPTBootVolumes( int biosdev, int * countPtr ) +{ + struct DiskBVMap * map = NULL; + void *buffer = malloc(BPS); + int error; + if ( error = readBytes( biosdev, /*secno*/0, 0, BPS, buffer ) != 0) { + verbose("Failed to read boot sector from BIOS device %02xh. Error=%d\n", biosdev, error); + goto scanErr; + } + struct REAL_disk_blk0 *fdiskMap = buffer; + if ( OSSwapLittleToHostInt16(fdiskMap->signature) != DISK_SIGNATURE ) + { + verbose("Failed to find boot signature on BIOS device %02xh\n", biosdev); + goto scanErr; + } + + int fdiskID = 0; + unsigned index; + for ( index = 0; index < FDISK_NPART; index++ ) + { + if ( fdiskMap->parts[index].systid ) + { + if ( fdiskMap->parts[index].systid == 0xEE ) + { + // Fail if two 0xEE partitions are present which + // means the FDISK code will wind up parsing it. + if ( fdiskID ) goto scanErr; + + fdiskID = index + 1; + } + } + } + + if ( fdiskID == 0 ) goto scanErr; + verbose("Attempting to read GPT\n"); + + if(readBytes(biosdev, 1, 0, BPS, buffer) != 0) + goto scanErr; + + gpt_hdr *headerMap = buffer; + + // Determine whether the partition header signature is present. + + if ( memcmp(headerMap->hdr_sig, GPT_HDR_SIG, strlen(GPT_HDR_SIG)) ) + { + goto scanErr; + } + + // Determine whether the partition header size is valid. + + UInt32 headerCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_self); + UInt32 headerSize = OSSwapLittleToHostInt32(headerMap->hdr_size); + + if ( headerSize < offsetof(gpt_hdr, padding) ) + { + goto scanErr; + } + + if ( headerSize > BPS ) + { + goto scanErr; + } + + // Determine whether the partition header checksum is valid. + + headerMap->hdr_crc_self = 0; + + if ( crc32(0, headerMap, headerSize) != headerCheck ) + { + goto scanErr; + } + + // Determine whether the partition entry size is valid. + + UInt64 gptBlock = 0; + UInt32 gptCheck = 0; + UInt32 gptCount = 0; + UInt32 gptID = 0; + gpt_ent * gptMap = 0; + UInt32 gptSize = 0; + + gptBlock = OSSwapLittleToHostInt64(headerMap->hdr_lba_table); + gptCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_table); + gptCount = OSSwapLittleToHostInt32(headerMap->hdr_entries); + gptSize = OSSwapLittleToHostInt32(headerMap->hdr_entsz); + + if ( gptSize < sizeof(gpt_ent) ) + { + goto scanErr; + } + + // Allocate a buffer large enough to hold one map, rounded to a media block. + free(buffer); + buffer = NULL; + + UInt32 bufferSize = IORound(gptCount * gptSize, BPS); + if(bufferSize == 0) + goto scanErr; + buffer = malloc(bufferSize); + + if(readBytes(biosdev, gptBlock, 0, bufferSize, buffer) != 0) + goto scanErr; + + verbose("Read GPT\n"); + + // Allocate a new map for this BIOS device and insert it into the chain + map = malloc(sizeof(*map)); + map->biosdev = biosdev; + map->bvr = NULL; + map->bvrcnt = 0; + map->next = gDiskBVMap; + gDiskBVMap = map; + + // fdisk like partition type id. + int fsType = 0; + + for(gptID = 1; gptID <= gptCount; ++gptID) + { + BVRef bvr = NULL; + unsigned int bvrFlags = 0; + + // size on disk can be larger than sizeof(gpt_ent) + gptMap = (gpt_ent *) ( buffer + ( (gptID - 1) * gptSize) ); + + // NOTE: EFI_GUID's are in LE and we know we're on an x86. + // The IOGUIDPartitionScheme.cpp code uses byte-based UUIDs, we don't. + + if (isPartitionUsed(gptMap)) + { + char stringuuid[100]; + efi_guid_unparse_upper((EFI_GUID*)gptMap->ent_type, stringuuid); + verbose("Reading GPT partition %d, type %s\n", gptID, stringuuid); + + // Getting fdisk like partition type. + fsType = probeFileSystem(biosdev, gptMap->ent_lba_start); + + if ( (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) || + (efi_guid_compare(&GPT_HFS_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) ) + { + bvrFlags = (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) ? kBVFlagBooter : 0; + bvr = newGPTBVRef(biosdev, + gptID, + gptMap->ent_lba_start, + gptMap, + HFSInitPartition, + HFSLoadFile, + HFSReadFile, + HFSGetDirEntry, + HFSGetFileBlock, + HFSGetUUID, + HFSGetDescription, + HFSFree, + 0, + kBIOSDevTypeHardDrive, bvrFlags); + } + + // zef - foreign OS support + if ( (efi_guid_compare(&GPT_BASICDATA_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) || + (efi_guid_compare(&GPT_BASICDATA2_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) ) + { + switch (fsType) + { + case FDISK_NTFS: + bvr = newGPTBVRef(biosdev, gptID, gptMap->ent_lba_start, gptMap, + 0, 0, 0, 0, 0, 0, NTFSGetDescription, + (BVFree)free, 0, kBIOSDevTypeHardDrive, 0); + break; + case FDISK_LINUX: + bvr = newGPTBVRef(biosdev, gptID, gptMap->ent_lba_start, gptMap, + 0, 0, 0, 0, 0, 0, EX2GetDescription, + (BVFree)free, 0, kBIOSDevTypeHardDrive, 0); + break; + + default: + bvr = newGPTBVRef(biosdev, gptID, gptMap->ent_lba_start, gptMap, + 0, 0, 0, 0, 0, 0, 0, + (BVFree)free, 0, kBIOSDevTypeHardDrive, 0); + break; + } + + } + + // turbo - save our booter partition + // zef - only on original boot device + if ( (efi_guid_compare(&GPT_EFISYS_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) ) + { + switch (fsType) + { + case FDISK_HFS: + if (readBootSector( biosdev, gptMap->ent_lba_start, (void *)0x7e00 ) == 0) + { + bvr = newGPTBVRef(biosdev, gptID, gptMap->ent_lba_start, gptMap, + HFSInitPartition, + HFSLoadFile, + HFSReadFile, + HFSGetDirEntry, + HFSGetFileBlock, + HFSGetUUID, + HFSGetDescription, + HFSFree, + 0, kBIOSDevTypeHardDrive, kBVFlagEFISystem); + } + break; + + case FDISK_FAT32: + if (testFAT32EFIBootSector( biosdev, gptMap->ent_lba_start, (void *)0x7e00 ) == 0) + { + bvr = newGPTBVRef(biosdev, gptID, gptMap->ent_lba_start, gptMap, + MSDOSInitPartition, + MSDOSLoadFile, + MSDOSReadFile, + MSDOSGetDirEntry, + MSDOSGetFileBlock, + MSDOSGetUUID, + MSDOSGetDescription, + MSDOSFree, + 0, kBIOSDevTypeHardDrive, kBVFlagEFISystem); + } + break; + + if (biosdev == gBIOSDev) + gBIOSBootVolume = bvr; + } + } + + if (bvr) + { + // Fixup bvr with the fake fdisk partition type. + if (fsType > 0) bvr->part_type = fsType; + + bvr->next = map->bvr; + map->bvr = bvr; + ++map->bvrcnt; + } + + } + } + +scanErr: + free(buffer); + + if(map) + { + if(countPtr) *countPtr = map->bvrcnt; + return map->bvr; + } + else + { + if(countPtr) *countPtr = 0; + return NULL; + } +} + +//========================================================================== + +static void scanFSLevelBVRSettings(BVRef chain) +{ + BVRef bvr; + char dirSpec[512], fileSpec[512]; + char label[BVSTRLEN]; + int ret; + long flags, time; + int fh, fileSize, error; + + for (bvr = chain; bvr; bvr = bvr->next) + { + ret = -1; + error = 0; + + // + // Check for alternate volume label on boot helper partitions. + // + if (bvr->flags & kBVFlagBooter) + { + sprintf(dirSpec, "hd(%d,%d)/System/Library/CoreServices/", BIOS_DEV_UNIT(bvr), bvr->part_no); + strcpy(fileSpec, ".disk_label.contentDetails"); + ret = GetFileInfo(dirSpec, fileSpec, &flags, &time); + if (!ret) + { + fh = open(strcat(dirSpec, fileSpec), 0); + fileSize = file_size(fh); + if (fileSize > 0 && fileSize < BVSTRLEN) + { + if (read(fh, label, fileSize) != fileSize) + error = -1; + } + else + error = -1; + + close(fh); + + if (!error) + { + label[fileSize] = '\0'; + strcpy(bvr->altlabel, label); + } + } + } + + // + // Check for SystemVersion.plist or ServerVersion.plist + // to determine if a volume hosts an installed system. + // + if (bvr->flags & kBVFlagNativeBoot) + { + sprintf(dirSpec, "hd(%d,%d)/System/Library/CoreServices/", BIOS_DEV_UNIT(bvr), bvr->part_no); + strcpy(fileSpec, "SystemVersion.plist"); + ret = GetFileInfo(dirSpec, fileSpec, &flags, &time); + + if (ret == -1) + { + strcpy(fileSpec, "ServerVersion.plist"); + ret = GetFileInfo(dirSpec, fileSpec, &flags, &time); + } + + if (!ret) + bvr->flags |= kBVFlagSystemVolume; + } + + } +} + +void rescanBIOSDevice(int biosdev) +{ + struct DiskBVMap *oldMap = diskResetBootVolumes(biosdev); + CacheReset(); + diskFreeMap(oldMap); + oldMap = NULL; + scanBootVolumes(biosdev, 0); +} + +struct DiskBVMap* diskResetBootVolumes(int biosdev) +{ + struct DiskBVMap * map; + struct DiskBVMap *prevMap = NULL; + for ( map = gDiskBVMap; map; prevMap = map, map = map->next ) { + if ( biosdev == map->biosdev ) { + break; + } + } + if(map != NULL) + { + verbose("Resetting BIOS device %xh\n", biosdev); + // Reset the biosbuf cache + cache_valid = false; + if(map == gDiskBVMap) + gDiskBVMap = map->next; + else if(prevMap != NULL) + prevMap->next = map->next; + else + stop(""); + } + // Return the old map, either to be freed, or reinserted later + return map; +} + +// Frees a DiskBVMap and all of its BootVolume's +void diskFreeMap(struct DiskBVMap *map) +{ + if(map != NULL) + { + while(map->bvr != NULL) + { + BVRef bvr = map->bvr; + map->bvr = bvr->next; + (*bvr->bv_free)(bvr); + } + free(map); + } +} + +BVRef diskScanBootVolumes( int biosdev, int * countPtr ) +{ + struct DiskBVMap * map = NULL; + BVRef bvr; + int count = 0; + + // Find an existing mapping for this device. + + for ( map = gDiskBVMap; map; map = map->next ) { + if ( biosdev == map->biosdev ) { + count = map->bvrcnt; + break; + } + } + + if (map == NULL) { + bvr = diskScanGPTBootVolumes(biosdev, &count); + if (bvr == NULL) { + bvr = diskScanFDiskBootVolumes(biosdev, &count); + } + if (bvr == NULL) { + bvr = diskScanAPMBootVolumes(biosdev, &count); + } + if (bvr) + { + scanFSLevelBVRSettings(bvr); + } + } else { + bvr = map->bvr; + } + if (countPtr) *countPtr += count; + return bvr; +} + +BVRef getBVChainForBIOSDev(int biosdev) +{ + BVRef chain = NULL; + struct DiskBVMap * map = NULL; + + for (map = gDiskBVMap; map; map = map->next) + { + if (map->biosdev == biosdev) + { + chain = map->bvr; + break; + } + } + + return chain; +} + +BVRef newFilteredBVChain(int minBIOSDev, int maxBIOSDev, unsigned int allowFlags, unsigned int denyFlags, int *count) +{ + BVRef chain = NULL; + BVRef bvr = NULL; + BVRef newBVR = NULL; + BVRef prevBVR = NULL; + + struct DiskBVMap * map = NULL; + int bvCount = 0; + + const char *raw = 0; + char* val = 0; + int len; + + getValueForKey(kHidePartition, &raw, &len, &bootInfo->chameleonConfig); + if(raw) + { + val = XMLDecode(raw); + } + + /* + * Traverse gDISKBVmap to get references for + * individual bvr chains of each drive. + */ + for (map = gDiskBVMap; map; map = map->next) + { + for (bvr = map->bvr; bvr; bvr = bvr->next) + { + /* + * Save the last bvr. + */ + if (newBVR) prevBVR = newBVR; + + /* + * Allocate and copy the matched bvr entry into a new one. + */ + newBVR = (BVRef) malloc(sizeof(*newBVR)); + bcopy(bvr, newBVR, sizeof(*newBVR)); + + /* + * Adjust the new bvr's fields. + */ + newBVR->next = NULL; + newBVR->filtered = true; + + if ( (!allowFlags || newBVR->flags & allowFlags) + && (!denyFlags || !(newBVR->flags & denyFlags) ) + && (newBVR->biosdev >= minBIOSDev && newBVR->biosdev <= maxBIOSDev) + ) + newBVR->visible = true; + + /* + * 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) ) + { + 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. + */ + if (!chain) + chain = newBVR; + + /* + * Update the previous bvr's link pointer to use the new memory area. + */ + if (prevBVR) + prevBVR->next = newBVR; + + if (newBVR->visible) + bvCount++; + } + } + +#if DEBUG //Azi: warning - too big for boot-log.. far too big.. i mean HUGE!! :P + for (bvr = chain; bvr; bvr = bvr->next) + { + printf(" bvr: %d, dev: %d, part: %d, flags: %d, vis: %d\n", bvr, bvr->biosdev, bvr->part_no, bvr->flags, bvr->visible); + } + printf("count: %d\n", bvCount); +// getchar(); +#endif + + *count = bvCount; + + free(val); + return chain; +} + +int freeFilteredBVChain(const BVRef chain) +{ + int ret = 1; + BVRef bvr = chain; + BVRef nextBVR = NULL; + + while (bvr) + { + nextBVR = bvr->next; + + if (bvr->filtered) + { + free(bvr); + } + else + { + ret = 0; + break; + } + + bvr = nextBVR; + } + + return ret; +} + +//========================================================================== + +static const struct NamedValue fdiskTypes[] = +{ + { FDISK_NTFS, "Windows NTFS" }, + { FDISK_DOS12, "Windows FAT12" }, + { FDISK_DOS16B, "Windows FAT16" }, + { FDISK_DOS16S, "Windows FAT16" }, + { FDISK_DOS16SLBA, "Windows FAT16" }, + { FDISK_SMALLFAT32, "Windows FAT32" }, + { FDISK_FAT32, "Windows FAT32" }, + { FDISK_LINUX, "Linux" }, + { FDISK_UFS, "Apple UFS" }, + { FDISK_HFS, "Apple HFS" }, + { FDISK_BOOTER, "Apple Boot/UFS" }, + { 0xCD, "CD-ROM" }, + { 0x00, 0 } /* must be last */ +}; + +//========================================================================== + +bool matchVolumeToString( BVRef bvr, const char* match, long matchLen) +{ + char testStr[128]; + + 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; +} + +/* 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" "alias"; etc... + */ + +bool getVolumeLabelAlias(BVRef bvr, char* str, long strMaxLen) +{ + char *aliasList, *entryStart, *entryNext; + + if ( !str || strMaxLen <= 0) + return false; + + aliasList = XMLDecode(getStringForKey(kRenamePartition, &bootInfo->chameleonConfig)); + 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 useDeviceDescription ) +{ + 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; + } + + /* 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 + } + + // + // Get the volume label using filesystem specific functions + // or use the alternate volume label if available. + // + if (*bvr->altlabel != '\0') + strncpy(p, bvr->altlabel, strMaxLen); + else if (bvr->description) + bvr->description(bvr, p, 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); + } + } + + // Set the devices label + sprintf(bvr->label, p); +} + +//========================================================================== +int readBootSector( int biosdev, unsigned int secno, void * buffer ) +{ + struct disk_blk0 * bootSector = (struct disk_blk0 *) buffer; + int error; + + if ( bootSector == NULL ) + { + if ( gBootSector == NULL ) + { + gBootSector = (struct disk_blk0 *) malloc(sizeof(*gBootSector)); + if ( gBootSector == NULL ) return -1; + } + bootSector = gBootSector; + } + + error = readBytes( biosdev, secno, 0, BPS, bootSector ); + if ( error || bootSector->signature != DISK_SIGNATURE ) + return -1; + + return 0; +} + +/* + * Format of boot1f32 block. + */ + +#define BOOT1F32_MAGIC "BOOT " +#define BOOT1F32_MAGICLEN 11 + +struct disk_boot1f32_blk { + unsigned char init[3]; + unsigned char fsheader[87]; + unsigned char magic[BOOT1F32_MAGICLEN]; + unsigned char bootcode[409]; + unsigned short signature; +}; + +int testFAT32EFIBootSector( int biosdev, unsigned int secno, void * buffer ) +{ + struct disk_boot1f32_blk * bootSector = (struct disk_boot1f32_blk *) buffer; + int error; + + if ( bootSector == NULL ) + { + if ( gBootSector == NULL ) + { + gBootSector = (struct disk_blk0 *) malloc(sizeof(*gBootSector)); + if ( gBootSector == NULL ) return -1; + } + bootSector = (struct disk_boot1f32_blk *) gBootSector; + } + + error = readBytes( biosdev, secno, 0, BPS, bootSector ); + if ( error || bootSector->signature != DISK_SIGNATURE + || strncmp((const char *)bootSector->magic, BOOT1F32_MAGIC, BOOT1F32_MAGICLEN) ) + return -1; + + return 0; +} + +//========================================================================== +// Handle seek request from filesystem modules. + +void diskSeek( BVRef bvr, long long position ) +{ + bvr->fs_boff = position / BPS; + bvr->fs_byteoff = position % BPS; +} + +//========================================================================== +// Handle read request from filesystem modules. + +int diskRead( BVRef bvr, long addr, long length ) +{ + return readBytes( bvr->biosdev, + bvr->fs_boff + bvr->part_boff, + bvr->fs_byteoff, + length, + (void *) addr ); +} + +int rawDiskRead( BVRef bvr, unsigned int secno, void *buffer, unsigned int len ) +{ + int secs; + unsigned char *cbuf = (unsigned char *)buffer; + unsigned int copy_len; + int rc; + + if ((len & (BPS-1)) != 0) { + error("raw disk read not sector aligned"); + return -1; + } + secno += bvr->part_boff; + + cache_valid = false; + + while (len > 0) { + secs = len / BPS; + if (secs > N_CACHE_SECS) secs = N_CACHE_SECS; + copy_len = secs * BPS; + + //printf("rdr: ebiosread(%d, %d, %d)\n", bvr->biosdev, secno, secs); + if ((rc = ebiosread(bvr->biosdev, secno, secs)) != 0) { + /* Ignore corrected ECC errors */ + if (rc != ECC_CORRECTED_ERR) { + error(" EBIOS read error: %s\n", bios_error(rc), rc); + error(" Block %d Sectors %d\n", secno, secs); + return rc; + } + } + bcopy( trackbuf, cbuf, copy_len ); + len -= copy_len; + cbuf += copy_len; + secno += secs; + spinActivityIndicator(secs); + } + + return 0; +} + +int rawDiskWrite( BVRef bvr, unsigned int secno, void *buffer, unsigned int len ) +{ + int secs; + unsigned char *cbuf = (unsigned char *)buffer; + unsigned int copy_len; + int rc; + + if ((len & (BPS-1)) != 0) { + error("raw disk write not sector aligned"); + return -1; + } + secno += bvr->part_boff; + + cache_valid = false; + + while (len > 0) { + secs = len / BPS; + if (secs > N_CACHE_SECS) secs = N_CACHE_SECS; + copy_len = secs * BPS; + + bcopy( cbuf, trackbuf, copy_len ); + //printf("rdr: ebioswrite(%d, %d, %d)\n", bvr->biosdev, secno, secs); + if ((rc = ebioswrite(bvr->biosdev, secno, secs)) != 0) { + error(" EBIOS write error: %s\n", bios_error(rc), rc); + error(" Block %d Sectors %d\n", secno, secs); + return rc; + } + len -= copy_len; + cbuf += copy_len; + secno += secs; + spinActivityIndicator(secs); + } + + return 0; +} + +int diskIsCDROM(BVRef bvr) +{ + struct driveInfo di; + + if (getDriveInfo(bvr->biosdev, &di) == 0 && di.no_emulation) { + return 1; + } + return 0; +} + +int biosDevIsCDROM(int biosdev) +{ + struct driveInfo di; + + if (getDriveInfo(biosdev, &di) == 0 && di.no_emulation) + { + return 1; + } + return 0; +} Index: branches/slice/trunkM/i386/libsaio/pci_setup.c =================================================================== --- branches/slice/trunkM/i386/libsaio/pci_setup.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/pci_setup.c (revision 1171) @@ -0,0 +1,86 @@ +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "pci.h" +#include "gma.h" +#include "nvidia.h" +#include "modules.h" + +#define DEBUG_PCI 0 + +#if DEBUG_PCI +#define DBG(x...) msglog(x) +#else +#define DBG(x...) +#endif + +extern bool setup_ati_devprop(pci_dt_t *ati_dev); +extern void set_eth_builtin(pci_dt_t *eth_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; + bool do_eth_devprop, do_gfx_devprop, do_enable_hpet; + pci_dt_t *current = pci_dt; + + do_eth_devprop = do_gfx_devprop = do_enable_hpet = false; + + getBoolForKey(kEthernetBuiltIn, &do_eth_devprop, &bootInfo->chameleonConfig); + getBoolForKey(kGraphicsEnabler, &do_gfx_devprop, &bootInfo->chameleonConfig); + getBoolForKey(kForceHPET, &do_enable_hpet, &bootInfo->chameleonConfig); + + while (current) + { + devicepath = get_pci_dev_path(current); + + switch (current->class_id) + { + case PCI_CLASS_BRIDGE_HOST: + if (current->dev.addr == PCIADDR(0, 0, 0)) + dram_controller_dev = current; + break; + + case PCI_CLASS_NETWORK_ETHERNET: + if (do_eth_devprop) + set_eth_builtin(current); + break; + + case PCI_CLASS_DISPLAY_VGA: + if (do_gfx_devprop) + switch (current->vendor_id) + { + case PCI_VENDOR_ID_ATI: + setup_ati_devprop(current); + break; + + case PCI_VENDOR_ID_INTEL: + setup_gma_devprop(current); + break; + + case PCI_VENDOR_ID_NVIDIA: + setup_nvidia_devprop(current); + break; + } + break; + + case PCI_CLASS_SERIAL_USB: + notify_usb_dev(current); + break; + + case PCI_CLASS_BRIDGE_ISA: + if (do_enable_hpet) + force_enable_hpet(current); + break; + } + + execute_hook("PCIDevice", current, NULL, NULL, NULL); + DBG("setup_pci_devs current devID=%08x\n", current->device_id); + setup_pci_devs(current->children); + DBG("setup_pci_devs children devID=%08x\n", current->device_id); + current = current->next; + } +} Index: branches/slice/trunkM/i386/libsaio/cpu.h =================================================================== --- branches/slice/trunkM/i386/libsaio/cpu.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/cpu.h (revision 1171) @@ -0,0 +1,167 @@ +/* + * Copyright 2008 Islam Ahmed Zaid. All rights reserved. + * AsereBLN: 2009: cleanup and bugfix + */ + +#ifndef __LIBSAIO_CPU_H +#define __LIBSAIO_CPU_H + +//#include "libsaio.h" + +extern void scan_cpu(PlatformInfo_t *); + +#ifndef bit +#define bit(n) (1ULL << (n)) +#define bitmask(h,l) ((bit(h)|(bit(h)-1)) & ~(bit(l)-1)) +#define bitfield(x,h,l) (((x) & bitmask(h,l)) >> l) +#endif + +#define CPU_STRING_UNKNOWN "Unknown CPU Type" + + + +#define MSR_IA32_PLATFORM_ID 0x0017 +#define MSR_P4_EBC_FREQUENCY_ID 0x002C +#define MSR_IA32_PERF_STATUS 0x0198 +#define MSR_IA32_PERF_CONTROL 0x0199 +#define MSR_IA32_EXT_CONFIG 0x00EE +#define MSR_FLEX_RATIO 0x0194 +#define MSR_TURBO_RATIO_LIMIT 0x01AD +#define MSR_PLATFORM_INFO 0x00CE +#define MSR_CORE_THREAD_COUNT 0x0035 // Undocumented + +#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: +#define CLKNUM 1193182 /* formerly 1193167 */ + +// DFE: These two constants come from Linux except CLOCK_TICK_RATE replaced with CLKNUM +#define CALIBRATE_TIME_MSEC 30 /* 30 msecs */ +#define CALIBRATE_LATCH ((CLKNUM * CALIBRATE_TIME_MSEC + 1000/2)/1000) + +// CPUID Values +#define CPUID_MODEL_YONAH 14 // Intel Mobile Core Solo, Duo +#define CPUID_MODEL_MEROM 15 // Intel Mobile Core 2 Solo, Duo, Xeon 30xx, Xeon 51xx, Xeon X53xx, Xeon E53xx, Xeon X32xx +#define CPUID_MODEL_PENRYN 23 // Intel Core 2 Solo, Duo, Quad, Extreme, Xeon X54xx, Xeon X33xx +#define CPUID_MODEL_NEHALEM 26 // Intel Core i7, Xeon W35xx, Xeon X55xx, Xeon E55xx LGA1366 (45nm) +#define CPUID_MODEL_ATOM 28 // Intel Atom (45nm) +#define CPUID_MODEL_FIELDS 30 // Intel Core i5, i7, Xeon X34xx LGA1156 (45nm) +#define CPUID_MODEL_DALES 31 // Havendale, Auburndale +#define CPUID_MODEL_DALES_32NM 37 // Intel Core i3, i5 LGA1156 (32nm) +#define CPUID_MODEL_SANDY 42 // Intel Core i3, i5, i7 LGA1155 (32nm) +#define CPUID_MODEL_WESTMERE 44 // Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core +#define CPUID_MODEL_NEHALEM_EX 46 // Intel Xeon X75xx, Xeon X65xx, Xeon E75xx, Xeon E65x +#define CPUID_MODEL_WESTMERE_EX 47 // Intel Xeon E7 + + +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/slice/trunkM/i386/libsaio/smbios.c =================================================================== --- branches/slice/trunkM/i386/libsaio/smbios.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/smbios.c (revision 1171) @@ -0,0 +1,864 @@ +/* + * SMBIOS Table Patcher, part of the Chameleon Boot Loader Project + * + * Copyright 2010 by Islam M. Ahmed Zaid. All rights reserved. + * + */ + + +#include "boot.h" +#include "bootstruct.h" +#include "smbios_getters.h" + +#ifndef DEBUG_SMBIOS +#define DEBUG_SMBIOS 0 +#endif + +#if DEBUG_SMBIOS +#define DBG(x...) printf(x) +#else +#define DBG(x...) msglog(x) +#endif + +#define SMBPlist &bootInfo->smbiosConfig +/* ASSUMPTION: 16KB should be enough for the whole thing */ +#define SMB_ALLOC_SIZE 16384 + + +//------------------------------------------------------------------------------------------------------------------------- +// SMBIOS Plist Keys +//------------------------------------------------------------------------------------------------------------------------- +/* BIOS Information */ +#define kSMBBIOSInformationVendorKey "SMbiosvendor" +#define kSMBBIOSInformationVersionKey "SMbiosversion" +#define kSMBBIOSInformationReleaseDateKey "SMbiosdate" + +/* System Information */ +#define kSMBSystemInformationManufacturerKey "SMmanufacturer" +#define kSMBSystemInformationProductNameKey "SMproductname" +#define kSMBSystemInformationVersionKey "SMsystemversion" +#define kSMBSystemInformationSerialNumberKey "SMserial" +#define kSMBSystemInformationFamilyKey "SMfamily" + +/* Base Board */ +#define kSMBBaseBoardManufacturerKey "SMboardmanufacturer" +#define kSMBBaseBoardProductKey "SMboardproduct" + +/* Processor Information */ +#define kSMBProcessorInformationExternalClockKey "SMexternalclock" +#define kSMBProcessorInformationMaximumClockKey "SMmaximalclock" + +/* Memory Device */ +#define kSMBMemoryDeviceDeviceLocatorKey "SMmemdevloc" +#define kSMBMemoryDeviceBankLocatorKey "SMmembankloc" +#define kSMBMemoryDeviceMemoryTypeKey "SMmemtype" +#define kSMBMemoryDeviceMemorySpeedKey "SMmemspeed" +#define kSMBMemoryDeviceManufacturerKey "SMmemmanufacturer" +#define kSMBMemoryDeviceSerialNumberKey "SMmemserial" +#define kSMBMemoryDevicePartNumberKey "SMmempart" + +/* Apple Specific */ +#define kSMBOemProcessorTypeKey "SMcputype" +#define kSMBOemProcessorBusSpeedKey "SMbusspeed" + +//------------------------------------------------------------------------------------------------------------------------- +// Default SMBIOS Data +//------------------------------------------------------------------------------------------------------------------------- +/* Rewrite: use a struct */ + +#define kDefaultVendorManufacturer "Apple Inc." +#define kDefaultBIOSReleaseDate "11/06/2009" +#define kDefaultSerialNumber "SOMESRLNMBR" +#define kDefaultBoardProduct "Mac-F4208DC8" +#define kDefaultSystemVersion "1.0" + +// defaults for a Mac mini +#define kDefaultMacminiFamily "Macmini" +#define kDefaultMacmini "Macmini1,1" +#define kDefaultMacminiBIOSVersion " MM21.88Z.009A.B00.0903051113" + +// defaults for a MacBook +#define kDefaultMacBookFamily "MacBook" +#define kDefaultMacBook "MacBook4,1" +#define kDefaultMacBookBIOSVersion " MB41.88Z.0073.B00.0903051113" + +// defaults for a MacBook Pro +#define kDefaultMacBookProFamily "MacBookPro" +#define kDefaultMacBookPro "MacBookPro4,1" +#define kDefaultMacBookProBIOSVersion " MBP41.88Z.0073.B00.0903051113" + +// defaults for an iMac +#define kDefaultiMacFamily "iMac" +#define kDefaultiMac "iMac8,1" +#define kDefaultiMacBIOSVersion " IM81.88Z.00C1.B00.0903051113" +// defaults for an iMac11,1 core i3/i5/i7 +#define kDefaultiMacNehalem "iMac11,1" +#define kDefaultiMacNehalemBIOSVersion " IM111.88Z.0034.B00.0903051113" +// defaults for an iMac12,1 +#define kDefaultiMacSandy "iMac12,1" +#define kDefaultiMacSandyBIOSVersion " IM121.88Z.0047.B00.1102091756" + +// defaults for a Mac Pro +#define kDefaultMacProFamily "MacPro" +#define kDefaultMacPro "MacPro3,1" +#define kDefaultMacProBIOSVersion " MP31.88Z.006C.B05.0903051113" +// defaults for a Mac Pro 4,1 core i7/Xeon +#define kDefaultMacProNehalem "MacPro4,1" +#define kDefaultMacProNehalemBIOSVersion " MP41.88Z.0081.B04.0903051113" +// defaults for a Mac Pro 5,1 core i7/Xeon +#define kDefaultMacProWestmere "MacPro5,1" +#define kDefaultMacProWestmereBIOSVersion " MP51.88Z.007F.B00.1008031144" +#define kDefaulMacProWestmereBIOSReleaseDate "08/03/10" +//------------------------------------------------------------------------------------------------------------------------- +#define MAX_DMI_TABLES 96 +typedef struct DmiNumAssocTag { + SMBStructHeader* dmi; + uint8_t type; +} DmiNumAssoc; + +static DmiNumAssoc DmiTablePair[MAX_DMI_TABLES]; +static int DmiTablePairCount = 0; +static int current_pos=0; +static bool ftTablePairInit = true; //use twice first run and after + +#define getFieldOffset(struct, field) ((uint8_t)(uint32_t)&(((struct *)0)->field)) + +typedef struct { + SMBStructHeader *orig; + SMBStructHeader *new; +} SMBStructPtrs; + +struct { + char *vendor; + char *version; + char *releaseDate; +} defaultBIOSInfo; + +struct { + char *manufacturer; + char *productName; + char *version; + char *serialNumber; + char *family; +} defaultSystemInfo; + +struct { + char *manufacturer; + char *product; +} defaultBaseBoard; + + +typedef struct { + uint8_t type; + SMBValueType valueType; + uint8_t fieldOffset; + char *keyString; + bool (*getSMBValue)(returnType *); + char **defaultValue; +} SMBValueSetter; + +SMBValueSetter SMBSetters[] = +{ + //------------------------------------------------------------------------------------------------------------------------- + // BIOSInformation + //------------------------------------------------------------------------------------------------------------------------- + {kSMBTypeBIOSInformation, kSMBString, getFieldOffset(SMBBIOSInformation, vendor), kSMBBIOSInformationVendorKey, + NULL, &defaultBIOSInfo.vendor }, + + {kSMBTypeBIOSInformation, kSMBString, getFieldOffset(SMBBIOSInformation, version), kSMBBIOSInformationVersionKey, + NULL, &defaultBIOSInfo.version }, + + {kSMBTypeBIOSInformation, kSMBString, getFieldOffset(SMBBIOSInformation, releaseDate), kSMBBIOSInformationReleaseDateKey, + NULL, &defaultBIOSInfo.releaseDate }, + + //------------------------------------------------------------------------------------------------------------------------- + // SystemInformation + //------------------------------------------------------------------------------------------------------------------------- + {kSMBTypeSystemInformation, kSMBString, getFieldOffset(SMBSystemInformation, manufacturer), kSMBSystemInformationManufacturerKey, + NULL, &defaultSystemInfo.manufacturer }, + + {kSMBTypeSystemInformation, kSMBString, getFieldOffset(SMBSystemInformation, productName), kSMBSystemInformationProductNameKey, + NULL, &defaultSystemInfo.productName }, + + {kSMBTypeSystemInformation, kSMBString, getFieldOffset(SMBSystemInformation, version), kSMBSystemInformationVersionKey, + NULL, &defaultSystemInfo.version }, + + {kSMBTypeSystemInformation, kSMBString, getFieldOffset(SMBSystemInformation, serialNumber), kSMBSystemInformationSerialNumberKey, + NULL, &defaultSystemInfo.serialNumber }, + + {kSMBTypeSystemInformation, kSMBString, getFieldOffset(SMBSystemInformation, skuNumber), NULL, + NULL, NULL }, + + {kSMBTypeSystemInformation, kSMBString, getFieldOffset(SMBSystemInformation, family), kSMBSystemInformationFamilyKey, + NULL, &defaultSystemInfo.family }, + + + //------------------------------------------------------------------------------------------------------------------------- + // BaseBoard + //------------------------------------------------------------------------------------------------------------------------- + {kSMBTypeBaseBoard, kSMBString, getFieldOffset(SMBBaseBoard, manufacturer), kSMBBaseBoardManufacturerKey, + NULL, &defaultBaseBoard.manufacturer }, + + {kSMBTypeBaseBoard, kSMBString, getFieldOffset(SMBBaseBoard, product), kSMBBaseBoardProductKey, + NULL, &defaultBaseBoard.product }, + + {kSMBTypeBaseBoard, kSMBString, getFieldOffset(SMBBaseBoard, version), NULL, NULL, NULL}, + + {kSMBTypeBaseBoard, kSMBString, getFieldOffset(SMBBaseBoard, serialNumber), NULL, NULL, NULL}, + + {kSMBTypeBaseBoard, kSMBString, getFieldOffset(SMBBaseBoard, assetTagNumber), NULL, NULL, NULL}, + + {kSMBTypeBaseBoard, kSMBString, getFieldOffset(SMBBaseBoard, locationInChassis), NULL, NULL, NULL}, + + + //------------------------------------------------------------------------------------------------------------------------- + // ProcessorInformation + //------------------------------------------------------------------------------------------------------------------------- + {kSMBTypeProcessorInformation, kSMBString, getFieldOffset(SMBProcessorInformation, socketDesignation), NULL, NULL, NULL}, + + {kSMBTypeProcessorInformation, kSMBString, getFieldOffset(SMBProcessorInformation, manufacturer), NULL, NULL, NULL}, + + {kSMBTypeProcessorInformation, kSMBString, getFieldOffset(SMBProcessorInformation, processorVersion), NULL, NULL, NULL}, + + {kSMBTypeProcessorInformation, kSMBWord, getFieldOffset(SMBProcessorInformation, externalClock), kSMBProcessorInformationExternalClockKey, + getProcessorInformationExternalClock, NULL}, + + {kSMBTypeProcessorInformation, kSMBWord, getFieldOffset(SMBProcessorInformation, maximumClock), kSMBProcessorInformationMaximumClockKey, + getProcessorInformationMaximumClock, NULL}, + + {kSMBTypeProcessorInformation, kSMBString, getFieldOffset(SMBProcessorInformation, serialNumber), NULL, NULL, NULL}, + + {kSMBTypeProcessorInformation, kSMBString, getFieldOffset(SMBProcessorInformation, assetTag), NULL, NULL, NULL}, + + {kSMBTypeProcessorInformation, kSMBString, getFieldOffset(SMBProcessorInformation, partNumber), NULL, NULL, NULL}, + + //------------------------------------------------------------------------------------------------------------------------- + // Memory Device + //------------------------------------------------------------------------------------------------------------------------- + {kSMBTypeMemoryDevice, kSMBString, getFieldOffset(SMBMemoryDevice, deviceLocator), kSMBMemoryDeviceDeviceLocatorKey, + NULL, NULL}, + + {kSMBTypeMemoryDevice, kSMBString, getFieldOffset(SMBMemoryDevice, bankLocator), kSMBMemoryDeviceBankLocatorKey, + NULL, NULL}, + + {kSMBTypeMemoryDevice, kSMBByte, getFieldOffset(SMBMemoryDevice, memoryType), kSMBMemoryDeviceMemoryTypeKey, + getSMBMemoryDeviceMemoryType, NULL}, + + {kSMBTypeMemoryDevice, kSMBWord, getFieldOffset(SMBMemoryDevice, memorySpeed), kSMBMemoryDeviceMemorySpeedKey, + getSMBMemoryDeviceMemorySpeed, NULL}, + + {kSMBTypeMemoryDevice, kSMBString, getFieldOffset(SMBMemoryDevice, manufacturer), kSMBMemoryDeviceManufacturerKey, + getSMBMemoryDeviceManufacturer, NULL}, + + {kSMBTypeMemoryDevice, kSMBString, getFieldOffset(SMBMemoryDevice, serialNumber), kSMBMemoryDeviceSerialNumberKey, + getSMBMemoryDeviceSerialNumber, NULL}, + + {kSMBTypeMemoryDevice, kSMBString, getFieldOffset(SMBMemoryDevice, assetTag), NULL, NULL, NULL}, + + {kSMBTypeMemoryDevice, kSMBString, getFieldOffset(SMBMemoryDevice, partNumber), kSMBMemoryDevicePartNumberKey, + getSMBMemoryDevicePartNumber, NULL}, + + + //------------------------------------------------------------------------------------------------------------------------- + // Apple Specific + //------------------------------------------------------------------------------------------------------------------------- + {kSMBTypeOemProcessorType, kSMBWord, getFieldOffset(SMBOemProcessorType, ProcessorType), kSMBOemProcessorTypeKey, + getSMBOemProcessorType, NULL}, + + {kSMBTypeOemProcessorBusSpeed, kSMBWord, getFieldOffset(SMBOemProcessorBusSpeed, ProcessorBusSpeed), kSMBOemProcessorBusSpeedKey, + getSMBOemProcessorBusSpeed, NULL} +}; + +int numOfSetters = sizeof(SMBSetters) / sizeof(SMBValueSetter); + + +SMBEntryPoint *origeps = 0; +SMBEntryPoint *neweps = 0; + +static uint8_t stringIndex; // increament when a string is added and set the field value accordingly +static uint8_t stringsSize; // add string size + +static SMBWord tableLength = 0; +static SMBWord handle = 0; +static SMBWord maxStructSize = 0; +static SMBWord structureCount = 0; + +/* Rewrite this function */ +void setDefaultSMBData(void) +{ + defaultBIOSInfo.vendor = kDefaultVendorManufacturer; + defaultBIOSInfo.releaseDate = kDefaultBIOSReleaseDate; + + defaultSystemInfo.manufacturer = kDefaultVendorManufacturer; + defaultSystemInfo.version = kDefaultSystemVersion; + defaultSystemInfo.serialNumber = kDefaultSerialNumber; + + defaultBaseBoard.manufacturer = kDefaultVendorManufacturer; + defaultBaseBoard.product = kDefaultBoardProduct; + + if (platformCPUFeature(CPU_FEATURE_MOBILE)) + { + if (Platform->CPU.NoCores > 1) + { + defaultBIOSInfo.version = kDefaultMacBookProBIOSVersion; + defaultSystemInfo.productName = kDefaultMacBookPro; + defaultSystemInfo.family = kDefaultMacBookProFamily; + } + else + { + defaultBIOSInfo.version = kDefaultMacBookBIOSVersion; + defaultSystemInfo.productName = kDefaultMacBook; + defaultSystemInfo.family = kDefaultMacBookFamily; + } + } + else + { + switch (Platform->CPU.NoCores) + { + case 1: + defaultBIOSInfo.version = kDefaultMacminiBIOSVersion; + defaultSystemInfo.productName = kDefaultMacmini; + defaultSystemInfo.family = kDefaultMacminiFamily; + break; + + case 2: + defaultBIOSInfo.version = kDefaultiMacBIOSVersion; + defaultSystemInfo.productName = kDefaultiMac; + defaultSystemInfo.family = kDefaultiMacFamily; + break; + default: + { + switch (Platform->CPU.Family) + { + case 0x06: + { + switch (Platform->CPU.Model) + { + case CPU_MODEL_FIELDS: // Intel Core i5, i7, Xeon X34xx LGA1156 (45nm) + case CPU_MODEL_DALES: + case CPU_MODEL_DALES_32NM: // Intel Core i3, i5 LGA1156 (32nm) + case 0x19: // ??? Intel Core i5 650 @3.20 GHz + defaultBIOSInfo.version = kDefaultiMacNehalemBIOSVersion; + defaultSystemInfo.productName = kDefaultiMacNehalem; + defaultSystemInfo.family = kDefaultiMacFamily; + break; + + case CPU_MODEL_SANDY: // Intel Core i3, i5, i7 LGA1155 (32nm) + case CPU_MODEL_SANDY_XEON: // Intel Xeon E3 + defaultBIOSInfo.version = kDefaultiMacSandyBIOSVersion; + defaultSystemInfo.productName = kDefaultiMacSandy; + defaultSystemInfo.family = kDefaultiMacFamily; + break; + case CPU_MODEL_NEHALEM: // Intel Core i7, Xeon W35xx, Xeon X55xx, Xeon E55xx LGA1366 (45nm) + case CPU_MODEL_NEHALEM_EX: // Intel Xeon X75xx, Xeon X65xx, Xeon E75xx, Xeon E65x + defaultBIOSInfo.version = kDefaultMacProNehalemBIOSVersion; + defaultSystemInfo.productName = kDefaultMacProNehalem; + defaultSystemInfo.family = kDefaultMacProFamily; + break; + + case CPU_MODEL_WESTMERE: // Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core + case CPU_MODEL_WESTMERE_EX: // Intel Xeon E7 + defaultBIOSInfo.version = kDefaultMacProWestmereBIOSVersion; + defaultBIOSInfo.releaseDate = kDefaulMacProWestmereBIOSReleaseDate; + defaultSystemInfo.productName = kDefaultMacProWestmere; + defaultSystemInfo.family = kDefaultMacProFamily; + break; + + default: + defaultBIOSInfo.version = kDefaultMacProBIOSVersion; + defaultSystemInfo.productName = kDefaultMacPro; + defaultSystemInfo.family = kDefaultMacProFamily; + break; + } + break; + } + default: + defaultBIOSInfo.version = kDefaultMacProBIOSVersion; + defaultSystemInfo.productName = kDefaultMacPro; + defaultSystemInfo.family = kDefaultMacProFamily; + break; + } + break; + } + } + } +} + +/* Used for SM*n smbios.plist keys */ +bool getSMBValueForKey(SMBStructHeader *structHeader, const char *keyString, const char **string, returnType *value) +{ + static int idx = -1; + static int current = -1; + int len; + char key[24]; + + if (current != structHeader->handle) + { + idx++; + current = structHeader->handle; + } + + sprintf(key, "%s%d", keyString, idx); + + if (value) + if (getIntForKey(key, (int *)&(value->dword), SMBPlist)) + return true; + else + if (getValueForKey(key, string, &len, SMBPlist)) + return true; + return false; +} + +char *getSMBStringForField(SMBStructHeader *structHeader, uint8_t field) +{ + uint8_t *stringPtr = (uint8_t *)structHeader + structHeader->length; + + if (!field) + return NULL; + + for (field--; field != 0 && strlen((char *)stringPtr) > 0; + field--, stringPtr = (uint8_t *)((uint32_t)stringPtr + strlen((char *)stringPtr) + 1)); + + return (char *)stringPtr; +} + +void setSMBStringForField(SMBStructHeader *structHeader, const char *string, uint8_t *field) +{ + int strSize; + + if (!field) + return; + if (!string) + { + *field = 0; + return; + } + + strSize = strlen(string); + + // remove any spaces found at the end + while ((strSize != 0) && (string[strSize - 1] == ' ')) + strSize--; + + if (strSize == 0) + { + *field = 0; + return; + } + + memcpy((uint8_t *)structHeader + structHeader->length + stringsSize, string, strSize); + *field = stringIndex; + + stringIndex++; + stringsSize += strSize + 1; +} + +bool setSMBValue(SMBStructPtrs *structPtr, int idx, returnType *value) +{ + const char *string = 0; + int len; + bool parsed; + int val; + + if (numOfSetters <= idx) + return false; + + switch (SMBSetters[idx].valueType) + { + case kSMBString: + if (SMBSetters[idx].keyString) + { + if (getValueForKey(SMBSetters[idx].keyString, &string, &len, SMBPlist)) + break; + else + if (structPtr->orig->type == kSMBTypeMemoryDevice) // MemoryDevice only + if (getSMBValueForKey(structPtr->orig, SMBSetters[idx].keyString, &string, NULL)) + break; + } + if (SMBSetters[idx].getSMBValue) + if (SMBSetters[idx].getSMBValue((returnType *)&string)) + break; + if ((SMBSetters[idx].defaultValue) && *(SMBSetters[idx].defaultValue)) + { + string = *(SMBSetters[idx].defaultValue); + break; + } + string = getSMBStringForField(structPtr->orig, *(uint8_t *)value); + break; + + case kSMBByte: + case kSMBWord: + case kSMBDWord: + //case kSMBQWord: + if (SMBSetters[idx].keyString) + { + parsed = getIntForKey(SMBSetters[idx].keyString, &val, SMBPlist); + if (!parsed) + if (structPtr->orig->type == kSMBTypeMemoryDevice) // MemoryDevice only + parsed = getSMBValueForKey(structPtr->orig, SMBSetters[idx].keyString, NULL, (returnType *)&val); + if (parsed) + { + switch (SMBSetters[idx].valueType) + { + case kSMBByte: + value->byte = (uint8_t)val; + break; + case kSMBWord: + value->word = (uint16_t)val; + break; + case kSMBDWord: + default: + value->dword = (uint32_t)val; + break; + } + return true; + } + } + + if (SMBSetters[idx].getSMBValue) + if (SMBSetters[idx].getSMBValue(value)) + return true; +#if 0 + if (*(SMBSetters[idx].defaultValue)) + { + value->dword = *(uint32_t *)(SMBSetters[idx].defaultValue); + return true; + } +#endif + break; + } + + if (SMBSetters[idx].valueType == kSMBString && string) + setSMBStringForField(structPtr->new, string, &value->byte); + + return true; +} + +//------------------------------------------------------------------------------------------------------------------------- +// Apple Specific +//------------------------------------------------------------------------------------------------------------------------- +void addSMBFirmwareVolume(SMBStructPtrs *structPtr) +{ + return; +} + +void addSMBMemorySPD(SMBStructPtrs *structPtr) +{ + /* SPD data from Platform->RAM.spd */ + return; +} + +void addSMBOemProcessorType(SMBStructPtrs *structPtr) +{ + SMBOemProcessorType *p = (SMBOemProcessorType *)structPtr->new; + + p->header.type = kSMBTypeOemProcessorType; + p->header.length = sizeof(SMBOemProcessorType); + p->header.handle = handle++; + + setSMBValue(structPtr, numOfSetters - 2 , (returnType *)&(p->ProcessorType)); + + structPtr->new = (SMBStructHeader *)((uint8_t *)structPtr->new + sizeof(SMBOemProcessorType) + 2); + tableLength += sizeof(SMBOemProcessorType) + 2; + structureCount++; +} + +void addSMBOemProcessorBusSpeed(SMBStructPtrs *structPtr) +{ + SMBOemProcessorBusSpeed *p = (SMBOemProcessorBusSpeed *)structPtr->new; + + switch (Platform->CPU.Family) + { + case 0x06: + { + switch (Platform->CPU.Model) + { + case 0x19: // ??? Intel Core i5 650 @3.20 GHz + case CPU_MODEL_FIELDS: // Intel Core i5, i7, Xeon X34xx LGA1156 (45nm) + case CPU_MODEL_DALES: + case CPU_MODEL_DALES_32NM: // Intel Core i3, i5 LGA1156 (32nm) + case CPU_MODEL_NEHALEM: // Intel Core i7, Xeon W35xx, Xeon X55xx, Xeon E55xx LGA1366 (45nm) + case CPU_MODEL_NEHALEM_EX: // Intel Xeon X75xx, Xeon X65xx, Xeon E75xx, Xeon E65x + case CPU_MODEL_WESTMERE: // Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core + case CPU_MODEL_WESTMERE_EX: // Intel Xeon E7 + break; + + default: + return; + } + } + } + + p->header.type = kSMBTypeOemProcessorBusSpeed; + p->header.length = sizeof(SMBOemProcessorBusSpeed); + p->header.handle = handle++; + + setSMBValue(structPtr, numOfSetters -1, (returnType *)&(p->ProcessorBusSpeed)); + + structPtr->new = (SMBStructHeader *)((uint8_t *)structPtr->new + sizeof(SMBOemProcessorBusSpeed) + 2); + tableLength += sizeof(SMBOemProcessorBusSpeed) + 2; + structureCount++; +} + +//------------------------------------------------------------------------------------------------------------------------- +// EndOfTable +//------------------------------------------------------------------------------------------------------------------------- +void addSMBEndOfTable(SMBStructPtrs *structPtr) +{ + structPtr->new->type = kSMBTypeEndOfTable; + structPtr->new->length = sizeof(SMBStructHeader); + structPtr->new->handle = handle++; + + structPtr->new = (SMBStructHeader *)((uint8_t *)structPtr->new + sizeof(SMBStructHeader) + 2); + tableLength += sizeof(SMBStructHeader) + 2; + structureCount++; +} + +void setSMBStruct(SMBStructPtrs *structPtr) +{ + bool setterFound = false; + + uint8_t *ptr; + SMBWord structSize; + int i; + + stringIndex = 1; + stringsSize = 0; + + if (handle < structPtr->orig->handle) + handle = structPtr->orig->handle; + + memcpy((void *)structPtr->new, structPtr->orig, structPtr->orig->length); + + for (i = 0; i < numOfSetters; i++) + if ((structPtr->orig->type == SMBSetters[i].type) && (SMBSetters[i].fieldOffset < structPtr->orig->length)) + { + setterFound = true; + setSMBValue(structPtr, i, (returnType *)((uint8_t *)structPtr->new + SMBSetters[i].fieldOffset)); + } + + if (setterFound) + { + ptr = (uint8_t *)structPtr->new + structPtr->orig->length; + for (; ((uint16_t *)ptr)[0] != 0; ptr++); + + if (((uint16_t *)ptr)[0] == 0) + ptr += 2; + + structSize = ptr - (uint8_t *)structPtr->new; + } + else + { + ptr = (uint8_t *)structPtr->orig + structPtr->orig->length; + for (; ((uint16_t *)ptr)[0] != 0; ptr++); + + if (((uint16_t *)ptr)[0] == 0) + ptr += 2; + + structSize = ptr - (uint8_t *)structPtr->orig; + memcpy((void *)structPtr->new, structPtr->orig, structSize); + } + + structPtr->new = (SMBStructHeader *)((uint8_t *)structPtr->new + structSize); + + tableLength += structSize; + + if (structSize > maxStructSize) + maxStructSize = structSize; + + structureCount++; +} + +void setupNewSMBIOSTable(SMBEntryPoint *eps, SMBStructPtrs *structPtr) +{ + uint8_t *ptr = (uint8_t *)eps->dmi.tableAddress; + structPtr->orig = (SMBStructHeader *)ptr; + + for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structPtr->orig + sizeof(SMBStructHeader)));) + { + switch (structPtr->orig->type) + { + /* Skip all Apple Specific Structures */ + case kSMBTypeFirmwareVolume: + case kSMBTypeMemorySPD: + case kSMBTypeOemProcessorType: + case kSMBTypeOemProcessorBusSpeed: + /* And this one too, to be added at the end */ + case kSMBTypeEndOfTable: + break; + + default: + /* Add */ + setSMBStruct(structPtr); + break; + } + + ptr = (uint8_t *)((uint32_t)structPtr->orig + structPtr->orig->length); + for (; ((uint16_t *)ptr)[0] != 0; ptr++); + + if (((uint16_t *)ptr)[0] == 0) + ptr += 2; + + structPtr->orig = (SMBStructHeader *)ptr; + } + + addSMBFirmwareVolume(structPtr); + addSMBMemorySPD(structPtr); + addSMBOemProcessorType(structPtr); + addSMBOemProcessorBusSpeed(structPtr); + + addSMBEndOfTable(structPtr); +} + +void setupSMBIOSTable(void) +{ + SMBStructPtrs *structPtr; + uint8_t *buffer; + bool setSMB = true; + + if (!origeps) + return; + + neweps = origeps; + + structPtr = (SMBStructPtrs *)malloc(sizeof(SMBStructPtrs)); + if (!structPtr) + return; + + buffer = malloc(SMB_ALLOC_SIZE); + if (!buffer) + return; + + bzero(buffer, SMB_ALLOC_SIZE); + structPtr->new = (SMBStructHeader *)buffer; + + getBoolForKey(kSMBIOSdefaults, &setSMB, &bootInfo->chameleonConfig); + if (setSMB) + setDefaultSMBData(); + + setupNewSMBIOSTable(origeps, structPtr); + + neweps = (SMBEntryPoint *)AllocateKernelMemory(sizeof(SMBEntryPoint)); + if (!neweps) + return; + bzero(neweps, sizeof(SMBEntryPoint)); + + neweps->anchor[0] = '_'; + neweps->anchor[1] = 'S'; + neweps->anchor[2] = 'M'; + neweps->anchor[3] = '_'; + neweps->entryPointLength = sizeof(SMBEntryPoint); + neweps->majorVersion = 2; + neweps->minorVersion = 4; + neweps->maxStructureSize = maxStructSize; + neweps->entryPointRevision = 0; + + neweps->dmi.anchor[0] = '_'; + neweps->dmi.anchor[1] = 'D'; + neweps->dmi.anchor[2] = 'M'; + neweps->dmi.anchor[3] = 'I'; + neweps->dmi.anchor[4] = '_'; + neweps->dmi.tableLength = tableLength; + neweps->dmi.tableAddress = AllocateKernelMemory(tableLength); + neweps->dmi.structureCount = structureCount; + neweps->dmi.bcdRevision = 0x24; + + if (!neweps->dmi.tableAddress) + return; + + memcpy((void *)neweps->dmi.tableAddress, buffer, tableLength); + + neweps->dmi.checksum = 0; + neweps->dmi.checksum = 0x100 - checksum8(&neweps->dmi, sizeof(DMIEntryPoint)); + + neweps->checksum = 0; + neweps->checksum = 0x100 - checksum8(neweps, sizeof(SMBEntryPoint)); + + free(buffer); + decodeSMBIOSTable(neweps); +} + +void *getSmbios(int which) +{ + switch (which) + { + case SMBIOS_ORIGINAL: + if (!origeps) + origeps = getAddressOfSmbiosTable(); + return origeps; + case SMBIOS_PATCHED: + return neweps; + } + + return 0; +} + +/** Find first original dmi Table with a particular type */ +SMBStructHeader* FindFirstDmiTableOfType(int type, int minlength) +{ + current_pos = 0; //static variable + + return FindNextDmiTableOfType(type, minlength); +}; + +/** Find next original dmi Table with a particular type */ +SMBStructHeader* FindNextDmiTableOfType(int type, int minlength) +{ + int i; + + if (ftTablePairInit) getSmbios(SMBIOS_ORIGINAL); + + for (i=current_pos; i < DmiTablePairCount; i++) { + if (type == DmiTablePair[i].type && + DmiTablePair[i].dmi && + DmiTablePair[i].dmi->length >= minlength ) { + current_pos = i+1; + return DmiTablePair[i].dmi; + } + } + return NULL; // not found +}; + + +/* Collect any information needed later */ +void readSMBIOSInfo(SMBEntryPoint *eps) +{ + uint8_t *structPtr = (uint8_t *)eps->dmi.tableAddress; + SMBStructHeader *structHeader = (SMBStructHeader *)structPtr; + + int dimmnbr = 0; + Platform->DMI.MaxMemorySlots = 0; + Platform->DMI.CntMemorySlots = 0; + Platform->DMI.MemoryModules = 0; + + for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));) + { + switch (structHeader->type) + { + case kSMBTypeSystemInformation: + Platform->UUID = ((SMBSystemInformation *)structHeader)->uuid; + break; + + case kSMBTypePhysicalMemoryArray: + Platform->DMI.MaxMemorySlots += ((SMBPhysicalMemoryArray *)structHeader)->numMemoryDevices; + break; + + case kSMBTypeMemoryDevice: + Platform->DMI.CntMemorySlots++; + if (((SMBMemoryDevice *)structHeader)->memorySize != 0) + Platform->DMI.MemoryModules++; + if (((SMBMemoryDevice *)structHeader)->memorySpeed > 0) + Platform->RAM.DIMM[dimmnbr].Frequency = ((SMBMemoryDevice *)structHeader)->memorySpeed; + dimmnbr++; + break; + } + + structPtr = (uint8_t *)((uint32_t)structHeader + structHeader->length); + for (; ((uint16_t *)structPtr)[0] != 0; structPtr++); + + if (((uint16_t *)structPtr)[0] == 0) + structPtr += 2; + + structHeader = (SMBStructHeader *)structPtr; + } +} Index: branches/slice/trunkM/i386/libsaio/disk.h =================================================================== --- branches/slice/trunkM/i386/libsaio/disk.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/disk.h (revision 1171) @@ -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 Index: branches/slice/trunkM/i386/libsaio/smbios_decode.c =================================================================== --- branches/slice/trunkM/i386/libsaio/smbios_decode.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/smbios_decode.c (revision 1171) @@ -0,0 +1,232 @@ +/* + * A very simple SMBIOS Table decoder, part of the Chameleon Boot Loader Project + * + * Copyright 2010 by Islam M. Ahmed Zaid. All rights reserved. + * + */ + +#include "libsaio.h" +#include "smbios.h" + +#ifndef DEBUG_SMBIOS +#define DEBUG_SMBIOS 0 +#endif + +#if DEBUG_SMBIOS +#define DBG(x...) printf(x) +#else +#define DBG(x...) msglog(x) +#endif + + +static SMBWord minorVersion; + +extern char *getSMBStringForField(SMBStructHeader *structHeader, uint8_t field); + +//------------------------------------------------------------------------------------------------------------------------- +// BIOSInformation +//------------------------------------------------------------------------------------------------------------------------- +void decodeBIOSInformation(SMBBIOSInformation *structHeader) +{ + DBG("BIOSInformation:\n"); + DBG("\tvendor: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->vendor)); + DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version)); + DBG("\treleaseDate: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->releaseDate)); + DBG("\n"); +} + +//------------------------------------------------------------------------------------------------------------------------- +// SystemInformation +//------------------------------------------------------------------------------------------------------------------------- +void decodeSystemInformation(SMBSystemInformation *structHeader) +{ + DBG("SystemInformation:\n"); + DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer)); + DBG("\tproductName: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->productName)); + DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version)); + DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber)); + + if (minorVersion < 1 || structHeader->header.length < 25) + return; + uint8_t *uuid = structHeader->uuid; + DBG("\tuuid: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02x%02X-%02X%02X%02X%02X%02X%02X\n", + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], + uuid[6], uuid[7], + uuid[8], uuid[9], + uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); + DBG("\twakeupReason: 0x%x\n", structHeader->wakeupReason); + + if (minorVersion < 4 || structHeader->header.length < 27) + return; + DBG("\tskuNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->skuNumber)); + DBG("\tfamily: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->family)); + DBG("\n"); +} + +//------------------------------------------------------------------------------------------------------------------------- +// BaseBoard +//------------------------------------------------------------------------------------------------------------------------- +void decodeBaseBoard(SMBBaseBoard *structHeader) +{ + DBG("BaseBoard:\n"); + DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer)); + DBG("\tproduct: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->product)); + DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version)); + DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber)); + DBG("\tassetTagNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTagNumber)); + DBG("\tlocationInChassis: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->locationInChassis)); + DBG("\tboardType: 0x%X\n", structHeader->boardType); + DBG("\n"); +} + +//------------------------------------------------------------------------------------------------------------------------- +// SystemEnclosure +//------------------------------------------------------------------------------------------------------------------------- +void decodeSystemEnclosure(SMBSystemEnclosure *structHeader) +{ + DBG("SystemEnclosure:\n"); + DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer)); + DBG("\ttype: %d\n", structHeader->type); + DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version)); + DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber)); + DBG("\tassetTagNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTagNumber)); + DBG("\n"); +} + +//------------------------------------------------------------------------------------------------------------------------- +// ProcessorInformation +//------------------------------------------------------------------------------------------------------------------------- +void decodeProcessorInformation(SMBProcessorInformation *structHeader) +{ + DBG("ProcessorInformation:\n"); + DBG("\tsocketDesignation: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->socketDesignation)); + DBG("\tprocessorType: %d\n", structHeader->processorType); + DBG("\tprocessorFamily: 0x%X\n", structHeader->processorFamily); + DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer)); + DBG("\tprocessorID: 0x%llX\n", structHeader->processorID); + DBG("\tprocessorVersion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->processorVersion)); + DBG("\texternalClock: %dMHz\n", structHeader->externalClock); + DBG("\tmaximumClock: %dMHz\n", structHeader->maximumClock); + DBG("\tcurrentClock: %dMHz\n", structHeader->currentClock); + + if (minorVersion < 3 || structHeader->header.length < 35) + return; + DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber)); + DBG("\tassetTag: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag)); + DBG("\tpartNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber)); + DBG("\n"); +} + +//------------------------------------------------------------------------------------------------------------------------- +// MemoryDevice +//------------------------------------------------------------------------------------------------------------------------- +void decodeMemoryDevice(SMBMemoryDevice *structHeader) +{ + DBG("MemoryDevice:\n"); + DBG("\tdeviceLocator: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->deviceLocator)); + DBG("\tbankLocator: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->bankLocator)); + DBG("\tmemoryType: %s\n", SMBMemoryDeviceTypes[structHeader->memoryType]); + + if (minorVersion < 3 || structHeader->header.length < 27) + return; + DBG("\tmemorySpeed: %dMHz\n", structHeader->memorySpeed); + DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer)); + DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber)); + DBG("\tassetTag: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag)); + DBG("\tpartNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber)); + DBG("\n"); +} + +//------------------------------------------------------------------------------------------------------------------------- +// Apple Specific +//------------------------------------------------------------------------------------------------------------------------- +void decodeOemProcessorType(SMBOemProcessorType *structHeader) +{ + DBG("AppleProcessorType:\n"); + DBG("\tProcessorType: 0x%x\n", ((SMBOemProcessorType *)structHeader)->ProcessorType); + DBG("\n"); +} + +void decodeOemProcessorBusSpeed(SMBOemProcessorBusSpeed *structHeader) +{ + DBG("AppleProcessorBusSpeed:\n"); + DBG("\tProcessorBusSpeed (QPI): %d.%dGT/s\n", + ((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 1000, + (((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 100) % 10); + DBG("\n"); +} +//------------------------------------------------------------------------------------------------------------------------- + + +void decodeSMBIOSTable(SMBEntryPoint *eps) +{ + uint8_t *ptr = (uint8_t *)eps->dmi.tableAddress; + SMBStructHeader *structHeader = (SMBStructHeader *)ptr; + + minorVersion = eps->minorVersion; + + DBG("\n"); + for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));) + { + DBG("Type: %d, Length: %d, Handle: 0x%x\n", + structHeader->type, structHeader->length, structHeader->handle); + + switch (structHeader->type) + { + case kSMBTypeBIOSInformation: + decodeBIOSInformation((SMBBIOSInformation *)structHeader); + break; + + case kSMBTypeSystemInformation: + decodeSystemInformation((SMBSystemInformation *)structHeader); + break; + + case kSMBTypeBaseBoard: + decodeBaseBoard((SMBBaseBoard *)structHeader); + break; + + case kSMBTypeSystemEnclosure: + decodeSystemEnclosure((SMBSystemEnclosure *)structHeader); + break; + + case kSMBTypeProcessorInformation: + decodeProcessorInformation((SMBProcessorInformation *)structHeader); + break; + + case kSMBTypeMemoryDevice: + decodeMemoryDevice((SMBMemoryDevice *)structHeader); + break; + + /* Skip all Apple Specific Structures */ + case kSMBTypeFirmwareVolume: + case kSMBTypeMemorySPD: + break; + + case kSMBTypeOemProcessorType: + decodeOemProcessorType((SMBOemProcessorType *)structHeader); + break; + + case kSMBTypeOemProcessorBusSpeed: + decodeOemProcessorBusSpeed((SMBOemProcessorBusSpeed *)structHeader); + break; + + case kSMBTypeEndOfTable: + /* Skip, to be added at the end */ + break; + + default: + break; + } + + ptr = (uint8_t *)((uint32_t)structHeader + structHeader->length); + for (; ((uint16_t *)ptr)[0] != 0; ptr++); + + if (((uint16_t *)ptr)[0] == 0) + ptr += 2; + + structHeader = (SMBStructHeader *)ptr; + } + DBG("\n"); +} + Index: branches/slice/trunkM/i386/libsaio/hpet.c =================================================================== --- branches/slice/trunkM/i386/libsaio/hpet.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/hpet.c (revision 1171) @@ -0,0 +1,103 @@ +/* + * + */ + +#include "libsaio.h" +#include "pci.h" +#include "hpet.h" + +#ifndef DEBUG_HPET +#define DEBUG_HPET 0 +#endif + +#if DEBUG_HPET +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif + +static struct lpc_controller_t lpc_controllers[] = { + + // Default unknown chipset + { 0, 0, "" }, + + // Intel + { 0x8086, 0x24dc, "ICH5" }, + { 0x8086, 0x2640, "ICH6" }, + { 0x8086, 0x2641, "ICH6M" }, + + { 0x8086, 0x27b0, "ICH7 DH" }, + { 0x8086, 0x27b8, "ICH7" }, + { 0x8086, 0x27b9, "ICH7M" }, + { 0x8086, 0x27bd, "ICH7M DH" }, + + { 0x8086, 0x2810, "ICH8R" }, + { 0x8086, 0x2811, "ICH8M-E" }, + { 0x8086, 0x2812, "ICH8DH" }, + { 0x8086, 0x2814, "ICH8DO" }, + { 0x8086, 0x2815, "ICH8M" }, + + { 0x8086, 0x2912, "ICH9DH" }, + { 0x8086, 0x2914, "ICH9DO" }, + { 0x8086, 0x2916, "ICH9R" }, + { 0x8086, 0x2917, "ICH9M-E" }, + { 0x8086, 0x2918, "ICH9" }, + { 0x8086, 0x2919, "ICH9M" }, + + { 0x8086, 0x3a14, "ICH10DO" }, + { 0x8086, 0x3a16, "ICH10R" }, + { 0x8086, 0x3a18, "ICH10" }, + { 0x8086, 0x3a1a, "ICH10D" }, + +}; + +void force_enable_hpet(pci_dt_t *lpc_dev) +{ + int i; + uint32_t val, hpet_address = 0xFED00000; + void *rcba; + + /* LPC on Intel ICH is always (?) at 00:1f.0 */ + for(i = 1; i < sizeof(lpc_controllers) / sizeof(lpc_controllers[0]); i++) + if ((lpc_controllers[i].vendor == lpc_dev->vendor_id) + && (lpc_controllers[i].device == lpc_dev->device_id)) + { + rcba = (void *)(pci_config_read32(lpc_dev->dev.addr, 0xF0) & 0xFFFFC000); + + DBG("Intel(R) %s LPC Interface [%04x:%04x], MMIO @ 0x%lx\n", + lpc_controllers[i].name, lpc_dev->vendor_id, lpc_dev->device_id, rcba); + + if (rcba == 0) + printf(" RCBA disabled; cannot force enable HPET\n"); + else + { + val = REG32(rcba, 0x3404); + if (val & 0x80) + { + // HPET is enabled in HPTC. Just not reported by BIOS + DBG(" HPET is enabled in HPTC, just not reported by BIOS\n"); + hpet_address |= (val & 3) << 12 ; + DBG(" HPET MMIO @ 0x%lx\n", hpet_address); + } + else + { + // HPET disabled in HPTC. Trying to enable + DBG(" HPET is disabled in HPTC, trying to enable\n"); + REG32(rcba, 0x3404) = val | 0x80; + hpet_address |= (val & 3) << 12 ; + DBG(" Force enabled HPET, MMIO @ 0x%lx\n", hpet_address); + } + + // verify if the job is done + val = REG32(rcba, 0x3404); + if (!(val & 0x80)) + printf(" Failed to force enable HPET\n"); + } + break; + } + +#if DEBUG_HPET + printf("Press [Enter] to continue...\n"); + getchar(); +#endif +} Index: branches/slice/trunkM/i386/libsaio/cache.c =================================================================== --- branches/slice/trunkM/i386/libsaio/cache.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/cache.c (revision 1171) @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 2.0 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * cache.c - A simple cache for file systems meta-data. + * + * Copyright (c) 2000 Apple Computer, Inc. + * + * DRI: Josh de Cesare + */ + +#include +// #include + +struct CacheEntry { + CICell ih; + long time; + long long offset; +}; +typedef struct CacheEntry CacheEntry; + +#define kCacheSize (0x100000) +#define kCacheMinBlockSize (0x200) +#define kCacheMaxBlockSize (0x8000) +#define kCacheMaxEntries (kCacheSize / kCacheMinBlockSize) + +static CICell gCacheIH; +static long gCacheBlockSize; +static long gCacheNumEntries; +static long gCacheTime; + +#ifdef __i386__ +static CacheEntry *gCacheEntries; +static char *gCacheBuffer; +#else +static CacheEntry gCacheEntries[kCacheMaxEntries]; +static char gCacheBuffer[kCacheSize]; +#endif + +#if CACHE_STATS +unsigned long gCacheHits; +unsigned long gCacheMisses; +unsigned long gCacheEvicts; +#endif + +void CacheReset() +{ + gCacheIH = NULL; +} + +void CacheInit( CICell ih, long blockSize ) +{ +#ifdef __i386__ + if ((ih == gCacheIH) && (blockSize == gCacheBlockSize)) + return; +#endif + + if ((blockSize < kCacheMinBlockSize) || + (blockSize > kCacheMaxBlockSize)) + return; + + gCacheBlockSize = blockSize; + gCacheNumEntries = kCacheSize / gCacheBlockSize; + gCacheTime = 0; + +#if CACHE_STATS + gCacheHits = 0; + gCacheMisses = 0; + gCacheEvicts = 0; +#endif + + gCacheIH = ih; + +#ifdef __i386__ + if (!gCacheBuffer) gCacheBuffer = (char *) malloc(kCacheSize); + if (!gCacheEntries) gCacheEntries = (CacheEntry *) malloc(kCacheMaxEntries * sizeof(CacheEntry)); + if ( !gCacheBuffer || !gCacheEntries ) + { + gCacheIH = 0; // invalidate cache + return; + } +#endif + + bzero(gCacheEntries, kCacheMaxEntries * sizeof(CacheEntry)); +} + +long CacheRead( CICell ih, char * buffer, long long offset, + long length, long cache ) +{ + long cnt, oldestEntry = 0, oldestTime, loadCache = 0; + CacheEntry *entry; + + // See if the data can be cached. + if (cache && (gCacheIH == ih) && (length == gCacheBlockSize)) { + // Look for the data in the cache. + for (cnt = 0; cnt < gCacheNumEntries; cnt++) { + entry = &gCacheEntries[cnt]; + if ((entry->ih == ih) && (entry->offset == offset)) { + entry->time = ++gCacheTime; + break; + } + } + + // If the data was found copy it to the caller. + if (cnt != gCacheNumEntries) { + bcopy(gCacheBuffer + cnt * gCacheBlockSize, buffer, gCacheBlockSize); +#if CACHE_STATS + gCacheHits++; +#endif + return gCacheBlockSize; + } + + // Could not find the data in the cache. + loadCache = 1; + } + + // Read the data from the disk. + Seek(ih, offset); + Read(ih, (long)buffer, length); +#if CACHE_STATS + if (cache) gCacheMisses++; +#endif + + // Put the data from the disk in the cache if needed. + if (loadCache) { + // Find a free entry. + oldestTime = gCacheTime; + for (cnt = 0; cnt < gCacheNumEntries; cnt++) { + entry = &gCacheEntries[cnt]; + + // Found a free entry. + if (entry->ih == 0) break; + + if (entry->time < oldestTime) { + oldestTime = entry->time; + oldestEntry = cnt; + } + } + + // If no free entry was found, use the oldest. + if (cnt == gCacheNumEntries) { + cnt = oldestEntry; +#if CACHE_STATS + gCacheEvicts++; +#endif + } + + // Copy the data from disk to the new entry. + entry = &gCacheEntries[cnt]; + entry->ih = ih; + entry->time = ++gCacheTime; + entry->offset = offset; + bcopy(buffer, gCacheBuffer + cnt * gCacheBlockSize, gCacheBlockSize); + } + + return length; +} Index: branches/slice/trunkM/i386/libsaio/hpet.h =================================================================== --- branches/slice/trunkM/i386/libsaio/hpet.h (revision 0) +++ branches/slice/trunkM/i386/libsaio/hpet.h (revision 1171) @@ -0,0 +1,20 @@ +/* + * + */ + +#ifndef __LIBSAIO_HPET_H +#define __LIBSAIO_HPET_H + +#include "libsaio.h" + +#define REG32(base, reg) ((volatile uint32_t *)base)[(reg) >> 2] + +void force_enable_hpet(pci_dt_t *lpc_dev); + +struct lpc_controller_t { + unsigned vendor; + unsigned device; + char *name; +}; + +#endif /* !__LIBSAIO_HPET_H */ Index: branches/slice/trunkM/i386/libsaio/pci.c =================================================================== --- branches/slice/trunkM/i386/libsaio/pci.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/pci.c (revision 1171) @@ -0,0 +1,199 @@ +/* + * + * Copyright 2008 by Islam M. Ahmed Zaid. All rights reserved. + * + */ + +#include "libsaio.h" +#include "bootstruct.h" +#include "boot.h" +#include "pci.h" +#include "pci_root.h" + +#ifndef DEBUG_PCI +#define DEBUG_PCI 0 +#endif + +#if DEBUG_PCI +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif + +pci_dt_t *root_pci_dev; + + +uint8_t pci_config_read8(uint32_t pci_addr, uint8_t reg) +{ + pci_addr |= reg & ~3; + outl(PCI_ADDR_REG, pci_addr); + return inb(PCI_DATA_REG + (reg & 3)); +} + +uint16_t pci_config_read16(uint32_t pci_addr, uint8_t reg) +{ + pci_addr |= reg & ~3; + outl(PCI_ADDR_REG, pci_addr); + return inw(PCI_DATA_REG + (reg & 2)); +} + +uint32_t pci_config_read32(uint32_t pci_addr, uint8_t reg) +{ + pci_addr |= reg & ~3; + outl(PCI_ADDR_REG, pci_addr); + return inl(PCI_DATA_REG); +} + +void pci_config_write8(uint32_t pci_addr, uint8_t reg, uint8_t data) +{ + pci_addr |= reg & ~3; + outl(PCI_ADDR_REG, pci_addr); + outb(PCI_DATA_REG + (reg & 3), data); +} + +void pci_config_write16(uint32_t pci_addr, uint8_t reg, uint16_t data) +{ + pci_addr |= reg & ~3; + outl(PCI_ADDR_REG, pci_addr); + outw(PCI_DATA_REG + (reg & 2), data); +} + +void pci_config_write32(uint32_t pci_addr, uint8_t reg, uint32_t data) +{ + pci_addr |= reg & ~3; + outl(PCI_ADDR_REG, pci_addr); + outl(PCI_DATA_REG, data); +} + +void scan_pci_bus(pci_dt_t *start, uint8_t bus) +{ + pci_dt_t *new; + pci_dt_t **current = &start->children; + uint32_t id; + uint32_t pci_addr; + uint8_t dev; + uint8_t func; + uint8_t secondary_bus; + uint8_t header_type; + + for (dev = 0; dev < 32; dev++) { + for (func = 0; func < 8; func++) { + pci_addr = PCIADDR(bus, dev, func); + id = pci_config_read32(pci_addr, PCI_VENDOR_ID); + if (!id || id == 0xffffffff) { + continue; + } + new = (pci_dt_t*)malloc(sizeof(pci_dt_t)); + if (!new) + return; + memset(new, 0, sizeof(pci_dt_t)); + + new->dev.addr = pci_addr; + new->vendor_id = id & 0xffff; + new->device_id = (id >> 16) & 0xffff; + new->subsys_id.subsys_id = pci_config_read32(pci_addr, PCI_SUBSYSTEM_VENDOR_ID); + new->subclass = pci_config_read8(pci_addr, PCI_CLASS_PROG); + new->class_id = pci_config_read16(pci_addr, PCI_CLASS_DEVICE); + new->parent = start; + + header_type = pci_config_read8(pci_addr, PCI_HEADER_TYPE); + switch (header_type & 0x7f) + { + case PCI_HEADER_TYPE_BRIDGE: + case PCI_HEADER_TYPE_CARDBUS: + secondary_bus = pci_config_read8(pci_addr, PCI_SECONDARY_BUS); + if (secondary_bus != 0) { + scan_pci_bus(new, secondary_bus); + } + break; + } + *current = new; + current = &new->next; + + if ((func == 0) && ((header_type & 0x80) == 0)) + { + break; + } + } + } +} + +void enable_pci_devs(void) +{ + uint16_t id; + uint32_t rcba, *fd; + + id = pci_config_read16(PCIADDR(0, 0x00, 0), 0x00); + /* make sure we're on Intel chipset */ + if (id != 0x8086) + return; + rcba = pci_config_read32(PCIADDR(0, 0x1f, 0), 0xf0) & ~1; + fd = (uint32_t *)(rcba + 0x3418); + /* set SMBus Disable (SD) to 0 */ + *fd &= ~0x8; + /* and all devices? */ + //*fd = 0x1; +} + + +void build_pci_dt(void) +{ + root_pci_dev = malloc(sizeof(pci_dt_t)); + + if (!root_pci_dev) + return; + gRootPCIDev = (void*)root_pci_dev; + bzero(root_pci_dev, sizeof(pci_dt_t)); + enable_pci_devs(); + scan_pci_bus(root_pci_dev, 0); +#if 1 //DEBUG_PCI + dump_pci_dt(root_pci_dev->children); + //pause(); +#endif +} + +static char dev_path[256]; +char *get_pci_dev_path(pci_dt_t *pci_dt) +{ + pci_dt_t *current; + pci_dt_t *end; + char tmp[64]; + + dev_path[0] = 0; + end = root_pci_dev; + + int uid = getPciRootUID(); + while (end != pci_dt) + { + current = pci_dt; + while (current->parent != end) + current = current->parent; + end = current; + if (current->parent == root_pci_dev) + { + sprintf(tmp, "PciRoot(0x%x)/Pci(0x%x,0x%x)", uid, + current->dev.bits.dev, current->dev.bits.func); + } else { + sprintf(tmp, "/Pci(0x%x,0x%x)", + current->dev.bits.dev, current->dev.bits.func); + } + strcat(dev_path, tmp); + } + return dev_path; +} + +void dump_pci_dt(pci_dt_t *pci_dt) +{ + pci_dt_t *current; + + current = pci_dt; + while (current) { + msglog("%02x:%02x.%x [%04x%02x] [%04x:%04x] (subsys [%04x:%04x]):: %s\n", + current->dev.bits.bus, current->dev.bits.dev, current->dev.bits.func, + current->class_id, current->subclass, current->vendor_id, current->device_id, + current->subsys_id.subsys.vendor_id, current->subsys_id.subsys.device_id, + get_pci_dev_path(current)); + dump_pci_dt(current->children); + current = current->next; + } +} Index: branches/slice/trunkM/i386/libsaio/stringTable.c =================================================================== --- branches/slice/trunkM/i386/libsaio/stringTable.c (revision 0) +++ branches/slice/trunkM/i386/libsaio/stringTable.c (revision 1171) @@ -0,0 +1,779 @@ +/* + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright 1993 NeXT, Inc. + * All rights reserved. + */ + +#include "bootstruct.h" +#include "libsaio.h" +#include "boot.h" +#include "xml.h" + +extern char *Language; +extern char *LoadableFamilies; + +bool sysConfigValid; + +/* + * Compare a string to a key with quoted characters + */ +static inline int +keyncmp(const char *str, const char *key, int n) +{ + int c; + while (n--) { + c = *key++; + if (c == '\\') { + switch(c = *key++) { + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + default: + break; + } + } else if (c == '\"') { + /* Premature end of key */ + return 1; + } + if (c != *str++) { + return 1; + } + } + return 0; +} + +#if UNUSED + +static void eatThru(char val, const char **table_p) +{ + register const char *table = *table_p; + register bool found = false; + + while (*table && !found) + { + if (*table == '\\') table += 2; + else + { + if (*table == val) found = true; + table++; + } + } + *table_p = table; +} + +/* Remove key and its associated value from the table. */ + +bool +removeKeyFromTable(const char *key, char *table) +{ + register int len; + register char *tab; + char *buf; + + len = strlen(key); + tab = (char *)table; + buf = (char *)malloc(len + 3); + + sprintf(buf, "\"%s\"", key); + len = strlen(buf); + + while(*tab) { + if(strncmp(buf, tab, len) == 0) { + char c; + + while((c = *(tab + len)) != ';') { + if(c == 0) { + len = -1; + goto out; + } + len++; + } + len++; + if(*(tab + len) == '\n') len++; + goto out; + } + tab++; + } + len = -1; +out: + free(buf); + + if(len == -1) return false; + + while((*tab = *(tab + len))) { + tab++; + } + + return true; +} + +char * +newStringFromList( + char **list, + int *size +) +{ + char *begin = *list, *end; + char *newstr; + int newsize = *size; + int bufsize; + + while (*begin && newsize && isspace(*begin)) { + begin++; + newsize--; + } + end = begin; + while (*end && newsize && !isspace(*end)) { + end++; + newsize--; + } + if (begin == end) + return 0; + bufsize = end - begin + 1; + newstr = malloc(bufsize); + strlcpy(newstr, begin, bufsize); + *list = end; + *size = newsize; + return newstr; +} + +#endif + +/* + * compress == compress escaped characters to one character + */ +int stringLength(const char *table, int compress) +{ + int ret = 0; + + while (*table) + { + if (*table == '\\') + { + table += 2; + ret += 1 + (compress ? 0 : 1); + } + else + { + if (*table == '\"') return ret; + ret++; + table++; + } + } + return ret; +} + + +bool getValueForConfigTableKey(config_file_t *config, const char *key, const char **val, int *size) +{ + if (config->dictionary != 0 ) { + // Look up key in XML dictionary + TagPtr value; + value = XMLGetProperty(config->dictionary, key); + if (value != 0) { + if (value->type != kTagTypeString) { + error("Non-string tag '%s' found in config file\n", + key); + return false; + } + *val = value->string; + *size = strlen(value->string); + return true; + } + } else { + + // Legacy plist-style table + + } + + return false; +} + +#if UNUSED + +/* + * Returns a new malloc'ed string if one is found + * in the string table matching 'key'. Also translates + * \n escapes in the string. + */ +char *newStringForStringTableKey( + char *table, + char *key, + config_file_t *config +) +{ + const char *val; + char *newstr, *p; + int size; + + if (getValueForConfigTableKey(config, key, &val, &size)) { + newstr = (char *)malloc(size+1); + for (p = newstr; size; size--, p++, val++) { + if ((*p = *val) == '\\') { + switch (*++val) { + case 'r': + *p = '\r'; + break; + case 'n': + *p = '\n'; + break; + case 't': + *p = '\t'; + break; + default: + *p = *val; + break; + } + size--; + } + } + *p = '\0'; + return newstr; + } else { + return 0; + } +} + +#endif + +char * +newStringForKey(char *key, config_file_t *config) +{ + const char *val; + char *newstr; + int size; + + if (getValueForKey(key, &val, &size, config) && size) { + newstr = (char *)malloc(size + 1); + strlcpy(newstr, val, size + 1); + return newstr; + } else { + return 0; + } +} + +/* parse a command line + * in the form: [ ...] [