Index: branches/slice/old749m/coding_standards.txt =================================================================== --- branches/slice/old749m/coding_standards.txt (revision 0) +++ branches/slice/old749m/coding_standards.txt (revision 1174) @@ -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/old749m/version =================================================================== --- branches/slice/old749m/version (revision 0) +++ branches/slice/old749m/version (revision 1174) @@ -0,0 +1 @@ +2.5-RC5m \ No newline at end of file Index: branches/slice/old749m/CreditsToMeklort.rtf =================================================================== --- branches/slice/old749m/CreditsToMeklort.rtf (revision 0) +++ branches/slice/old749m/CreditsToMeklort.rtf (revision 1174) @@ -0,0 +1,7 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\paperw11900\paperh16840\margl1440\margr1440\vieww9000\viewh8400\viewkind0 +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 I do not want to compete with Meklort. I just want to propose my numerous changes.} \ No newline at end of file Index: branches/slice/old749m/artwork/themes/default/text_scroll_prev.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/text_scroll_prev.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_hfsraid.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_hfsraid.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/logo.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/logo.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_ext3.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_ext3.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/menu_single_user.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/menu_single_user.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/boot.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/boot.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_fat_o.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_fat_o.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_ntfs_o.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_ntfs_o.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_scroll_prev.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_scroll_prev.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/menu_ignore_caches.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/menu_ignore_caches.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/menu_verbose_disabled.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/menu_verbose_disabled.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_hfsplus_o.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_hfsplus_o.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/menu_boot.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/menu_boot.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/font_console.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/font_console.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_fat.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_fat.png ___________________________________________________________________ Added: svn:executable + * Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_ntfs.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_ntfs.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/menu_single_user_disabled.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/menu_single_user_disabled.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/font_small.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/font_small.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/text_scroll_next.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/text_scroll_next.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_cdrom_o.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_cdrom_o.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_hfsplus.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_hfsplus.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_selection.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_selection.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/menu_ignore_caches_disabled.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/menu_ignore_caches_disabled.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/menu_video_info.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/menu_video_info.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/menu_memory_info.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/menu_memory_info.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/theme.plist =================================================================== --- branches/slice/old749m/artwork/themes/default/theme.plist (revision 0) +++ branches/slice/old749m/artwork/themes/default/theme.plist (revision 1174) @@ -0,0 +1,121 @@ + + + + + Author + Blackosx + Version + 1.0 + + Enabled + no + + screen_width + 1024 + screen_height + 768 + screen_textmargin_h + 10 + screen_textmargin_v + 10 + screen_bgcolor + #767f73 + + background_pos_x + 50% + background_pos_y + 0 + + logo_pos_x + + logo_pos_y + 5% + logo_bgcolor + #000000 + logo_transparency + 255 + + devices_pos_x + + devices_pos_y + + devices_bgcolor + #767f73 + devices_transparency + 0 + devices_max_visible + 4 + devices_iconspacing + 45 + devices_layout + horizontal + + bootprompt_pos_x + + bootprompt_pos_y + -6 + bootprompt_width + 40% + bootprompt_height + 20 + bootprompt_textmargin_h + 10 + bootprompt_textmargin_v + 5 + bootprompt_bgcolor + #3e3e3e + bootprompt_transparency + 1 + + infobox_pos_x + + infobox_pos_y + 30% + infobox_width + 660 + infobox_height + 320 + infobox_textmargin_h + 10 + infobox_textmargin_v + 10 + infobox_bgcolor + #3e3e3e + infobox_transparency + 35 + + menu_pos_x + + menu_pos_y + -5% + menu_textmargin_h + 10 + menu_textmargin_v + 5 + menu_bgcolor + #3e3e3e + menu_transparency + 1 + + progressbar_pos_x + + progressbar_pos_y + -30% + progressbar_width + 100 + progressbar_height + 40 + + countdown_pos_x + + countdown_pos_y + -20% + + boot_width + 1024 + boot_height + 768 + boot_bgcolor + #AAAAAA + + Index: branches/slice/old749m/artwork/themes/default/device_generic_o.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_generic_o.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/menu_selection.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/menu_selection.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_scroll_next.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_scroll_next.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/menu_help.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/menu_help.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_hfsraid_o.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_hfsraid_o.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/background.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/background.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/thumb.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/thumb.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_ext3_o.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_ext3_o.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_cdrom.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_cdrom.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/progress_bar_background.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/progress_bar_background.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/progress_bar.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/progress_bar.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/menu_verbose.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/menu_verbose.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/default/device_generic.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/default/device_generic.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/text_scroll_prev.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/text_scroll_prev.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/font_small.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/font_small.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/text_scroll_next.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/text_scroll_next.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/logo.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/logo.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/device_ext3.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/device_ext3.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/menu_single_user.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/menu_single_user.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/boot.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/boot.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/device_hfsplus.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/device_hfsplus.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/menu_ignore_caches_disabled.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/menu_ignore_caches_disabled.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/device_selection.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/device_selection.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/menu_video_info.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/menu_video_info.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/menu_memory_info.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/menu_memory_info.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/theme.plist =================================================================== --- branches/slice/old749m/artwork/themes/legacy/theme.plist (revision 0) +++ branches/slice/old749m/artwork/themes/legacy/theme.plist (revision 1174) @@ -0,0 +1,106 @@ + + + + + Enabled + no + screen_width + 1024 + screen_height + 768 + screen_textmargin_h + 10 + screen_textmargin_v + 10 + screen_bgcolor + #222334 + background_pos_x + 50% + background_pos_y + 0 + logo_pos_x + + logo_pos_y + 3% + logo_bgcolor + #000000 + logo_transparency + 255 + devices_pos_x + + devices_pos_y + + devices_bgcolor + #222334 + devices_transparency + 0 + devices_max_visible + 5 + devices_iconspacing + 20 + devices_layout + horizontal + bootprompt_pos_x + %50 + bootprompt_pos_y + -2 + bootprompt_width + 50% + bootprompt_height + 20 + bootprompt_textmargin_h + 10 + bootprompt_textmargin_v + 5 + bootprompt_bgcolor + #222334 + bootprompt_transparency + 1 + infobox_pos_x + + infobox_pos_y + + infobox_width + 650 + infobox_height + 406 + infobox_textmargin_h + 10 + infobox_textmargin_v + 10 + infobox_bgcolor + #222334 + infobox_transparency + 10 + menu_pos_x + + menu_pos_y + -5% + menu_textmargin_h + 10 + menu_textmargin_v + 5 + menu_bgcolor + #222334 + menu_transparency + 1 + progressbar_pos_x + + progressbar_pos_y + -30% + progressbar_width + 100 + progressbar_height + 40 + countdown_pos_x + + countdown_pos_y + -20% + boot_width + 1024 + boot_height + 768 + boot_bgcolor + #AAAAAA + + Index: branches/slice/old749m/artwork/themes/legacy/menu_selection.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/menu_selection.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/device_scroll_prev.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/device_scroll_prev.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/device_scroll_next.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/device_scroll_next.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/menu_help.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/menu_help.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/menu_ignore_caches.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/menu_ignore_caches.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/background.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/background.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/menu_verbose_disabled.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/menu_verbose_disabled.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/device_cdrom.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/device_cdrom.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/menu_boot.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/menu_boot.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/progress_bar_background.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/progress_bar_background.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/font_console.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/font_console.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/progress_bar.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/progress_bar.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/device_ntfs.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/device_ntfs.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/device_fat.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/device_fat.png ___________________________________________________________________ Added: svn:executable + * Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/menu_verbose.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/menu_verbose.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/menu_single_user_disabled.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/menu_single_user_disabled.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/legacy/device_generic.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/legacy/device_generic.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/text_scroll_prev.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/text_scroll_prev.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/device_fat32.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/device_fat32.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/font_small.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/font_small.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/text_scroll_next.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/text_scroll_next.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/device_fat16.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/device_fat16.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/logo.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/logo.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/device_ext3.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/device_ext3.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/menu_single_user.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/menu_single_user.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/boot.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/boot.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/device_hfsplus.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/device_hfsplus.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/menu_ignore_caches_disabled.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/menu_ignore_caches_disabled.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/device_selection.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/device_selection.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/menu_video_info.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/menu_video_info.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/menu_memory_info.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/menu_memory_info.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/menu_selection.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/menu_selection.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/device_scroll_prev.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/device_scroll_prev.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/theme.plist =================================================================== --- branches/slice/old749m/artwork/themes/bullet/theme.plist (revision 0) +++ branches/slice/old749m/artwork/themes/bullet/theme.plist (revision 1174) @@ -0,0 +1,116 @@ + + + + + Enabled + yes + + screen_width + 1024 + screen_height + 768 + screen_textmargin_h + 10 + screen_textmargin_v + 10 + screen_bgcolor + #aaaaaa + + background_pos_x + 50% + background_pos_y + 0 + + logo_pos_x + + logo_pos_y + 3% + logo_bgcolor + #aaaaaa + logo_transparency + 255 + + devices_pos_x + + devices_pos_y + + devices_bgcolor + #aaaaaa + devices_transparency + 0 + devices_max_visible + 5 + devices_iconspacing + 20 + devices_layout + horizontal + + bootprompt_pos_x + %50 + bootprompt_pos_y + -2 + bootprompt_width + 50% + bootprompt_height + 20 + bootprompt_textmargin_h + 10 + bootprompt_textmargin_v + 5 + bootprompt_bgcolor + #aaaaaa + bootprompt_transparency + 1 + + infobox_pos_x + + infobox_pos_y + + infobox_width + 650 + infobox_height + 406 + infobox_textmargin_h + 10 + infobox_textmargin_v + 10 + infobox_bgcolor + #aaaaaa + infobox_transparency + 10 + + menu_pos_x + + menu_pos_y + -5% + menu_textmargin_h + 10 + menu_textmargin_v + 5 + menu_bgcolor + #aaaaaa + menu_transparency + 1 + + progressbar_pos_x + + progressbar_pos_y + -37% + progressbar_width + 100 + progressbar_height + 40 + + countdown_pos_x + + countdown_pos_y + -30% + + boot_width + 1024 + boot_height + 768 + boot_bgcolor + #aaaaaa + + Index: branches/slice/old749m/artwork/themes/bullet/device_scroll_next.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/device_scroll_next.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/menu_help.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/menu_help.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/menu_ignore_caches.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/menu_ignore_caches.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/background.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/background.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/menu_verbose_disabled.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/menu_verbose_disabled.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/device_cdrom.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/device_cdrom.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/menu_boot.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/menu_boot.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/progress_bar_background.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/progress_bar_background.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/font_console.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/font_console.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/progress_bar.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/progress_bar.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/device_ntfs.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/device_ntfs.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/menu_verbose.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/menu_verbose.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/menu_single_user_disabled.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/menu_single_user_disabled.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/bullet/device_generic.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/bullet/device_generic.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/pinktink/logo.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/pinktink/logo.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/pinktink/theme.plist =================================================================== --- branches/slice/old749m/artwork/themes/pinktink/theme.plist (revision 0) +++ branches/slice/old749m/artwork/themes/pinktink/theme.plist (revision 1174) @@ -0,0 +1,106 @@ + + + + + Enabled + no + screen_width + 1024 + screen_height + 768 + screen_textmargin_h + 10 + screen_textmargin_v + 10 + screen_bgcolor + #FF1493 + background_pos_x + + background_pos_y + + logo_pos_x + 20% + logo_pos_y + 20% + logo_bgcolor + #000000 + logo_transparency + 255 + devices_pos_x + + devices_pos_y + + devices_bgcolor + #FF1493 + devices_transparency + 0 + devices_max_visible + 5 + devices_iconspacing + 20 + devices_layout + horizontal + bootprompt_pos_x + %50 + bootprompt_pos_y + -2 + bootprompt_width + 50% + bootprompt_height + 20 + bootprompt_textmargin_h + 10 + bootprompt_textmargin_v + 5 + bootprompt_bgcolor + #FF1493 + bootprompt_transparency + 1 + infobox_pos_x + + infobox_pos_y + + infobox_width + 650 + infobox_height + 406 + infobox_textmargin_h + 10 + infobox_textmargin_v + 10 + infobox_bgcolor + #FF1493 + infobox_transparency + 10 + menu_pos_x + + menu_pos_y + -5% + menu_textmargin_h + 10 + menu_textmargin_v + 5 + menu_bgcolor + #FF1493 + menu_transparency + 1 + progressbar_pos_x + + progressbar_pos_y + -30% + progressbar_width + 100 + progressbar_height + 40 + countdown_pos_x + + countdown_pos_y + -20% + boot_width + 1024 + boot_height + 768 + boot_bgcolor + #AAAAAA + + Index: branches/slice/old749m/artwork/themes/msi_netbook/logo.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/msi_netbook/logo.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/msi_netbook/theme.plist =================================================================== --- branches/slice/old749m/artwork/themes/msi_netbook/theme.plist (revision 0) +++ branches/slice/old749m/artwork/themes/msi_netbook/theme.plist (revision 1174) @@ -0,0 +1,106 @@ + + + + + Enabled + no + screen_width + 1024 + screen_height + 768 + screen_textmargin_h + 10 + screen_textmargin_v + 10 + screen_bgcolor + #000000 + background_pos_x + 50% + background_pos_y + 0 + logo_pos_x + + logo_pos_y + 15% + logo_bgcolor + #000000 + logo_transparency + 255 + devices_pos_x + + devices_pos_y + + devices_bgcolor + #000000 + devices_transparency + 0 + devices_max_visible + 5 + devices_iconspacing + 20 + devices_layout + horizontal + bootprompt_pos_x + %50 + bootprompt_pos_y + -2 + bootprompt_width + 50% + bootprompt_height + 20 + bootprompt_textmargin_h + 10 + bootprompt_textmargin_v + 5 + bootprompt_bgcolor + #000000 + bootprompt_transparency + 1 + infobox_pos_x + + infobox_pos_y + + infobox_width + 650 + infobox_height + 406 + infobox_textmargin_h + 10 + infobox_textmargin_v + 10 + infobox_bgcolor + #000000 + infobox_transparency + 10 + menu_pos_x + + menu_pos_y + -5% + menu_textmargin_h + 10 + menu_textmargin_v + 5 + menu_bgcolor + #000000 + menu_transparency + 1 + progressbar_pos_x + + progressbar_pos_y + -30% + progressbar_width + 100 + progressbar_height + 40 + countdown_pos_x + + countdown_pos_y + -20% + boot_width + 1024 + boot_height + 768 + boot_bgcolor + #AAAAAA + + Index: branches/slice/old749m/artwork/themes/twilight/font_small.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/twilight/font_small.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/twilight/logo.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/twilight/logo.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/twilight/theme.plist =================================================================== --- branches/slice/old749m/artwork/themes/twilight/theme.plist (revision 0) +++ branches/slice/old749m/artwork/themes/twilight/theme.plist (revision 1174) @@ -0,0 +1,106 @@ + + + + + Enabled + no + screen_width + 1024 + screen_height + 768 + screen_textmargin_h + 10 + screen_textmargin_v + 10 + screen_bgcolor + #000000 + background_pos_x + 50% + background_pos_y + 0 + logo_pos_x + + logo_pos_y + 3% + logo_bgcolor + #000000 + logo_transparency + 255 + devices_pos_x + + devices_pos_y + + devices_bgcolor + #000000 + devices_transparency + 0 + devices_max_visible + 5 + devices_iconspacing + 20 + devices_layout + horizontal + bootprompt_pos_x + %50 + bootprompt_pos_y + -2 + bootprompt_width + 50% + bootprompt_height + 20 + bootprompt_textmargin_h + 10 + bootprompt_textmargin_v + 5 + bootprompt_bgcolor + #000000 + bootprompt_transparency + 1 + infobox_pos_x + + infobox_pos_y + + infobox_width + 650 + infobox_height + 406 + infobox_textmargin_h + 10 + infobox_textmargin_v + 10 + infobox_bgcolor + #000000 + infobox_transparency + 10 + menu_pos_x + + menu_pos_y + -5% + menu_textmargin_h + 10 + menu_textmargin_v + 5 + menu_bgcolor + #000000 + menu_transparency + 1 + progressbar_pos_x + + progressbar_pos_y + -30% + progressbar_width + 100 + progressbar_height + 40 + countdown_pos_x + + countdown_pos_y + -20% + boot_width + 1024 + boot_height + 768 + boot_bgcolor + #AAAAAA + + Index: branches/slice/old749m/artwork/themes/embed/text_scroll_prev.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/text_scroll_prev.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/font_small.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/font_small.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/device_hfsraid.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/device_hfsraid.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/text_scroll_next.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/text_scroll_next.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/logo.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/logo.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/device_ext3.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/device_ext3.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/menu_single_user.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/menu_single_user.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/boot.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/boot.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/device_hfsplus.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/device_hfsplus.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/menu_ignore_caches_disabled.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/menu_ignore_caches_disabled.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/device_selection.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/device_selection.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/menu_video_info.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/menu_video_info.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/menu_memory_info.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/menu_memory_info.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/theme.plist =================================================================== --- branches/slice/old749m/artwork/themes/embed/theme.plist (revision 0) +++ branches/slice/old749m/artwork/themes/embed/theme.plist (revision 1174) @@ -0,0 +1,110 @@ + + + + + Author + Blackosx + Version + 1.0 + Enabled + no + screen_width + 1024 + screen_height + 600 + screen_textmargin_h + 10 + screen_textmargin_v + 10 + screen_bgcolor + #767f73 + background_pos_x + 50% + background_pos_y + 0 + logo_pos_x + + logo_pos_y + 5% + logo_bgcolor + #000000 + logo_transparency + 255 + devices_pos_x + + devices_pos_y + + devices_bgcolor + #767f73 + devices_transparency + 0 + devices_max_visible + 5 + devices_iconspacing + 35 + devices_layout + horizontal + bootprompt_pos_x + + bootprompt_pos_y + -6 + bootprompt_width + 40% + bootprompt_height + 20 + bootprompt_textmargin_h + 10 + bootprompt_textmargin_v + 5 + bootprompt_bgcolor + #3e3e3e + bootprompt_transparency + 1 + infobox_pos_x + + infobox_pos_y + 30% + infobox_width + 660 + infobox_height + 320 + infobox_textmargin_h + 10 + infobox_textmargin_v + 10 + infobox_bgcolor + #3e3e3e + infobox_transparency + 35 + menu_pos_x + + menu_pos_y + -5% + menu_textmargin_h + 10 + menu_textmargin_v + 5 + menu_bgcolor + #3e3e3e + menu_transparency + 1 + progressbar_pos_x + + progressbar_pos_y + -30% + progressbar_width + 100 + progressbar_height + 40 + countdown_pos_x + + countdown_pos_y + -20% + boot_width + 1024 + boot_height + 768 + boot_bgcolor + #AAAAAA + + Index: branches/slice/old749m/artwork/themes/embed/menu_selection.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/menu_selection.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/device_scroll_prev.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/device_scroll_prev.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/device_scroll_next.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/device_scroll_next.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/menu_help.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/menu_help.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/menu_ignore_caches.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/menu_ignore_caches.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/background.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/background.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/menu_verbose_disabled.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/menu_verbose_disabled.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/device_cdrom.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/device_cdrom.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/menu_boot.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/menu_boot.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/progress_bar_background.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/progress_bar_background.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/font_console.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/font_console.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/progress_bar.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/progress_bar.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/device_ntfs.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/device_ntfs.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/device_fat.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/device_fat.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/menu_verbose.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/menu_verbose.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/menu_single_user_disabled.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/menu_single_user_disabled.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/artwork/themes/embed/device_generic.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: branches/slice/old749m/artwork/themes/embed/device_generic.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: branches/slice/old749m/i386/libsaio/fake_efi.h =================================================================== --- branches/slice/old749m/i386/libsaio/fake_efi.h (revision 0) +++ branches/slice/old749m/i386/libsaio/fake_efi.h (revision 1174) @@ -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/old749m/i386/libsaio/xml.c =================================================================== --- branches/slice/old749m/i386/libsaio/xml.c (revision 0) +++ branches/slice/old749m/i386/libsaio/xml.c (revision 1174) @@ -0,0 +1,1150 @@ +/* + * 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 alder32; + unsigned long version; + unsigned long numDrivers; + unsigned long reserved1; + unsigned long reserved2; +}; +typedef struct DriversPackage DriversPackage; + +enum { + kCFBundleType2, + kCFBundleType3 +}; + + +#define USEMALLOC 1 +#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 ParseTagBoolean(char *buffer, TagPtr *tag, long type); +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; +} + + +// 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; + + + + configBuffer = malloc(strlen(buffer)+1); + strcpy(configBuffer, buffer); + + 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 + { + verbose("ParseStringID error (0x%x)\n", *val); + getc(); + 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); + getc(); + 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 + { + verbose("ParseIntegerID error (0x%x)\n", *val); + getc(); + 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 + { + verbose("ParseStringIDREF error (0x%x)\n", *val); + getc(); + 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 + { + verbose("ParseTagInteger hex error (0x%x) in buffer %s\n", *val, buffer); + getc(); + 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') + { + verbose("ParseTagInteger decimal error (0x%x) in buffer %s\n", *val, buffer); + getc(); + 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); + // getc(); + + // 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; + + verbose("ParseTagDate unimplimented\n"); + getc(); + + 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 + +static 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) + { +#if USEMALLOC + tag = (TagPtr)malloc(kTagsPerBlock * sizeof(Tag)); +#else + tag = (TagPtr)AllocateBootXMemory(kTagsPerBlock * sizeof(Tag)); +#endif + 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) + { +#if USEMALLOC + symbol = (SymbolPtr)malloc(sizeof(Symbol) + 1 + strlen(string)); +#else + symbol = (SymbolPtr)AllocateBootXMemory(sizeof(Symbol) + 1 + strlen(string)); +#endif + 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 ***/ +TagPtr XMLCastArray(TagPtr dict) +{ + if(!dict) return NULL; + if(dict->type == kTagTypeArray) return dict; + else return NULL; +} + + +TagPtr XMLCastDict(TagPtr dict) +{ + if(!dict) return NULL; + if(dict->type == kTagTypeDict) return dict; + else return NULL; +} + +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 XMLCastBoolean(TagPtr dict) +{ + if(!dict) return false; + if(dict->type == kTagTypeTrue) return true; + return false; +} + +int XMLCastInteger(TagPtr dict) +{ + if(!dict) + { + verbose("XMLCastInteger: null dict\n"); + return 0; + } + if(dict->type == kTagTypeInteger) return (int)(dict->string); + return 0; +} Index: branches/slice/old749m/i386/libsaio/asm.s =================================================================== --- branches/slice/old749m/i386/libsaio/asm.s (revision 0) +++ branches/slice/old749m/i386/libsaio/asm.s (revision 1174) @@ -0,0 +1,499 @@ +/* + * 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 +#if UNUSED +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// 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 +#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/old749m/i386/libsaio/console.c =================================================================== --- branches/slice/old749m/i386/libsaio/console.c (revision 0) +++ branches/slice/old749m/i386/libsaio/console.c (revision 1174) @@ -0,0 +1,246 @@ +/* + * 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" + +extern int vprf(const char * fmt, va_list ap); + +bool gVerboseMode; +bool gErrors; + +/* Kabyl: BooterLog */ +#define BOOTER_LOG_SIZE (64 * 1024) +#define SAFE_LOG_SIZE 80 + +char *msgbuf = 0; +char *cursor = 0; + +struct putc_info { + char * str; + char * last_str; +}; + +void sputc(int c, struct putc_info * pi) +{ + if (pi->last_str) + if (pi->str == pi->last_str) + { + *(pi->str) = '\0'; + return; + } + *(pi->str)++ = c; +} + +void initBooterLog(void) +{ + msgbuf = malloc(BOOTER_LOG_SIZE); + bzero(msgbuf, BOOTER_LOG_SIZE); + cursor = msgbuf; +} + +void msglog(const char * fmt, ...) +{ + va_list ap; + struct putc_info pi; + + if (!msgbuf) + return; + + if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE))) + return; + + va_start(ap, fmt); + pi.str = cursor; + pi.last_str = 0; + prf(fmt, ap, sputc, &pi); + va_end(ap); + cursor += strlen((char *)cursor); +} + +void setupBooterLog(void) +{ + if (!msgbuf) + return; + + Node *node = DT__FindNode("/", false); + if (node) + DT__AddProperty(node, "boot-log", strlen((char *)msgbuf) + 1, msgbuf); +} +/* Kabyl: !BooterLog */ + + +/* + * write one character to console + */ +void putchar(int c) +{ + if ( c == '\t' ) + { + for (c = 0; c < 8; c++) putc(' '); + return; + } + + if ( c == '\n' ) + { + putc('\r'); + } + + putc(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); + + prf(fmt, ap, putchar, 0); + + { + /* 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) + { + prf(fmt, ap, putchar, 0); + } + + { + /* 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); + + prf(fmt, ap, putchar, 0); + + va_end(ap); + return(0); +} + +void stop(const char * fmt, ...) +{ + va_list ap; + + printf("\n"); + va_start(ap, fmt); + + prf(fmt, ap, putchar, 0); + + 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..."); + getc(); +} Index: branches/slice/old749m/i386/libsaio/shortatombios.h =================================================================== --- branches/slice/old749m/i386/libsaio/shortatombios.h (revision 0) +++ branches/slice/old749m/i386/libsaio/shortatombios.h (revision 1174) @@ -0,0 +1,192 @@ +/****************************************************************************/ +/*Portion I: Definitions shared between VBIOS and Driver */ +/****************************************************************************/ + + +#ifndef _SHORT_ATOMBIOS_H +#define _SHORT_ATOMBIOS_H + +#define ATOM_VERSION_MAJOR 0x00020000 +#define ATOM_VERSION_MINOR 0x00000002 + +#define ATOM_HEADER_VERSION (ATOM_VERSION_MAJOR | ATOM_VERSION_MINOR) + +typedef unsigned char BOOLEAN; +typedef signed char INT8; +typedef unsigned char UINT8; +typedef signed short INT16; +typedef unsigned short UINT16; +typedef signed long INT32; +typedef unsigned long UINT32; +typedef unsigned char CHAR8; +typedef unsigned short CHAR16; +typedef unsigned short USHORT; +typedef unsigned char UCHAR; +typedef unsigned long ULONG; + +#pragma pack(1) /* BIOS data must use byte aligment */ + +/* Define offset to location of ROM header. */ + +#define OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER 0x00000048L +#define OFFSET_TO_ATOM_ROM_IMAGE_SIZE 0x00000002L + +typedef struct _ATOM_COMMON_TABLE_HEADER +{ + USHORT usStructureSize; + UCHAR ucTableFormatRevision; /*Change it when the Parser is not backward compatible */ + UCHAR ucTableContentRevision; /*Change it only when the table needs to change but the firmware */ + /*Image can't be updated, while Driver needs to carry the new table! */ +} ATOM_COMMON_TABLE_HEADER; + +typedef struct _ATOM_ROM_HEADER +{ + ATOM_COMMON_TABLE_HEADER sHeader; + UCHAR uaFirmWareSignature[4]; /*Signature to distinguish between Atombios and non-atombios, + + atombios should init it as "ATOM", don't change the position */ + USHORT usBiosRuntimeSegmentAddress; + USHORT usProtectedModeInfoOffset; + USHORT usConfigFilenameOffset; + USHORT usCRC_BlockOffset; + USHORT usBIOS_BootupMessageOffset; + USHORT usInt10Offset; + USHORT usPciBusDevInitCode; + USHORT usIoBaseAddress; + USHORT usSubsystemVendorID; + USHORT usSubsystemID; + USHORT usPCI_InfoOffset; + USHORT usMasterCommandTableOffset; /*Offset for SW to get all command table offsets, Don't change the position */ + USHORT usMasterDataTableOffset; /*Offset for SW to get all data table offsets, Don't change the position */ + UCHAR ucExtendedFunctionCode; + UCHAR ucReserved; +} ATOM_ROM_HEADER; + +/****************************************************************************/ +// Structure used in Data.mtb +/****************************************************************************/ +typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES +{ + USHORT UtilityPipeLine; // Offest for the utility to get parser info,Don't change this position! + USHORT MultimediaCapabilityInfo; // Only used by MM Lib,latest version 1.1, not configuable from Bios, need to include the table to build Bios + USHORT MultimediaConfigInfo; // Only used by MM Lib,latest version 2.1, not configuable from Bios, need to include the table to build Bios + USHORT StandardVESA_Timing; // Only used by Bios + USHORT FirmwareInfo; // Shared by various SW components,latest version 1.4 + USHORT DAC_Info; // Will be obsolete from R600 + USHORT LVDS_Info; // Shared by various SW components,latest version 1.1 + USHORT TMDS_Info; // Will be obsolete from R600 + USHORT AnalogTV_Info; // Shared by various SW components,latest version 1.1 + USHORT SupportedDevicesInfo; // Will be obsolete from R600 + USHORT GPIO_I2C_Info; // Shared by various SW components,latest version 1.2 will be used from R600 + USHORT VRAM_UsageByFirmware; // Shared by various SW components,latest version 1.3 will be used from R600 + USHORT GPIO_Pin_LUT; // Shared by various SW components,latest version 1.1 + USHORT VESA_ToInternalModeLUT; // Only used by Bios + USHORT ComponentVideoInfo; // Shared by various SW components,latest version 2.1 will be used from R600 + USHORT PowerPlayInfo; // Shared by various SW components,latest version 2.1,new design from R600 + USHORT CompassionateData; // Will be obsolete from R600 + USHORT SaveRestoreInfo; // Only used by Bios + USHORT PPLL_SS_Info; // Shared by various SW components,latest version 1.2, used to call SS_Info, change to new name because of int ASIC SS info + USHORT OemInfo; // Defined and used by external SW, should be obsolete soon + USHORT XTMDS_Info; // Will be obsolete from R600 + USHORT MclkSS_Info; // Shared by various SW components,latest version 1.1, only enabled when ext SS chip is used + USHORT Object_Header; // Shared by various SW components,latest version 1.1 + USHORT IndirectIOAccess; // Only used by Bios,this table position can't change at all!! + USHORT MC_InitParameter; // Only used by command table + USHORT ASIC_VDDC_Info; // Will be obsolete from R600 + USHORT ASIC_InternalSS_Info; // New tabel name from R600, used to be called "ASIC_MVDDC_Info" + USHORT TV_VideoMode; // Only used by command table + USHORT VRAM_Info; // Only used by command table, latest version 1.3 + USHORT MemoryTrainingInfo; // Used for VBIOS and Diag utility for memory training purpose since R600. the new table rev start from 2.1 + USHORT IntegratedSystemInfo; // Shared by various SW components + USHORT ASIC_ProfilingInfo; // New table name from R600, used to be called "ASIC_VDDCI_Info" for pre-R600 + USHORT VoltageObjectInfo; // Shared by various SW components, latest version 1.1 + USHORT PowerSourceInfo; // Shared by various SW components, latest versoin 1.1 +} ATOM_MASTER_LIST_OF_DATA_TABLES; + +typedef struct _ATOM_MASTER_DATA_TABLE +{ + ATOM_COMMON_TABLE_HEADER sHeader; + ATOM_MASTER_LIST_OF_DATA_TABLES ListOfDataTables; +} ATOM_MASTER_DATA_TABLE; + +typedef union _ATOM_MODE_MISC_INFO_ACCESS +{ + USHORT usAccess; +} ATOM_MODE_MISC_INFO_ACCESS; + +/****************************************************************************/ +// Structure used in StandardVESA_TimingTable +// AnalogTV_InfoTable +// ComponentVideoInfoTable +/****************************************************************************/ +typedef struct _ATOM_MODE_TIMING +{ + USHORT usCRTC_H_Total; + USHORT usCRTC_H_Disp; + USHORT usCRTC_H_SyncStart; + USHORT usCRTC_H_SyncWidth; + USHORT usCRTC_V_Total; + USHORT usCRTC_V_Disp; + USHORT usCRTC_V_SyncStart; + USHORT usCRTC_V_SyncWidth; + USHORT usPixelClock; //in 10Khz unit + ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; + USHORT usCRTC_OverscanRight; + USHORT usCRTC_OverscanLeft; + USHORT usCRTC_OverscanBottom; + USHORT usCRTC_OverscanTop; + USHORT usReserve; + UCHAR ucInternalModeNumber; + UCHAR ucRefreshRate; +} ATOM_MODE_TIMING; + +typedef struct _ATOM_DTD_FORMAT +{ + USHORT usPixClk; + USHORT usHActive; + USHORT usHBlanking_Time; + USHORT usVActive; + USHORT usVBlanking_Time; + USHORT usHSyncOffset; + USHORT usHSyncWidth; + USHORT usVSyncOffset; + USHORT usVSyncWidth; + USHORT usImageHSize; + USHORT usImageVSize; + UCHAR ucHBorder; + UCHAR ucVBorder; + ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; + UCHAR ucInternalModeNumber; + UCHAR ucRefreshRate; +} ATOM_DTD_FORMAT; + +typedef struct _ATOM_LVDS_INFO_V12 +{ + ATOM_COMMON_TABLE_HEADER sHeader; + ATOM_DTD_FORMAT sLCDTiming; + USHORT usExtInfoTableOffset; + USHORT usSupportedRefreshRate; //Refer to panel info table in ATOMBIOS extension Spec. + USHORT usOffDelayInMs; + UCHAR ucPowerSequenceDigOntoDEin10Ms; + UCHAR ucPowerSequenceDEtoBLOnin10Ms; + UCHAR ucLVDS_Misc; // Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level} + // Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888} + // Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled} + // Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled} + UCHAR ucPanelDefaultRefreshRate; + UCHAR ucPanelIdentification; + UCHAR ucSS_Id; + USHORT usLCDVenderID; + USHORT usLCDProductID; + UCHAR ucLCDPanel_SpecialHandlingCap; + UCHAR ucPanelInfoSize; // start from ATOM_DTD_FORMAT to end of panel info, include ExtInfoTable + UCHAR ucReserved[2]; +} ATOM_LVDS_INFO_V12; + + +typedef struct _ATOM_STANDARD_VESA_TIMING +{ + ATOM_COMMON_TABLE_HEADER sHeader; + char * aModeTimings; // 16 is not the real array number, just for initial allocation +} ATOM_STANDARD_VESA_TIMING; + +#endif \ No newline at end of file Index: branches/slice/old749m/i386/libsaio/xml.h =================================================================== --- branches/slice/old749m/i386/libsaio/xml.h (revision 0) +++ branches/slice/old749m/i386/libsaio/xml.h (revision 1174) @@ -0,0 +1,111 @@ +/* + * 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 ); +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 ); + +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 ); + +#endif /* __LIBSAIO_XML_H */ Index: branches/slice/old749m/i386/libsaio/efi.h =================================================================== --- branches/slice/old749m/i386/libsaio/efi.h (revision 0) +++ branches/slice/old749m/i386/libsaio/efi.h (revision 1174) @@ -0,0 +1,571 @@ +/* + * 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 +//rfc4122 +typedef struct { + EFI_UINT32 time_low; + EFI_UINT16 time_mid; + EFI_UINT16 time_hi_and_version; + EFI_UINT8 clock_seq_hi_and_reserved; + EFI_UINT8 clock_seq_low; + EFI_UINT8 node[6]; +} 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 + +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; + +typedef EFI_UINT8 EFI_DEVICE_PATH_PROTOCOL; + +typedef struct _BLESS_EFI_LOAD_OPTION { + EFI_UINT32 Attributes; + EFI_UINT16 FilePathListLength; + EFI_CHAR16 Description[0]; + EFI_DEVICE_PATH_PROTOCOL FilePathList[0]; + EFI_UINT8 OptionalData[0]; +} BLESS_EFI_LOAD_OPTION; + + +#endif /* _PEXPERT_I386_EFI_H */ Index: branches/slice/old749m/i386/libsaio/bootstruct.c =================================================================== --- branches/slice/old749m/i386/libsaio/bootstruct.c (revision 0) +++ branches/slice/old749m/i386/libsaio/bootstruct.c (revision 1174) @@ -0,0 +1,173 @@ +/* + * 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; +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)); + 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(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 = 5; + + init_done = 1; + } + +} + + +/* Copy boot args after kernel and record address. */ + +void +reserveKernBootStruct(void) +{ + void *oldAddr = bootArgs; + bootArgs = (boot_args *)AllocateKernelMemory(sizeof(boot_args)); + bcopy(oldAddr, bootArgs, sizeof(boot_args)); +} + +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; +} Index: branches/slice/old749m/i386/libsaio/cpuid.h =================================================================== --- branches/slice/old749m/i386/libsaio/cpuid.h (revision 0) +++ branches/slice/old749m/i386/libsaio/cpuid.h (revision 1174) @@ -0,0 +1,437 @@ +/* + * cpuid.h + * + */ + +#ifndef M_CPUID_H +#define M_CPUID_H + +#include +#include +#include +#include + + +#define CPUID_VID_INTEL "GenuineIntel" +#define CPUID_VID_AMD "AuthenticAMD" + +#define CPUID_STRING_UNKNOWN "Unknown CPU Typ" + +#define MSR_CORE_THREAD_COUNT 0x035 + +#define _Bit(n) (1ULL << n) +#define _HBit(n) (1ULL << ((n)+32)) + +/* + * The CPUID_FEATURE_XXX values define 64-bit values + * returned in %ecx:%edx to a CPUID request with %eax of 1: + */ +#define CPUID_FEATURE_FPU _Bit(0) /* Floating point unit on-chip */ +#define CPUID_FEATURE_VME _Bit(1) /* Virtual Mode Extension */ +#define CPUID_FEATURE_DE _Bit(2) /* Debugging Extension */ +#define CPUID_FEATURE_PSE _Bit(3) /* Page Size Extension */ +#define CPUID_FEATURE_TSC _Bit(4) /* Time Stamp Counter */ +#define CPUID_FEATURE_MSR _Bit(5) /* Model Specific Registers */ +#define CPUID_FEATURE_PAE _Bit(6) /* Physical Address Extension */ +#define CPUID_FEATURE_MCE _Bit(7) /* Machine Check Exception */ +#define CPUID_FEATURE_CX8 _Bit(8) /* CMPXCHG8B */ +#define CPUID_FEATURE_APIC _Bit(9) /* On-chip APIC */ +#define CPUID_FEATURE_SEP _Bit(11) /* Fast System Call */ +#define CPUID_FEATURE_MTRR _Bit(12) /* Memory Type Range Register */ +#define CPUID_FEATURE_PGE _Bit(13) /* Page Global Enable */ +#define CPUID_FEATURE_MCA _Bit(14) /* Machine Check Architecture */ +#define CPUID_FEATURE_CMOV _Bit(15) /* Conditional Move Instruction */ +#define CPUID_FEATURE_PAT _Bit(16) /* Page Attribute Table */ +#define CPUID_FEATURE_PSE36 _Bit(17) /* 36-bit Page Size Extension */ +#define CPUID_FEATURE_PSN _Bit(18) /* Processor Serial Number */ +#define CPUID_FEATURE_CLFSH _Bit(19) /* CLFLUSH Instruction supported */ +#define CPUID_FEATURE_DS _Bit(21) /* Debug Store */ +#define CPUID_FEATURE_ACPI _Bit(22) /* Thermal monitor and Clock Ctrl */ +#define CPUID_FEATURE_MMX _Bit(23) /* MMX supported */ +#define CPUID_FEATURE_FXSR _Bit(24) /* Fast floating pt save/restore */ +#define CPUID_FEATURE_SSE _Bit(25) /* Streaming SIMD extensions */ +#define CPUID_FEATURE_SSE2 _Bit(26) /* Streaming SIMD extensions 2 */ +#define CPUID_FEATURE_SS _Bit(27) /* Self-Snoop */ +#define CPUID_FEATURE_HTT _Bit(28) /* Hyper-Threading Technology */ +#define CPUID_FEATURE_TM _Bit(29) /* Thermal Monitor (TM1) */ +#define CPUID_FEATURE_PBE _Bit(31) /* Pend Break Enable */ + +#define CPUID_FEATURE_SSE3 _HBit(0) /* Streaming SIMD extensions 3 */ +#define CPUID_FEATURE_PCLMULQDQ _HBit(1) /* PCLMULQDQ Instruction */ + +#define CPUID_FEATURE_MONITOR _HBit(3) /* Monitor/mwait */ +#define CPUID_FEATURE_DSCPL _HBit(4) /* Debug Store CPL */ +#define CPUID_FEATURE_VMX _HBit(5) /* VMX */ +#define CPUID_FEATURE_SMX _HBit(6) /* SMX */ +#define CPUID_FEATURE_EST _HBit(7) /* Enhanced SpeedsTep (GV3) */ +#define CPUID_FEATURE_TM2 _HBit(8) /* Thermal Monitor 2 */ +#define CPUID_FEATURE_SSSE3 _HBit(9) /* Supplemental SSE3 instructions */ +#define CPUID_FEATURE_CID _HBit(10) /* L1 Context ID */ + +#define CPUID_FEATURE_CX16 _HBit(13) /* CmpXchg16b instruction */ +#define CPUID_FEATURE_xTPR _HBit(14) /* Send Task PRiority msgs */ +#define CPUID_FEATURE_PDCM _HBit(15) /* Perf/Debug Capability MSR */ + +#define CPUID_FEATURE_DCA _HBit(18) /* Direct Cache Access */ +#define CPUID_FEATURE_SSE4_1 _HBit(19) /* Streaming SIMD extensions 4.1 */ +#define CPUID_FEATURE_SSE4_2 _HBit(20) /* Streaming SIMD extensions 4.2 */ +#define CPUID_FEATURE_xAPIC _HBit(21) /* Extended APIC Mode */ +#define CPUID_FEATURE_POPCNT _HBit(23) /* POPCNT instruction */ +#define CPUID_FEATURE_AES _HBit(25) /* AES instructions */ +#define CPUID_FEATURE_VMM _HBit(31) /* VMM (Hypervisor) present */ + +/* + * The CPUID_EXTFEATURE_XXX values define 64-bit values + * returned in %ecx:%edx to a CPUID request with %eax of 0x80000001: + */ +#define CPUID_EXTFEATURE_SYSCALL _Bit(11) /* SYSCALL/sysret */ +#define CPUID_EXTFEATURE_XD _Bit(20) /* eXecute Disable */ +#define CPUID_EXTFEATURE_1GBPAGE _Bit(26) /* 1G-Byte Page support */ +#define CPUID_EXTFEATURE_RDTSCP _Bit(27) /* RDTSCP */ +#define CPUID_EXTFEATURE_EM64T _Bit(29) /* Extended Mem 64 Technology */ + +//#define CPUID_EXTFEATURE_LAHF _HBit(20) /* LAFH/SAHF instructions */ +// New definition with Snow kernel +#define CPUID_EXTFEATURE_LAHF _HBit(0) /* LAHF/SAHF instructions */ +/* + * The CPUID_EXTFEATURE_XXX values define 64-bit values + * returned in %ecx:%edx to a CPUID request with %eax of 0x80000007: + */ +#define CPUID_EXTFEATURE_TSCI _Bit(8) /* TSC Invariant */ + +#define CPUID_CACHE_SIZE 16 /* Number of descriptor values */ + +#define CPUID_MWAIT_EXTENSION _Bit(0) /* enumeration of WMAIT extensions */ +#define CPUID_MWAIT_BREAK _Bit(1) /* interrupts are break events */ + +#define CPU_MODEL_PENTIUM_M 0x0D +#define CPU_MODEL_YONAH 0x0E +#define CPU_MODEL_MEROM 0x0F +#define CPU_MODEL_PENRYN 0x17 +#define CPU_MODEL_NEHALEM 0x1A +#define CPU_MODEL_ATOM 0x1C +#define CPU_MODEL_FIELDS 0x1E /* Lynnfield, Clarksfield, Jasper */ +#define CPU_MODEL_DALES 0x1F /* Havendale, Auburndale */ +#define CPU_MODEL_DALES_32NM 0x25 /* Clarkdale, Arrandale */ +#define CPU_MODEL_WESTMERE 0x2C /* Gulftown, Westmere-EP, Westmere-WS */ +#define CPU_MODEL_NEHALEM_EX 0x2E +#define CPU_MODEL_WESTMERE_EX 0x2F + +#include +#include +#include +#include + + +typedef enum { eax, ebx, ecx, edx } cpuid_register_t; +static inline void +cpuid(uint32_t *data) +{ + __asm__ volatile("cpuid" + : "=a" (data[eax]), + "=b" (data[ebx]), + "=c" (data[ecx]), + "=d" (data[edx]) + : "a" (data[eax]), + "b" (data[ebx]), + "c" (data[ecx]), + "d" (data[edx])); +} +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)); +} + +/* + * Cache ID descriptor structure, used to parse CPUID leaf 2. + * Note: not used in kernel. + */ +typedef enum { Lnone, L1I, L1D, L2U, L3U, LCACHE_MAX } cache_type_t ; +typedef struct { + unsigned char value; /* Descriptor value */ + cache_type_t type; /* Cache type */ + unsigned int size; /* Cache size */ + unsigned int linesize; /* Cache line size */ + const char *description; /* Cache description */ +} cpuid_cache_desc_t; + + +#define CACHE_DESC(value,type,size,linesize,text) \ +{ value, type, size, linesize, text } + +#define _Bit(n) (1ULL << n) +//#define _HBit(n) (1ULL << ((n) + 32)) + +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define quad(hi,lo) (((uint64_t)(hi)) << 32 | (lo)) +#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) + +/* Physical CPU info - this is exported out of the kernel (kexts), so be wary of changes */ +typedef struct { + char cpuid_vendor[16]; + char cpuid_brand_string[48]; + const char *cpuid_model_string; + + cpu_type_t cpuid_type; /* this is *not* a cpu_type_t in our */ + uint8_t cpuid_family; + uint8_t cpuid_model; + uint8_t cpuid_extmodel; + uint8_t cpuid_extfamily; + uint8_t cpuid_stepping; + uint64_t cpuid_features; + uint64_t cpuid_extfeatures; + uint32_t cpuid_signature; + uint8_t cpuid_brand; + + uint32_t cache_size[LCACHE_MAX]; + uint32_t cache_linesize; + + uint8_t cache_info[64]; /* list of cache descriptors */ + + uint32_t cpuid_cores_per_package; + uint32_t cpuid_logical_per_package; + uint32_t cache_sharing[LCACHE_MAX]; + uint32_t cache_partitions[LCACHE_MAX]; + + cpu_type_t cpuid_cpu_type; /* */ + cpu_subtype_t cpuid_cpu_subtype; /* */ + + /* Monitor/mwait Leaf: */ + uint32_t cpuid_mwait_linesize_min; + uint32_t cpuid_mwait_linesize_max; + uint32_t cpuid_mwait_extensions; + uint32_t cpuid_mwait_sub_Cstates; + + /* Thermal and Power Management Leaf: */ + boolean_t cpuid_thermal_sensor; + boolean_t cpuid_thermal_dynamic_acceleration; + uint32_t cpuid_thermal_thresholds; + boolean_t cpuid_thermal_ACNT_MCNT; + + /* Architectural Performance Monitoring Leaf: */ + uint8_t cpuid_arch_perf_version; + uint8_t cpuid_arch_perf_number; + uint8_t cpuid_arch_perf_width; + uint8_t cpuid_arch_perf_events_number; + uint32_t cpuid_arch_perf_events; + uint8_t cpuid_arch_perf_fixed_number; + uint8_t cpuid_arch_perf_fixed_width; + + /* Cache details: */ + uint32_t cpuid_cache_linesize; + uint32_t cpuid_cache_L2_associativity; + uint32_t cpuid_cache_size; + + /* Virtual and physical address aize: */ + uint32_t cpuid_address_bits_physical; + uint32_t cpuid_address_bits_virtual; + + uint32_t cpuid_microcode_version; + + /* Numbers of tlbs per processor [i|d, small|large, level0|level1] */ + uint32_t cpuid_tlb[2][2][2]; +#define TLB_INST 0 +#define TLB_DATA 1 +#define TLB_SMALL 0 +#define TLB_LARGE 1 + uint32_t cpuid_stlb; + + uint32_t core_count; + uint32_t thread_count; + + /* Max leaf ids available from CPUID */ + uint32_t cpuid_max_basic; + uint32_t cpuid_max_ext; +} i386_cpu_info_t; + +static i386_cpu_info_t cpuid_cpu_info; + +static i386_cpu_info_t *cpuid_info(void) +{ + return &cpuid_cpu_info; +} +/* +static uint32_t cpuid_count_cores() +{ + uint32_t cpuid_reg[4]; + + do_cpuid(1, cpuid_reg); + + return bitfield(cpuid_reg[1], 23, 16); +} +*/ + +static void cpuid_update_generic_info() +{ + uint32_t cpuid_reg[4]; + uint32_t max_extid; + char str[128]; + char* p; + i386_cpu_info_t* info_p = cpuid_info(); + + /* Get vendor */ + do_cpuid(0, cpuid_reg); + bcopy((char *)&cpuid_reg[ebx], &info_p->cpuid_vendor[0], 4); /* ug */ + bcopy((char *)&cpuid_reg[ecx], &info_p->cpuid_vendor[8], 4); + bcopy((char *)&cpuid_reg[edx], &info_p->cpuid_vendor[4], 4); + info_p->cpuid_vendor[12] = 0; + + /* Get extended CPUID results */ + do_cpuid(0x80000000, cpuid_reg); + max_extid = cpuid_reg[eax]; + + /* Check to see if we can get the brand string */ + if (max_extid >= 0x80000004) { + /* + * The brand string is up to 48 bytes and is guaranteed to be + * NUL terminated. + */ + do_cpuid(0x80000002, cpuid_reg); + bcopy((char *)cpuid_reg, &str[0], 16); + do_cpuid(0x80000003, cpuid_reg); + bcopy((char *)cpuid_reg, &str[16], 16); + do_cpuid(0x80000004, cpuid_reg); + bcopy((char *)cpuid_reg, &str[32], 16); + for (p = str; *p != '\0'; p++) { + if (*p != ' ') break; + } + strncpy(info_p->cpuid_brand_string, p, + sizeof(info_p->cpuid_brand_string)); + + if (!strncmp(info_p->cpuid_brand_string, CPUID_STRING_UNKNOWN, + min(sizeof(info_p->cpuid_brand_string), + strlen(CPUID_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. + */ + info_p->cpuid_brand_string[0] = '\0'; + } + } + + /* Get cache and addressing info */ + if (max_extid >= 0x80000006) { + do_cpuid(0x80000006, cpuid_reg); + info_p->cpuid_cache_linesize = bitfield(cpuid_reg[ecx], 7, 0); + info_p->cpuid_cache_L2_associativity = bitfield(cpuid_reg[ecx], 15, 12); + info_p->cpuid_cache_size = bitfield(cpuid_reg[ecx], 31, 16); + do_cpuid(0x80000008, cpuid_reg); + info_p->cpuid_address_bits_physical = bitfield(cpuid_reg[eax], 7, 0); + info_p->cpuid_address_bits_virtual = bitfield(cpuid_reg[eax], 15, 8); + } + + /* Get processor signature and decode */ + do_cpuid(1, cpuid_reg); + info_p->cpuid_signature = cpuid_reg[eax]; + info_p->cpuid_stepping = bitfield(cpuid_reg[eax], 3, 0); + info_p->cpuid_model = bitfield(cpuid_reg[eax], 7, 4); + info_p->cpuid_family = bitfield(cpuid_reg[eax], 11, 8); + info_p->cpuid_type = bitfield(cpuid_reg[eax], 13, 12); + info_p->cpuid_extmodel = bitfield(cpuid_reg[eax], 19, 16); + info_p->cpuid_extfamily = bitfield(cpuid_reg[eax], 27, 20); + info_p->cpuid_brand = bitfield(cpuid_reg[ebx], 7, 0); + info_p->cpuid_features = quad(cpuid_reg[ecx], cpuid_reg[edx]); + + /* Fold extensions into family/model */ + if (info_p->cpuid_family == 0x0f) { + info_p->cpuid_family += info_p->cpuid_extfamily; + } + if (info_p->cpuid_family == 0x0f || info_p->cpuid_family== 0x06) { + info_p->cpuid_model += (info_p->cpuid_extmodel << 4); + } + + if (info_p->cpuid_features & CPUID_FEATURE_HTT) { + info_p->cpuid_logical_per_package = bitfield(cpuid_reg[ebx], 23, 16); + } else { + info_p->cpuid_logical_per_package = 1; + } + + if (max_extid >= 0x80000001) { + do_cpuid(0x80000001, cpuid_reg); + info_p->cpuid_extfeatures = quad(cpuid_reg[ecx], cpuid_reg[edx]); + } + + if (info_p->cpuid_extfeatures & CPUID_FEATURE_MONITOR) { + + do_cpuid(5, cpuid_reg); + info_p->cpuid_mwait_linesize_min = cpuid_reg[eax]; + info_p->cpuid_mwait_linesize_max = cpuid_reg[ebx]; + info_p->cpuid_mwait_extensions = cpuid_reg[ecx]; + info_p->cpuid_mwait_sub_Cstates = cpuid_reg[edx]; + + do_cpuid(6, cpuid_reg); + info_p->cpuid_thermal_sensor = bitfield(cpuid_reg[eax], 0, 0); + info_p->cpuid_thermal_dynamic_acceleration = + bitfield(cpuid_reg[eax], 1, 1); + info_p->cpuid_thermal_thresholds = bitfield(cpuid_reg[ebx], 3, 0); + info_p->cpuid_thermal_ACNT_MCNT = bitfield(cpuid_reg[ecx], 0, 0); + + do_cpuid(0xa, cpuid_reg); + info_p->cpuid_arch_perf_version = bitfield(cpuid_reg[eax], 7, 0); + info_p->cpuid_arch_perf_number = bitfield(cpuid_reg[eax],15, 8); + info_p->cpuid_arch_perf_width = bitfield(cpuid_reg[eax],23,16); + info_p->cpuid_arch_perf_events_number = bitfield(cpuid_reg[eax],31,24); + info_p->cpuid_arch_perf_events = cpuid_reg[ebx]; + info_p->cpuid_arch_perf_fixed_number = bitfield(cpuid_reg[edx], 4, 0); + info_p->cpuid_arch_perf_fixed_width = bitfield(cpuid_reg[edx],12, 5); + + } + + do_cpuid(4, cpuid_reg); + info_p->cpuid_cores_per_package = bitfield(cpuid_reg[eax], 31, 26) + 1; + + if (info_p->cpuid_cores_per_package == 0) { + info_p->cpuid_cores_per_package = 1; + + } + + switch (info_p->cpuid_model) + { + case 0x1C: + { + //uint64_t msr = rdmsr64(MSR_CORE_THREAD_COUNT); + info_p->core_count = 1; //bitfield((uint32_t)msr, 19, 16); + info_p->thread_count = 2; //bitfield((uint32_t)msr, 15, 0); + } + break; + + case 0x1A: // Intel Core i7 LGA1366 (45nm) + case 0x1E: // Intel Core i5, i7 LGA1156 (45nm) + case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm) + { + uint64_t msr = rdmsr64(MSR_CORE_THREAD_COUNT); + info_p->core_count = bitfield((uint32_t)msr, 31, 16); + info_p->thread_count = bitfield((uint32_t)msr, 15, 0); + } break; + case 0x2C: // Intel Core i7 LGA1366 (32nm) 6 Core + case 0x1F: + case 0x2F: + { + uint64_t msr = rdmsr64(MSR_CORE_THREAD_COUNT); + info_p->core_count = bitfield((uint32_t)msr, 19, 16); + info_p->thread_count = bitfield((uint32_t)msr, 15, 0); + break; + } + + default: + { + do_cpuid(1, cpuid_reg); + info_p->core_count = bitfield(cpuid_reg[1], 23, 16); + } break; + } + if (info_p->core_count == 0) { + info_p->core_count = info_p->cpuid_cores_per_package; + info_p->thread_count = info_p->cpuid_logical_per_package; + } + +} + +#endif /*M_CPUID_H*/ Index: branches/slice/old749m/i386/libsaio/ntfs_private.h =================================================================== --- branches/slice/old749m/i386/libsaio/ntfs_private.h (revision 0) +++ branches/slice/old749m/i386/libsaio/ntfs_private.h (revision 1174) @@ -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/old749m/i386/libsaio/io_inline.h =================================================================== --- branches/slice/old749m/i386/libsaio/io_inline.h (revision 0) +++ branches/slice/old749m/i386/libsaio/io_inline.h (revision 1174) @@ -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/old749m/i386/libsaio/ext2fs.c =================================================================== --- branches/slice/old749m/i386/libsaio/ext2fs.c (revision 0) +++ branches/slice/old749m/i386/libsaio/ext2fs.c (revision 1174) @@ -0,0 +1,43 @@ +/* + * ext2fs.c + * + * + * Created by mackerintel on 1/26/09. + * Copyright 2009 __MyCompanyName__. All rights reserved. + * + */ +#ifndef OPTION_ROM +#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); +} +#endif \ No newline at end of file Index: branches/slice/old749m/i386/libsaio/hfs_CaseTables.h =================================================================== --- branches/slice/old749m/i386/libsaio/hfs_CaseTables.h (revision 0) +++ branches/slice/old749m/i386/libsaio/hfs_CaseTables.h (revision 1174) @@ -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/old749m/i386/libsaio/vbe.c =================================================================== --- branches/slice/old749m/i386/libsaio/vbe.c (revision 0) +++ branches/slice/old749m/i386/libsaio/vbe.c (revision 1174) @@ -0,0 +1,304 @@ +/* + * 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" + +/* + * 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); +} +#if UNUSED +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); +} +#endif + +int getEDID( void * edidBlock, UInt8 block) +{ + bzero(&bb, sizeof(bb)); + bb.intno = 0x10; + bb.eax.rr = funcGetEDID; + bb.ebx.r.l= 0x01; + bb.edx.rr = block; + + bb.es = SEG( edidBlock ); + bb.edi.rr = OFF( edidBlock ); + + 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 + */ +#if UNUSED +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; +} + +#endif + +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); +} + +#if UNUSED + +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); +} +#endif Index: branches/slice/old749m/i386/libsaio/bootstruct.h =================================================================== --- branches/slice/old749m/i386/libsaio/bootstruct.h (revision 0) +++ branches/slice/old749m/i386/libsaio/bootstruct.h (revision 1174) @@ -0,0 +1,142 @@ +/* + * 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 +#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 Node *gMemoryMapNode; +extern void *new_dsdt; + +#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 fo 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; // boot.plist + config_file_t overrideConfig; // additional boot.plist which can override bootConfig keys + config_file_t themeConfig; // theme.plist + config_file_t smbiosConfig; // smbios.plist + config_file_t helperConfig; // boot helper partition's boot.plist + config_file_t ramdiskConfig; // RAMDisk.plist +} PrivateBootInfo_t; + +extern PrivateBootInfo_t *bootInfo; + +#endif /* __BOOTSTRUCT_H */ Index: branches/slice/old749m/i386/libsaio/device_tree.c =================================================================== --- branches/slice/old749m/i386/libsaio/device_tree.c (revision 0) +++ branches/slice/old749m/i386/libsaio/device_tree.c (revision 1174) @@ -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'; + + verbose("%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 == '_')) { + verbose("%s Property '%s' [%d] = '%s'\n", spaces, prop->name, prop->length, prop->value); + } else { + verbose("%s Property '%s' [%d] = (data)\n", spaces, prop->name, prop->length); + } + } + verbose("%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'; + + verbose("%s===Entry %p===\n", spaces, entry); + if (kSuccess != DTCreatePropertyIterator(entry, &propIter)) { + verbose("Couldn't create property iterator\n"); + return; + } + while( kSuccess == DTIterateProperties( propIter, &name)) { + if( kSuccess != DTGetProperty( entry, name, &prop, &propSize )) + continue; + verbose("%s Property %s = %s\n", spaces, name, prop); + } + DTDisposePropertyIterator(propIter); + + verbose("%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"); + + verbose("In-memory tree:\n\n"); + + PrintTree(rootNode); + + FlattenDeviceTree(&flatTree, &flatSize); + + verbose("Flat tree = %p, size %d\n", flatTree, flatSize); + + dtEntry = (DTEntry)flatTree; + + verbose("\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/old749m/i386/libsaio/hfs.c =================================================================== --- branches/slice/old749m/i386/libsaio/hfs.c (revision 0) +++ branches/slice/old749m/i386/libsaio/hfs.c (revision 1174) @@ -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/old749m/i386/libsaio/ext2fs.h =================================================================== --- branches/slice/old749m/i386/libsaio/ext2fs.h (revision 0) +++ branches/slice/old749m/i386/libsaio/ext2fs.h (revision 1174) @@ -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/old749m/i386/libsaio/vbe.h =================================================================== --- branches/slice/old749m/i386/libsaio/vbe.h (revision 0) +++ branches/slice/old749m/i386/libsaio/vbe.h (revision 1174) @@ -0,0 +1,289 @@ +/* + * 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, + funcGetEDID = 0x4F15 + +}; + +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 getEDID( void * edidBlock, UInt8 block); +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/old749m/i386/libsaio/acpi_patcher.c =================================================================== --- branches/slice/old749m/i386/libsaio/acpi_patcher.c (revision 0) +++ branches/slice/old749m/i386/libsaio/acpi_patcher.c (revision 1174) @@ -0,0 +1,1289 @@ +/* + * Copyright 2008 mackerintel + */ + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "acpi.h" +#include "efi_tables.h" +#include "fake_efi.h" +#include "acpi_patcher.h" +#include "platform.h" +#include "cpu.h" +#include "aml_generator.h" +#include "smbios_patcher.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...) msglog(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 + + if(gSMBIOSBoardModel) + { + sprintf(dirSpec,"%s.%s", gSMBIOSBoardModel, filename); + fd = open(dirSpec, 0); + } + + if (fd < 0) + { + sprintf(dirSpec, "%s", filename); + fd = open(dirSpec, 0); + if (fd < 0) + { + if(gSMBIOSBoardModel) + { + sprintf(dirSpec, "/Extra/%s.%s", gSMBIOSBoardModel, filename); + fd = open(dirSpec, 0); + } + if (fd < 0) + { + sprintf(dirSpec, "/Extra/%s", filename); + fd = open(dirSpec, 0); + if (fd < 0) + { + if(gSMBIOSBoardModel) + { + sprintf(dirSpec, "bt(0,0)/Extra/%s.%s", gSMBIOSBoardModel, 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: + DBG("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]; + +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; + + DBG("Found ACPI CPU: %c%c%c%c\n", acpi_cpu_name[acpi_cpu_count][0], acpi_cpu_name[acpi_cpu_count][1], acpi_cpu_name[acpi_cpu_count][2], acpi_cpu_name[acpi_cpu_count][3]); + + if (++acpi_cpu_count == 32) return; + } + } + } +} + +struct acpi_2_ssdt *generate_cst_ssdt(struct acpi_2_fadt* fadt) +{ + char ssdt_header[] = + { + 0x53, 0x53, 0x44, 0x54, 0xE7, 0x00, 0x00, 0x00, /* SSDT.... */ + 0x01, 0x17, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x41, /* ..PmRefA */ + 0x43, 0x70, 0x75, 0x43, 0x73, 0x74, 0x00, 0x00, /* CpuCst.. */ + 0x00, 0x10, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* ....INTL */ + 0x31, 0x03, 0x10, 0x20 /* 1.._ */ + }; + + char cstate_resource_template[] = + { + 0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F, + 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x79, 0x00 + }; + + if (Platform->CPU.Vendor != 0x756E6547) { + verbose ("Not an Intel platform: C-States will not be generated !!!\n"); + return NULL; + } + + if (fadt == NULL) { + verbose ("FACP not exists: C-States will not be generated !!!\n"); + return NULL; + } + + struct acpi_2_dsdt* dsdt = (void*)fadt->DSDT; + + if (dsdt == NULL) { + verbose ("DSDT not found: C-States will not be generated !!!\n"); + return NULL; + } + + if (acpi_cpu_count == 0) + get_acpi_cpu_names((void*)dsdt, dsdt->Length); + + if (acpi_cpu_count > 0) + { + bool c2_enabled = false; + bool c3_enabled = false; + bool c4_enabled = false; + + getBoolForKey(kEnableC2States, &c2_enabled, &bootInfo->bootConfig); + getBoolForKey(kEnableC3States, &c3_enabled, &bootInfo->bootConfig); + getBoolForKey(kEnableC4States, &c4_enabled, &bootInfo->bootConfig); + + 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); + cstate_resource_template[11] = 0x00; // C1 + aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template)); + aml_add_byte(tmpl, 0x01); // C1 + aml_add_byte(tmpl, 0x01); // Latency + aml_add_word(tmpl, 0x03e8); // Power + + // C2 + if (c2_enabled) + { + tmpl = aml_add_package(pack); + cstate_resource_template[11] = 0x10; // C2 + aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template)); + aml_add_byte(tmpl, 0x02); // C2 + aml_add_byte(tmpl, fadt->C2_Latency); + aml_add_word(tmpl, 0x01f4); // Power + } + // C4 + if (c4_enabled) + { + tmpl = aml_add_package(pack); + cstate_resource_template[11] = 0x30; // C4 + aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template)); + aml_add_byte(tmpl, 0x04); // C4 + aml_add_word(tmpl, fadt->C3_Latency / 2); // TODO: right latency for C4 + aml_add_byte(tmpl, 0xfa); // Power + } + else + // C3 + if (c3_enabled) + { + tmpl = aml_add_package(pack); + cstate_resource_template[11] = 0x20; // C3 + aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template)); + aml_add_byte(tmpl, 0x03); // C3 + aml_add_word(tmpl, fadt->C3_Latency); + aml_add_word(tmpl, 0x015e); // Power + } + + + // Aliaces + int i; + for (i = 0; i < acpi_cpu_count; i++) + { + char name[9]; + sprintf(name, "_PR_%c%c%c%c", acpi_cpu_name[i][0], acpi_cpu_name[i][1], acpi_cpu_name[i][2], acpi_cpu_name[i][3]); + + scop = aml_add_scope(root, name); + aml_add_alias(scop, "CST_", "_CST"); + } + + aml_calculate_size(root); + + struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size); + + aml_write_node(root, (void*)ssdt, 0); + + ssdt->Length = root->Size; + ssdt->Checksum = 0; + ssdt->Checksum = 256 - checksum8(ssdt, ssdt->Length); + + aml_destroy_node(root); + + //dumpPhysAddr("C-States SSDT content: ", ssdt, ssdt->Length); + + verbose ("SSDT with CPU C-States generated successfully\n"); + + return ssdt; + } + else + { + verbose ("ACPI CPUs not found: C-States not generated !!!\n"); + } + + return NULL; +} + +struct acpi_2_ssdt *generate_pss_ssdt(struct acpi_2_dsdt* dsdt) +{ + char ssdt_header[] = + { + 0x53, 0x53, 0x44, 0x54, 0x7E, 0x00, 0x00, 0x00, /* SSDT.... */ + 0x01, 0x6A, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x00, /* ..PmRef. */ + 0x43, 0x70, 0x75, 0x50, 0x6D, 0x00, 0x00, 0x00, /* CpuPm... */ + 0x00, 0x30, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* .0..INTL */ + 0x31, 0x03, 0x10, 0x20, /* 1.._ */ + }; + 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: // Yonah + case CPU_MODEL_MEROM: // Merom + case CPU_MODEL_PENRYN: // Penryn + case CPU_MODEL_ATOM: // Intel Atom (45nm) + { + bool cpu_dynamic_fsb = false; + + if (rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 27)) + { + wrmsr64(MSR_IA32_EXT_CONFIG, (rdmsr64(MSR_IA32_EXT_CONFIG) | (1 << 28))); + delay(1); + cpu_dynamic_fsb = rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 28); + } + + bool cpu_noninteger_bus_ratio = (rdmsr64(MSR_IA32_PERF_STATUS) & (1ULL << 46)); + + initial.Control = rdmsr64(MSR_IA32_PERF_STATUS); + + maximum.Control = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 32) & 0x1F3F) | (0x4000 * cpu_noninteger_bus_ratio); + maximum.CID = ((maximum.FID & 0x1F) << 1) | cpu_noninteger_bus_ratio; + + minimum.FID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 24) & 0x1F) | (0x80 * cpu_dynamic_fsb); + minimum.VID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 48) & 0x3F); + + if (minimum.FID == 0) + { + uint64_t msr; + uint8_t i; + // Probe for lowest fid + for (i = maximum.FID; i >= 0x6; i--) + { + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (i << 8) | minimum.VID); + intel_waitforsts(); + minimum.FID = (rdmsr64(MSR_IA32_PERF_STATUS) >> 8) & 0x1F; + delay(1); + } + + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID); + intel_waitforsts(); + } + + if (minimum.VID == maximum.VID) + { + uint64_t msr; + uint8_t i; + // Probe for lowest vid + for (i = maximum.VID; i > 0xA; i--) + { + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (minimum.FID << 8) | i); + intel_waitforsts(); + minimum.VID = rdmsr64(MSR_IA32_PERF_STATUS) & 0x3F; + delay(1); + } + + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID); + intel_waitforsts(); + } + + minimum.CID = ((minimum.FID & 0x1F) << 1) >> cpu_dynamic_fsb; + + // Sanity check + if (maximum.CID < minimum.CID) + { + DBG("Insane FID values!"); + p_states_count = 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: + case CPU_MODEL_DALES: + case CPU_MODEL_DALES_32NM: + case CPU_MODEL_NEHALEM: + case CPU_MODEL_NEHALEM_EX: + case CPU_MODEL_WESTMERE: + case CPU_MODEL_WESTMERE_EX: + { + 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->bootConfig); + } 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->bootConfig))!=NULL) + { + if (Platform->Type > 6) + { + if(fadt_mod->PM_Profile<=6) + Platform->Type = fadt_mod->PM_Profile; // get the fadt if correct + else + Platform->Type = 1; /* Set a fixed value (Desktop) */ + verbose("Error: system-type must be 0..6. Defaulting to %d !\n", Platform->Type); + } + else + Platform->Type = (unsigned char) strtoul(value, NULL, 10); + } + // Set PM_Profile from System-type if only user wanted this value to be forced + if (fadt_mod->PM_Profile != Platform->Type) + { + if (value) + { // user has overriden the SystemType so take care of it in FACP + 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); + + // Insert old dsdt into the IORegistery + Node* node = DT__FindNode("/dsdt", false); + if(node == NULL) + { + // Only add if not already here + Node* node = DT__FindNode("/", false); + + if(node != NULL) + { + node = DT__AddChild(node, "dsdt"); + + struct acpi_2_dsdt *dsdt; + dsdt = (struct acpi_2_dsdt*) (fadt_mod->DSDT); + DT__AddProperty(node, "originaldsdt", (dsdt->Length + sizeof(struct acpi_2_dsdt) - 1), (void*)dsdt); /// Insert old dsdt. Length is header length (36) + dsdt length + + } + } + + 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->bootConfig)) + { + sprintf(dirSpec, filename); + } + else + { + sprintf(dirSpec, "DSDT.aml"); + } + + // Load replacement DSDT + new_dsdt = loadACPITable(dirSpec); + if(!new_dsdt) + { + sprintf(dirSpec, "DSDT.%s.aml", gSMBIOSBoardModel); + new_dsdt = loadACPITable(dirSpec); + } + + // Mozodojo: going to patch FACP and load SSDT's even if DSDT.aml is not present + /*if (!new_dsdt) + { + return setupAcpiNoMod(); + }*/ + + // Mozodojo: Load additional SSDTs + struct acpi_2_ssdt *new_ssdt[32]; // 30 + 2 additional tables for pss & cst + int ssdt_count=0; + + // SSDT Options + bool drop_ssdt=false, generate_pstates=false, generate_cstates=false; + + getBoolForKey(kDropSSDT, &drop_ssdt, &bootInfo->bootConfig); + getBoolForKey(kGeneratePStates, &generate_pstates, &bootInfo->bootConfig); + getBoolForKey(kGenerateCStates, &generate_cstates, &bootInfo->bootConfig); + + { + int i; + + for (i=0; i<30; i++) + { + char filename[512]; + + sprintf(filename, i>0?"SSDT-%d.aml":"SSDT.aml", i); + + if(new_ssdt[ssdt_count] = loadACPITable(filename)) + { + ssdt_count++; + } + else + { + break; + } + } + } + + // Do the same procedure for both versions of ACPI + for (version=0; version<2; version++) { +// 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; + } + DBG("Old DSDT @%x, X_DSDT %x from FADT\n",fadt->DSDT,fadt->X_DSDT); + + 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"); + getc(); +#endif + return 1; +} Index: branches/slice/old749m/i386/libsaio/device_tree.h =================================================================== --- branches/slice/old749m/i386/libsaio/device_tree.h (revision 0) +++ branches/slice/old749m/i386/libsaio/device_tree.h (revision 1174) @@ -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/old749m/i386/libsaio/allocate.c =================================================================== --- branches/slice/old749m/i386/libsaio/allocate.c (revision 0) +++ branches/slice/old749m/i386/libsaio/allocate.c (revision 1174) @@ -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/old749m/i386/libsaio/hfs.h =================================================================== --- branches/slice/old749m/i386/libsaio/hfs.h (revision 0) +++ branches/slice/old749m/i386/libsaio/hfs.h (revision 1174) @@ -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/old749m/i386/libsaio/hfs_compare.c =================================================================== --- branches/slice/old749m/i386/libsaio/hfs_compare.c (revision 0) +++ branches/slice/old749m/i386/libsaio/hfs_compare.c (revision 1174) @@ -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/old749m/i386/libsaio/libsaio.h =================================================================== --- branches/slice/old749m/i386/libsaio/libsaio.h (revision 0) +++ branches/slice/old749m/i386/libsaio/libsaio.h (revision 1174) @@ -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/old749m/i386/libsaio/acpi_patcher.h =================================================================== --- branches/slice/old749m/i386/libsaio/acpi_patcher.h (revision 0) +++ branches/slice/old749m/i386/libsaio/acpi_patcher.h (revision 1174) @@ -0,0 +1,39 @@ +/* + * Copyright 2008 mackerintel + */ + +#ifndef __LIBSAIO_ACPI_PATCHER_H +#define __LIBSAIO_ACPI_PATCHER_H + +#include "libsaio.h" +#include "efi.h" +//#include "ACPIPatcher.h" + +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/old749m/i386/libsaio/Makefile =================================================================== --- branches/slice/old749m/i386/libsaio/Makefile (revision 0) +++ branches/slice/old749m/i386/libsaio/Makefile (revision 1174) @@ -0,0 +1,97 @@ + +DIR = libsaio +include ../MakePaths.dir + +UTILDIR = ../util +LIBSADIR = ../libsa +BOOT2DIR = ../boot2 +INSTALLDIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/standalone +#SYMROOT= + +OPTIM = -Os -Oz +DEBUG = -DNOTHING +#DEBUG = -DDEBUG_CPU=1 -DDEBUG_MEM=1 -DDEBUG_SPD=1 -DDEBUG_PCI=1 -DDEBUG_SMBIOS=1 +CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost \ + -D__ARCHITECTURE__=\"i386\" -DSAIO_INTERNAL_USER \ + -DRCZ_COMPRESSED_FILE_SUPPORT $(DEBUG) \ + -fno-builtin -static $(OMIT_FRAME_POINTER_CFLAG) \ + -mpreferred-stack-boundary=2 -fno-align-functions -fno-stack-protector \ + -march=pentium4 -msse2 -mfpmath=sse -msoft-float + +DEFINES= +CONFIG = hd +INC = -I. -I$(SYMROOT) -I$(UTILDIR) -I$(LIBSADIR) -I$(BOOT2DIR) +ifneq "" "$(wildcard /bin/mkdirs)" + MKDIRS = /bin/mkdirs +else + MKDIRS = /bin/mkdir -p +endif +AS = as +LD = ld +# LIBS= -lc_static +LIBS= + +VPATH = $(OBJROOT):$(SYMROOT) + +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 \ + ufs.o ufs_byteorder.o \ + vbe.o nbp.o smbios_patcher.o hfs.o hfs_compare.o \ + xml.o ntfs.o msdos.o md5c.o device_tree.o \ + cpu.o platform.o acpi_patcher.o aml_generator.o \ + fake_efi.o ext2fs.o \ + pci_setup.o \ + device_inject.o pci_root.o \ + convert.o + + +SAIO_EXTERN_OBJS = console.o + +SFILES = +CFILES = +HFILES = +EXPORTED_HFILES = +INSTALLED_HFILES = +OTHERFILES = Makefile +ALLSRC = $(SFILES) $(CFILES) \ + $(HFILES) $(OTHERFILES) +LIBS = libsaio.a +DIRS_NEEDED = $(OBJROOT) $(SYMROOT) +#GENFILES = $(SYMROOT)/saio_internal.h \ +# $(SYMROOT)/saio_external.h \ +# $(SYMROOT)/saio_defs.h \ +# $(SYMROOT)/saio_table.c + +#SIG = $(SYMROOT)/sig + +optionrom: CFLAGS += -DOPTION_ROM + +all embedtheme optionrom: $(DIRS_NEEDED) libsaio.h $(LIBS) + +#libsaio_static.a: $(SAIO_OBJS) +# rm -f $(SYMROOT)/$@ +# ar q $(SYMROOT)/$@ $(SAIO_OBJS) +# ranlib $(SYMROOT)/$@ + +libsaio.a: $(SAIO_EXTERN_OBJS) $(SAIO_OBJS) + @echo "\t[RM] $(SYMROOT)/$(@F)" + @rm -f $(SYMROOT)/$(@F) + @echo "\t[AR] $@" + @ar q $(SYMROOT)/$(@F) $^ &> /dev/null + @echo "\t[RANLIB] $@" + @ranlib $(SYMROOT)/$(@F) + +#saio_internal.h: saio_external.h +#saio_table.c: saio_external.h +#saio_defs.h: saio_external.h +#saio_external.h: saio.def +# $(SIG) -d $(SYMROOT) -n saio saio.def + +#installhdrs:: $(INSTALLDIR) +# cp $(INSTALLED_HFILES) $(INSTALLDIR) + +include ../MakeInc.dir + +# dependencies +-include $(OBJROOT)/Makedep Index: branches/slice/old749m/i386/libsaio/ufs.c =================================================================== --- branches/slice/old749m/i386/libsaio/ufs.c (revision 0) +++ branches/slice/old749m/i386/libsaio/ufs.c (revision 1174) @@ -0,0 +1,534 @@ +/* + * 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@ + */ +/* + * ufs.c - File System Module for UFS. + * + * Copyright (c) 1998-2002 Apple Computer, Inc. + * + * DRI: Josh de Cesare + */ +#include + +#include "ufs.h" +#include "ufs_byteorder.h" + +#if !defined(MAXNAMLEN) && defined(UFSMAXNAMLEN) +#define MAXNAMLEN UFSMAXNAMLEN +#endif + +typedef struct dinode Inode, *InodePtr; + +// Private function prototypes + +static char *ReadBlock(long fragNum, long fragOffset, long length, + char *buffer, long cache); +static long ReadInode(long inodeNum, InodePtr inode, long *flags, long *time); +static long ResolvePathToInode(char *filePath, long *flags, + InodePtr fileInode, InodePtr dirInode); +static long ReadDirEntry(InodePtr dirInode, long *fileInodeNum, + long long *dirIndex, char **name); +static long FindFileInDir(char *fileName, long *flags, + InodePtr fileInode, InodePtr dirInode); +static char *ReadFileBlock(InodePtr fileInode, long fragNum, long blockOffset, + long length, char *buffer, long cache); +static long ReadFile(InodePtr fileInode, uint64_t *length, void *base, uint64_t offset); + +#define kDevBlockSize (0x200) // Size of each disk block. +#define kDiskLabelBlock (15) // Block the DL is in. + +#ifdef __i386__ + +static CICell gCurrentIH; +static long long gPartitionBase; +static char *gULBuf; +static char *gFSBuf; +static struct fs *gFS; +#if !BOOT1 +static struct ufslabel gUFSLabel; // for UUID +#endif +static long gBlockSize; +static long gFragSize; +static long gFragsPerBlock; +static char *gTempBlock; +static char *gTempName; +static char *gTempName2; +static InodePtr gRootInodePtr; +static InodePtr gFileInodePtr; + +#else /* !__i386__ */ + +static CICell gCurrentIH; +static long long gPartitionBase; +static char gDLBuf[8192]; +static char gFSBuf[SBSIZE]; +static struct fs *gFS; +#if !BOOT1 +static struct ufslabel gUFSLabel; // for UUID +#endif +static long gBlockSize; +static long gFragSize; +static long gFragsPerBlock; +static char *gTempBlock; +static char gTempName[MAXNAMLEN + 1]; +static char gTempName2[MAXNAMLEN + 1]; +static Inode _gRootInode; +static Inode _gFileInode; +static InodePtr gRootInodePtr = &_gRootInode; +static InodePtr gFileInodePtr = &_gFileInode; + +#endif /* !__i386__ */ + +// Public functions + +void UFSFree(CICell ih) +{ + if(gCurrentIH == ih) + gCurrentIH = 0; + free(ih); +} + +long UFSInitPartition( CICell ih ) +{ +#if !BOOT1 + long ret; +#endif + + if (ih == gCurrentIH) { +#ifdef __i386__ + CacheInit(ih, gBlockSize); +#endif + return 0; + } + +#if !BOOT1 + verbose("UFSInitPartition: %x\n", ih); +#endif + + gCurrentIH = 0; + +#ifdef __i386__ + if (!gULBuf) gULBuf = (char *) malloc(UFS_LABEL_SIZE); + if (!gFSBuf) gFSBuf = (char *) malloc(SBSIZE); + if (!gTempName) gTempName = (char *) malloc(MAXNAMLEN + 1); + if (!gTempName2) gTempName2 = (char *) malloc(MAXNAMLEN + 1); + if (!gRootInodePtr) gRootInodePtr = (InodePtr) malloc(sizeof(Inode)); + if (!gFileInodePtr) gFileInodePtr = (InodePtr) malloc(sizeof(Inode)); + if (!gULBuf || !gFSBuf || !gTempName || !gTempName2 || + !gRootInodePtr || !gFileInodePtr) return -1; +#endif + + // Assume there is no Disk Label + gPartitionBase = 0; + +#if !BOOT1 + // read the disk label to get the UUID + // (rumor has it that UFS headers can be either-endian on disk; hopefully + // that isn't true for this UUID field). + Seek(ih, gPartitionBase + UFS_LABEL_OFFSET); + ret = Read(ih, (long)&gUFSLabel, UFS_LABEL_SIZE); + if(ret != 0) + bzero(&gUFSLabel, UFS_LABEL_SIZE); +#endif /* !BOOT1 */ + + // Look for the Super Block + Seek(ih, gPartitionBase + SBOFF); + Read(ih, (long)gFSBuf, SBSIZE); + + gFS = (struct fs *)gFSBuf; + byte_swap_superblock(gFS); + + if (gFS->fs_magic != FS_MAGIC) { + return -1; + } + + ih->modTime = gFS->fs_time; + + // Calculate the block size and set up the block cache. + gBlockSize = gFS->fs_bsize; + gFragSize = gFS->fs_fsize; + gFragsPerBlock = gBlockSize / gFragSize; + if (gTempBlock != 0) free(gTempBlock); + gTempBlock = malloc(gBlockSize); + CacheInit(ih, gBlockSize); + + gCurrentIH = ih; + + // Read the Root Inode + ReadInode(ROOTINO, gRootInodePtr, 0, 0); + + return 0; +} + +#if !BOOT1 + +long UFSGetUUID(CICell ih, char *uuidStr) +{ + long long uuid = gUFSLabel.ul_uuid; + + if (UFSInitPartition(ih) == -1) return -1; + if (uuid == 0LL) return -1; + + return CreateUUIDString((uint8_t*)(&uuid), sizeof(uuid), uuidStr); +} + +#endif /* !BOOT1 */ + +long UFSLoadFile( CICell ih, char * filePath ) +{ + return UFSReadFile(ih, filePath, (void *)gFSLoadAddress, 0, 0); +} + +long UFSReadFile( CICell ih, char * filePath, void * base, uint64_t offset, uint64_t length ) +{ + long ret, flags; + +#if !BOOT1 + verbose("Loading UFS file: [%s] from %x.\n", filePath, (unsigned)ih); +#endif + + if (UFSInitPartition(ih) == -1) return -1; + + // Skip one or two leading '/'. + if (*filePath == '/') filePath++; + if (*filePath == '/') filePath++; + + ret = ResolvePathToInode(filePath, &flags, gFileInodePtr, gRootInodePtr); + if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) return -1; + + ret = ReadFile(gFileInodePtr, &length, base, offset); + if (ret == -1) return -1; + + return length; +} + +#ifndef BOOT1 + +long UFSGetDirEntry( CICell ih, char * dirPath, long long * dirIndex, + char ** name, long * flags, long * time, + FinderInfo * finderInfo, long * infoValid) +{ + long ret, fileInodeNum, dirFlags; + Inode tmpInode; + + if (UFSInitPartition(ih) == -1) return -1; + + if (infoValid) *infoValid = 0; + + // Skip a leading '/' if present + if (*dirPath == '/') dirPath++; + if (*dirPath == '/') dirPath++; + + ret = ResolvePathToInode(dirPath, &dirFlags, gFileInodePtr, gRootInodePtr); + if ((ret == -1) || ((dirFlags & kFileTypeMask) != kFileTypeDirectory)) + return -1; + + ret = ReadDirEntry(gFileInodePtr, &fileInodeNum, dirIndex, name); + if (ret != 0) return ret; + + ReadInode(fileInodeNum, &tmpInode, flags, time); + + return 0; +} + +void +UFSGetDescription(CICell ih, char *str, long strMaxLen) +{ + if (UFSInitPartition(ih) == -1) { return; } + + struct ufslabel *ul; + + // Look for the Disk Label + Seek(ih, 1ULL * UFS_LABEL_OFFSET); + Read(ih, (long)gULBuf, UFS_LABEL_SIZE); + + ul = (struct ufslabel *)gULBuf; + + unsigned char magic_bytes[] = UFS_LABEL_MAGIC; + int i; + unsigned char *p = (unsigned char *)&ul->ul_magic; + + for (i=0; iul_name, strMaxLen); +} + +long +UFSGetFileBlock(CICell ih, char *filePath, unsigned long long *firstBlock) +{ + long ret, flags; + + if (UFSInitPartition(ih) == -1) return -1; + + // Skip one or two leading '/'. + if (*filePath == '/') filePath++; + if (*filePath == '/') filePath++; + + ret = ResolvePathToInode(filePath, &flags, gFileInodePtr, gRootInodePtr); + if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) return -1; + + *firstBlock = (gPartitionBase + 1ULL * gFileInodePtr->di_db[0] * gBlockSize) / 512ULL; + + return 0; +} + + +#endif /* !BOOT1 */ + +// Private functions + +static char * ReadBlock( long fragNum, long blockOffset, long length, + char * buffer, long cache ) +{ + long long offset; + long blockNum; + + blockNum = fragNum / gFragsPerBlock; + fragNum -= blockNum * gFragsPerBlock; + + blockOffset += fragNum * gFragSize; + + offset = gPartitionBase + 1ULL * blockNum * gBlockSize; + + if (cache && ((blockOffset + length) <= gBlockSize)) { + CacheRead(gCurrentIH, gTempBlock, offset, gBlockSize, 1); + if (buffer != 0) bcopy(gTempBlock + blockOffset, buffer, length); + else buffer = gTempBlock + blockOffset; + } else { + offset += blockOffset; + CacheRead(gCurrentIH, buffer, offset, length, 0); + } + + return buffer; +} + +static long ReadInode( long inodeNum, InodePtr inode, long * flags, long * time ) +{ + long fragNum = ino_to_fsba(gFS, inodeNum); + long blockOffset = ino_to_fsbo(gFS, inodeNum) * sizeof(Inode); + + ReadBlock(fragNum, blockOffset, sizeof(Inode), (char *)inode, 1); + byte_swap_dinode_in(inode); + + if (time != 0) *time = inode->di_mtime; + + if (flags != 0) { + switch (inode->di_mode & IFMT) { + case IFREG: *flags = kFileTypeFlat; break; + case IFDIR: *flags = kFileTypeDirectory; break; + case IFLNK: *flags = kFileTypeLink; break; + default : *flags = kFileTypeUnknown; break; + } + + *flags |= inode->di_mode & kPermMask; + + if (inode->di_uid != 0) *flags |= kOwnerNotRoot; + } + + return 0; +} + +static long ResolvePathToInode( char * filePath, long * flags, + InodePtr fileInode, InodePtr dirInode ) +{ + char * restPath; + long ret, cnt; + + // if filePath is empty the we want this directory. + if (*filePath == '\0') { + bcopy((char *)dirInode, (char *)fileInode, sizeof(Inode)); + return 0; + } + + // Copy the file name to gTempName + cnt = 0; + while ((filePath[cnt] != '/') && (filePath[cnt] != '\0')) cnt++; + strlcpy(gTempName, filePath, cnt+1); + + // Move restPath to the right place. + if (filePath[cnt] != '\0') cnt++; + restPath = filePath + cnt; + + // gTempName is a name in the current Dir. + // restPath is the rest of the path if any. + + ret = FindFileInDir(gTempName, flags, fileInode, dirInode); + if (ret == -1) return -1; + + if ((*restPath != '\0') && ((*flags & kFileTypeMask) == kFileTypeDirectory)) + ret = ResolvePathToInode(restPath, flags, fileInode, fileInode); + + return ret; +} + +static long ReadDirEntry( InodePtr dirInode, long * fileInodeNum, + long long * dirIndex, char ** name ) +{ + struct direct *dir; + char *buffer; + long long index; + long dirBlockNum, dirBlockOffset; + + while (1) { + index = *dirIndex; + + dirBlockOffset = (long) (index % DIRBLKSIZ); + dirBlockNum = (long) (index / DIRBLKSIZ); + + buffer = ReadFileBlock(dirInode, dirBlockNum, 0, DIRBLKSIZ, 0, 1); + if (buffer == 0) return -1; + + dir = (struct direct *)(buffer + dirBlockOffset); + byte_swap_dir_block_in((char *)dir, 1); + + *dirIndex += dir->d_reclen; + + if (dir->d_ino != 0) break; + + if (dirBlockOffset != 0) return -1; + } + + *fileInodeNum = dir->d_ino; + *name = strlcpy(gTempName2, dir->d_name, dir->d_namlen+1); + + return 0; +} + +static long FindFileInDir( char * fileName, long * flags, + InodePtr fileInode, InodePtr dirInode ) +{ + long ret, inodeNum; + long long index = 0; + char *name; + + while (1) { + ret = ReadDirEntry(dirInode, &inodeNum, &index, &name); + if (ret == -1) return -1; + + if (strcmp(fileName, name) == 0) break; + } + + ReadInode(inodeNum, fileInode, flags, 0); + + return 0; +} + +static char * ReadFileBlock( InodePtr fileInode, long fragNum, long blockOffset, + long length, char * buffer, long cache ) +{ + long fragCount, blockNum; + long diskFragNum, indFragNum, indBlockOff, refsPerBlock; + char *indBlock; + + fragCount = (fileInode->di_size + gFragSize - 1) / gFragSize; + if (fragNum >= fragCount) return 0; + + refsPerBlock = gBlockSize / sizeof(ufs_daddr_t); + + blockNum = fragNum / gFragsPerBlock; + fragNum -= blockNum * gFragsPerBlock; + + // Get Direct Block Number. + if (blockNum < NDADDR) { + diskFragNum = fileInode->di_db[blockNum]; + } else { + blockNum -= NDADDR; + + // Get Single Indirect Fragment Number. + if (blockNum < refsPerBlock) { + indFragNum = fileInode->di_ib[0]; + } else { + blockNum -= refsPerBlock; + + // Get Double Indirect Fragment Number. + if (blockNum < (refsPerBlock * refsPerBlock)) { + indFragNum = fileInode->di_ib[1]; + } else { + blockNum -= refsPerBlock * refsPerBlock; + + // Get Triple Indirect Fragment Number. + indFragNum = fileInode->di_ib[2]; + + indBlock = ReadBlock(indFragNum, 0, gBlockSize, 0, 1); + indBlockOff = blockNum / (refsPerBlock * refsPerBlock); + blockNum %= (refsPerBlock * refsPerBlock); + indFragNum = SWAP_BE32(((ufs_daddr_t *)indBlock)[indBlockOff]); + } + + indBlock = ReadBlock(indFragNum, 0, gBlockSize, 0, 1); + indBlockOff = blockNum / refsPerBlock; + blockNum %= refsPerBlock; + indFragNum = SWAP_BE32(((ufs_daddr_t *)indBlock)[indBlockOff]); + } + + indBlock = ReadBlock(indFragNum, 0, gBlockSize, 0, 1); + diskFragNum = SWAP_BE32(((ufs_daddr_t *)indBlock)[blockNum]); + } + + buffer = ReadBlock(diskFragNum+fragNum, blockOffset, length, buffer, cache); + + return buffer; +} + +static long ReadFile( InodePtr fileInode, uint64_t * length, void * base, uint64_t offset ) +{ + long bytesLeft, curSize, curFrag; + char *buffer, *curAddr = (char *)base; + + bytesLeft = fileInode->di_size; + + if (offset > bytesLeft) { + printf("Offset is too large.\n"); + return -1; + } + + if ((*length == 0) || ((offset + *length) > bytesLeft)) { + *length = bytesLeft - offset; + } +/* + if (bytesLeft > kLoadSize) { + printf("File is too large.\n"); + return -1; + } +*/ + bytesLeft = *length; + curFrag = (offset / gBlockSize) * gFragsPerBlock; + offset %= gBlockSize; + + while (bytesLeft) { + curSize = gBlockSize; + if (curSize > bytesLeft) curSize = bytesLeft; + if ((offset + curSize) > gBlockSize) curSize = (gBlockSize - offset); + + buffer = ReadFileBlock(fileInode, curFrag, offset, curSize, curAddr, 0); + if (buffer == 0) break; + + if (offset != 0) offset = 0; + + curFrag += gFragsPerBlock; + curAddr += curSize; + bytesLeft -= curSize; + } + + return bytesLeft; +} \ No newline at end of file Index: branches/slice/old749m/i386/libsaio/bios.h =================================================================== --- branches/slice/old749m/i386/libsaio/bios.h (revision 0) +++ branches/slice/old749m/i386/libsaio/bios.h (revision 1174) @@ -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 + +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/old749m/i386/libsaio/SMBIOS.h =================================================================== --- branches/slice/old749m/i386/libsaio/SMBIOS.h (revision 0) +++ branches/slice/old749m/i386/libsaio/SMBIOS.h (revision 1174) @@ -0,0 +1,451 @@ +/* + * Copyright (c) 1998-2006 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@ + */ + +/* This file is a stripped-down version of the one found in the AppleSMBIOS project. + * Changes: + * - Don't use pragma pack but instead use GCC's packed attribute + */ + +#ifndef _LIBSAIO_SMBIOS_H +#define _LIBSAIO_SMBIOS_H + +/* + * Based on System Management BIOS Reference Specification v2.5, //Slice - 2.7.0 + */ + +typedef uint8_t SMBString; +typedef uint8_t SMBByte; +typedef uint16_t SMBWord; +typedef uint32_t SMBDWord; +typedef uint64_t SMBQWord; + +// Apple known 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, + + // Apple Specific Structures + kSMBTypeFirmwareVolume = 128, + kSMBTypeMemorySPD = 130, + kSMBTypeOemProcessorType = 131, + kSMBTypeOemProcessorBusSpeed = 132 + }; + + +struct DMIHeader { + SMBByte type; + SMBByte length; + SMBWord handle; +} __attribute__((packed)); +typedef struct DMIHeader DMIHeader; + +#define SMB_STRUCT_HEADER struct DMIHeader dmiHeader; + +struct DMIEntryPoint { + SMBByte anchor[5]; + SMBByte checksum; + SMBWord tableLength; + SMBDWord tableAddress; + SMBWord structureCount; + SMBByte bcdRevision; +} __attribute__((packed)); +typedef struct DMIEntryPoint DMIEntryPoint; + +struct SMBEntryPoint { + SMBByte anchor[4]; + SMBByte checksum; + SMBByte entryPointLength; + SMBByte majorVersion; + SMBByte minorVersion; + SMBWord maxStructureSize; + SMBByte entryPointRevision; + SMBByte formattedArea[5]; + struct DMIEntryPoint dmi; +} __attribute__((packed)); +typedef struct SMBEntryPoint SMBEntryPoint; + + +// +// BIOS Information (Type 0) //min len 18+num_of_extChars. Max=18h=24 +// +struct SMBBIOSInformation { + struct DMIHeader dmiHeader; // 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 +}; + +//BIOS Characteristics Extension Bits +/* + Characteristics Ext1 0x87 + Bit0 ACPI supported - 1 (Yes) + Bit1 USB Legacy is supported - 1 (Yes) + Bit2 AGP is supported - 1 (Yes) + Bit3 I2O boot is supported - 0 (No) + Bit4 LS-120 boot is supported - 0 (No) + Bit5 ATAPI ZIP Drive boot is supported - 0 (No) + Bit6 1394 boot is supported - 0 (No) + Bit7 Smart Battery supported - 1 (Yes) + Characteristics Ext2 0x07 + Bit0 BIOS Boot Specification supported - 1 (Yes) + Bit1 Function key-initiated Network Service boot supported - 1 (Yes) + Bit2 Enable Targeted Content Distribution - 1 (Yes) + + Bit 0 BIOS Boot Specification is supported. + Bit 1 Function key-initiated Network Service boot is supported. When function key-uninitiated Network Service Boot is not supported, a network adapter option ROM may choose to offer this functionality on its own, thus offering this capability to legacy systems. When the function is supported, the network adapter option ROM shall not offer this capability. + Bit 2 Enable Targeted Content Distribution. The manufacturer has ensured that the SMBIOS data is useful in identifying the computer for targeted delivery of model-specific software and firmware content through third-party content distribution services. + Bit 3 UEFI Specification is supported. + Bit 4 The SMBIOS table describes a virtual machine. (If this bit is not set, no inference can be made about the virtuality of the system.) + + Bits 5:7 Reserved for future assignment by this specification + */ + +// +// System Information (Type 1) +// + +struct DMISystemInformation { + // 2.0+ spec (8 bytes) + struct DMIHeader dmiHeader; // 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 + SMBString SKUNumber; // purchase order number +}; +typedef struct DMISystemInformation DMISystemInformation; +// +// Base Board (Type 2) +// + +struct DMIBaseBoard { + struct DMIHeader dmiHeader; // 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. +}; +typedef struct DMIBaseBoard DMIBaseBoard; +// 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) +// + +struct DMISystemEnclosure { + struct DMIHeader dmiHeader; // Type 3 len=13 + SMBString manufacturer; + SMBByte type; + SMBString version; + SMBString serialNumber; + SMBString assetTagNumber; + SMBByte bootupState; + SMBByte powerSupplyState; + SMBByte thermalState; + SMBByte securityStatus; + SMBDWord oemDefined; +}; +typedef struct DMISystemEnclosure DMISystemEnclosure; +// +// Processor Information (Type 4) +// + +struct DMIProcessorInformation { + // 2.0+ spec (26 bytes) + struct DMIHeader dmiHeader; // 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)); + +#define kSMBProcessorInformationMinSize 26 + + + + +struct DMIMemoryControllerInfo {/* 3.3.6 Memory Controller Information (Type 5) */ + struct DMIHeader dmiHeader; + SMBByte errorDetectingMethod; + SMBByte errorCorrectingCapability; + SMBByte supportedInterleave; + SMBByte currentInterleave; + SMBByte maxMemoryModuleSize; + SMBWord supportedSpeeds; + SMBWord supportedMemoryTypes; + SMBByte memoryModuleVoltage; + SMBByte numberOfMemorySlots; +} __attribute__((packed)); +typedef struct DMIMemoryControllerInfo DMIMemoryControllerInfo; + +struct DMIMemoryModuleInfo { /* 3.3.7 Memory Module Information (Type 6) */ + struct DMIHeader dmiHeader; + SMBByte socketDesignation; + SMBByte bankConnections; + SMBByte currentSpeed; + SMBWord currentMemoryType; + SMBByte installedSize; + SMBByte enabledSize; + SMBByte errorStatus; +} __attribute__((packed)); +typedef struct DMIMemoryModuleInfo DMIMemoryModuleInfo; + + +#define kSMBMemoryModuleSizeNotDeterminable 0x7D +#define kSMBMemoryModuleSizeNotEnabled 0x7E +#define kSMBMemoryModuleSizeNotInstalled 0x7F + +// +// Cache Information (Type 7) +// + +struct DMICacheInformation { + 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)); + +struct DMISystemSlot { + // 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)); + + + +struct DMIPhysicalMemoryArray { /* 3.3.17 Physical Memory Array (Type 16) */ + struct DMIHeader dmiHeader; + SMBByte location; + SMBByte use; + SMBByte memoryCorrectionError; + SMBDWord maximumCapacity; + SMBWord memoryErrorInformationHandle; + SMBWord numberOfMemoryDevices; +} __attribute__((packed)); +typedef struct DMIPhysicalMemoryArray DMIPhysicalMemoryArray; + +struct DMIMemoryDevice { /* 3.3.18 Memory Device (Type 17) */ + struct DMIHeader dmiHeader; + SMBWord physicalMemoryArrayHandle; + SMBWord memoryErrorInformationHandle; + SMBWord totalWidth; + SMBWord dataWidth; + SMBWord size; + SMBByte formFactor; + SMBByte deviceSet; + SMBByte deviceLocator; + SMBByte bankLocator; + SMBByte memoryType; + SMBWord typeDetail; + // 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)); +typedef struct DMIMemoryDevice DMIMemoryDevice; + +//Apple specific fields +// +// 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 +}; + + +struct SMBStructHeader { + SMBByte type; + SMBByte length; + SMBWord handle; +}; + +typedef struct SMBStructHeader SMBStructHeader; + +struct FW_REGION_INFO +{ + SMBDWord StartAddress; + SMBDWord EndAddress; +}; + + +struct DMIFirmwareVolume { + struct DMIHeader dmiHeader; // Type 128 + SMBByte RegionCount; + SMBByte Reserved[3]; + SMBDWord FirmwareFeatures; + SMBDWord FirmwareFeaturesMask; + SMBByte RegionType[ NUM_FLASHMAP_ENTRIES ]; + struct FW_REGION_INFO FlashMap[ NUM_FLASHMAP_ENTRIES ]; +} __attribute__((packed)); + +// +// Memory SPD Data (Apple Specific - Type 130) +// + +struct DMIMemorySPD { + struct DMIHeader dmiHeader; // Type 130 + SMBWord Type17Handle; + SMBWord Offset; + SMBWord Size; + SMBWord Data[]; +} __attribute__((packed)); + +// +// OEM Processor Type (Apple Specific - Type 131) +// + +struct DMIOemProcessorType { + SMB_STRUCT_HEADER + SMBWord ProcessorType; +} __attribute__((packed)); + +// +// OEM Processor Bus Speed (Apple Specific - Type 132) +// +struct DMIOemProcessorBusSpeed { + SMB_STRUCT_HEADER + SMBWord ProcessorBusSpeed; // MT/s unit +} __attribute__((packed)); + + +#if UNUSED +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] */ +}; +#endif + +#endif /* !_LIBSAIO_SMBIOS_H */ Index: branches/slice/old749m/i386/libsaio/smbios_patcher.c =================================================================== --- branches/slice/old749m/i386/libsaio/smbios_patcher.c (revision 0) +++ branches/slice/old749m/i386/libsaio/smbios_patcher.c (revision 1174) @@ -0,0 +1,1327 @@ +/* + * Copyright 2008 mackerintel + */ + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "acpi.h" +#include "convert.h" +#include "efi_tables.h" +#include "fake_efi.h" +#include "platform.h" +#include "smbios_patcher.h" +#include "SMBIOS.h" +#include "pci.h" + +#ifndef DEBUG_SMBIOS +#define DEBUG_SMBIOS 0 +#endif + +#if DEBUG_SMBIOS +#define DBG(x...) verbose(x) +#else +#define DBG(x...) +#endif +//Slice - for ACPI patcher templates +int ModelLength = 0; +char MacModel[8] = "MacBook"; +unsigned int ModelRev = 0x00010001; +uint64_t smbios_p; + +char* gSMBIOSBoardModel; + +typedef struct { + const char* key; + const char* value; +} SMStrEntryPair; +//Slice - TODO must be unique UUID for each model? +/* Random values +19422392-C343-4A3A-92A3-AB1F0A6C3E52 +E3314823-659D-42B6-B42C-147E4E3484D4 +C3D73A74-809A-4804-A747-DDB934A737D0 +*/ +// defaults for a MacBook +static const SMStrEntryPair const sm_macbook_defaults[]={ + {"SMbiosvendor", "Apple Inc." }, + {"SMbiosversion", "MB41.88Z.0073.B00.0809221748" }, + {"SMbiosdate", "04/01/2008" }, + {"SMmanufacter", "Apple Inc." }, + {"SMproductname", "MacBook4,1" }, + {"SMsystemversion", "1.0" }, + {"SMserial", "SOMESRLNMBR" }, + {"SMfamily", "MacBook" }, + {"SMboardmanufacter", "Apple Inc." }, + {"SMboardproduct", "Mac-F42D89C8" }, + {"SMUUID" , "19422392-C343-106B-80A3-001F0A6C3E52"}, + { "","" } +}; + +// defaults for a MacBook Pro +static const SMStrEntryPair const sm_macbookpro_defaults[]={ + {"SMbiosvendor", "Apple Inc." }, + {"SMbiosversion", "MBP41.88Z.0073.B00.0809221748" }, + {"SMbiosdate", "04/01/2008" }, + {"SMmanufacter", "Apple Inc." }, + {"SMproductname", "MacBookPro4,1" }, + {"SMsystemversion", "1.0" }, + {"SMserial", "SOMESRLNMBR" }, + {"SMfamily", "MacBookPro" }, + {"SMboardmanufacter", "Apple Inc." }, + {"SMboardproduct", "Mac-F42D89C8" }, + {"SMUUID" , "862F78AF-9B36-106B-807A-00BA8C14A528"}, + { "","" } +}; + +// defaults for a Mac mini +static const SMStrEntryPair const sm_macmini_defaults[]={ + {"SMbiosvendor", "Apple Inc." }, + {"SMbiosversion", "MM21.88Z.009A.B00.0706281359" }, + {"SMbiosdate", "04/01/2008" }, + {"SMmanufacter", "Apple Inc." }, + {"SMproductname", "Macmini2,1" }, + {"SMsystemversion", "1.0" }, + {"SMserial", "SOMESRLNMBR" }, + {"SMfamily", "Napa Mac" }, + {"SMboardmanufacter", "Apple Inc." }, + {"SMboardproduct", "Mac-F4208EAA" }, + {"SMUUID" , "862F78AF-9B36-40AF-B67A-ABBA8C14A528"}, + { "","" } +}; + +// defaults for an iMac +static const SMStrEntryPair const sm_imac_defaults[]={ + {"SMbiosvendor", "Apple Inc." }, + {"SMbiosversion", "IM91.88Z.00C1.B00.0802091538" }, + {"SMbiosdate", "04/01/2008" }, + {"SMmanufacter", "Apple Inc." }, + {"SMproductname", "iMac9,1" }, + {"SMsystemversion", "1.0" }, + {"SMserial", "SOMESRLNMBR" }, + {"SMfamily", "Mac" }, + {"SMboardmanufacter", "Apple Inc." }, + {"SMboardproduct", "Mac-F227BEC8" }, + {"SMUUID" , "862F78AF-9B36-40AF-B67A-ABBA8C14A528"}, + { "","" } +}; + +// defaults for a Mac Pro +static const SMStrEntryPair const sm_macpro_defaults[]={ + {"SMbiosvendor", "Apple Computer, Inc." }, + {"SMbiosversion", "MP31.88Z.006C.B05.0802291410" }, + {"SMbiosdate", "04/01/2008" }, + {"SMmanufacter", "Apple Computer, Inc." }, + {"SMproductname", "MacPro3,1" }, + {"SMsystemversion", "1.0" }, + {"SMserial", "SOMESRLNMBR" }, + {"SMfamily", "MacPro" }, + {"SMboardmanufacter", "Apple Computer, Inc." }, + {"SMboardproduct", "Mac-F4208DC8" }, + {"SMUUID" , "862F78AF-9B36-40AF-B67A-ABBA8C14A528"}, + { "","" } +}; + +// defaults for an iMac11,1 core i3/i5/i7 +static const SMStrEntryPair const sm_imac_core_defaults[]={ + {"SMbiosvendor", "Apple Inc." }, + {"SMbiosversion", "IM111.88Z.0034.B00.0802091538" }, + {"SMbiosdate", "06/01/2009" }, + {"SMmanufacter", "Apple Inc." }, + {"SMproductname", "iMac11,1" }, + {"SMsystemversion", "1.0" }, + {"SMserial", "SOMESRLNMBR" }, + {"SMfamily", "iMac" }, + {"SMboardmanufacter", "Apple Computer, Inc." }, + {"SMboardproduct", "Mac-F2268DAE" }, + {"SMUUID" , "862F78AF-9B36-40AF-B67A-ABBA8C14A528"}, + { "","" } +}; +#if NEVER_USE_MACPRO41 +// defaults for a Mac Pro 4,1 Xeon +static const SMStrEntryPair const sm_macpro_core_defaults[]={ + {"SMbiosvendor", "Apple Computer, Inc." }, + {"SMbiosversion", "MP41.88Z.0081.B04.0903051113" }, + {"SMbiosdate", "11/06/2009" }, + {"SMmanufacter", "Apple Computer, Inc." }, + {"SMproductname", "MacPro4,1" }, + {"SMsystemversion", "1.0" }, + {"SMserial", "SOMESRLNMBR" }, + {"SMfamily", "MacPro" }, + {"SMboardmanufacter", "Apple Computer, Inc." }, + {"SMboardproduct", "Mac-F4208DC8" }, + {"SMUUID" , "862F78AF-9B36-40AF-B67A-ABBA8C14A528"}, + { "","" } +}; +#endif +static const char* sm_get_defstr(const char * key, int table_num) +{ + int i; + const SMStrEntryPair* sm_defaults; + +// if (platformCPUFeature(CPU_FEATURE_MOBILE)) { + if (Platform->CPU.Mobile) { + if (Platform->CPU.NoCores > 1) { + //TODO if NVidia - MBP else MB + sm_defaults=sm_macbookpro_defaults; + } else { + sm_defaults=sm_macbook_defaults; + } + } else { + switch (Platform->CPU.NoCores) + { + case 1: + sm_defaults=sm_macmini_defaults; + break; + case 2: + sm_defaults=sm_imac_defaults; + break; + default: + { + switch (Platform->CPU.Family) + { + case 0x06: + { + switch (Platform->CPU.Model) + { + case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm) + case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ??? + case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) (Clarkdale, Arrandale) + case 0x19: // Intel Core i5 650 @3.20 Ghz + // sm_defaults=sm_imac_defaults; + // break; + case CPU_MODEL_NEHALEM: + case CPU_MODEL_NEHALEM_EX: + case CPU_MODEL_WESTMERE: + case CPU_MODEL_WESTMERE_EX: + sm_defaults=sm_imac_core_defaults; + break; + default: + sm_defaults=sm_imac_core_defaults; + break; + } + break; + } + default: + sm_defaults=sm_macpro_defaults; + break; + } + break; + } + } + } + + for (i=0; sm_defaults[i].key[0]; i++) { + if (!strcmp (sm_defaults[i].key, key)) { + return sm_defaults[i].value; + } + } + + // Shouldn't happen + printf ("Error: no default for '%s' known\n", key); + sleep (2); + return ""; +} + +static int sm_get_fsb(const char *name, int table_num) +{ + return Platform->CPU.FSBFrequency/1000000; +} + +static int sm_get_cpu (const char *name, int table_num) +{ + return Platform->CPU.CPUFrequency/1000000; +} + +static int sm_get_bus_speed (const char *name, int table_num) +{ + if (Platform->CPU.Vendor == 0x756E6547) // Intel + { + switch (Platform->CPU.Family) + { + case 0x06: + { + switch (Platform->CPU.Model) + { + case CPU_MODEL_PENTIUM_M: // Pentium M 0x0D + case CPU_MODEL_YONAH: // Yonah 0x0E + case CPU_MODEL_MEROM: // Merom 0x0F + case CPU_MODEL_PENRYN: // Penryn 0x17 + case CPU_MODEL_ATOM: // Atom 45nm 0x1C + return 0; // TODO: populate bus speed for these processors + +// case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm) +// if (strstr(Platform->CPU.BrandString, "Core(TM) i5")) +// return 2500; // Core i5 +// return 4800; // Core i7 + +// case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm) +// case CPU_MODEL_NEHALEM_EX: +// case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ??? +// return 4800; // GT/s / 1000 +// + case CPU_MODEL_WESTMERE_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ??? + return 0; // TODO: populate bus speed for these processors + +// case 0x19: // Intel Core i5 650 @3.20 Ghz +// return 2500; // why? Intel spec says 2.5GT/s + + case 0x19: // Intel Core i5 650 @3.20 Ghz + case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm) + case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm) + case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ??? + case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) + case CPU_MODEL_WESTMERE: // Intel Core i7 LGA1366 (32nm) 6 Core + case CPU_MODEL_NEHALEM_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ??? + { // thanks to dgobe for i3/i5/i7 bus speed detection + int nhm_bus = 0x3F; + static long possible_nhm_bus[] = {0xFF, 0x7F, 0x3F}; + unsigned long did, vid; + int i; + + // Nehalem supports Scrubbing + // First, locate the PCI bus where the MCH is located + for(i = 0; i < sizeof(possible_nhm_bus); i++) + { + vid = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x00); + did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x02); + vid &= 0xFFFF; + did &= 0xFF00; + + if(vid == 0x8086 && did >= 0x2C00) + nhm_bus = possible_nhm_bus[i]; + } + + unsigned long qpimult, qpibusspeed; + qpimult = pci_config_read32(PCIADDR(nhm_bus, 2, 1), 0x50); + qpimult &= 0x7F; + DBG("qpimult %d\n", qpimult); + qpibusspeed = (qpimult * 2 * (Platform->CPU.FSBFrequency/1000000)); + // Rek: rounding decimals to match original mac profile info + if (qpibusspeed%100 != 0)qpibusspeed = ((qpibusspeed+50)/100)*100; + DBG("qpibusspeed %d\n", qpibusspeed); + return qpibusspeed; + } + } + } + } + } + return 0; +} + +static int sm_get_simplecputype() +{ + if (Platform->CPU.NoCores >= 4) + { + return 0x0501; // Quad-Core Xeon + } + else if (Platform->CPU.NoCores == 1) + { + return 0x0201; // Core Solo + }; + + return 0x0301; // Core 2 Duo +} + +static int sm_get_cputype (const char *name, int table_num) +{ + static bool done = false; + + if (Platform->CPU.Vendor == 0x756E6547) // Intel + { + if (!done) { + verbose("CPU is %s, family 0x%x, model 0x%x\n", Platform->CPU.BrandString, Platform->CPU.Family, Platform->CPU.Model); + done = true; + } + + switch (Platform->CPU.Family) + { + case 0x06: + { + switch (Platform->CPU.Model) + { + case CPU_MODEL_PENTIUM_M: // Pentium M = 0x0D + return 0x0101; + case CPU_MODEL_YONAH: // Yonah + case CPU_MODEL_MEROM: // Merom + case CPU_MODEL_PENRYN: // Penryn + case CPU_MODEL_ATOM: // Intel Atom (45nm) + return sm_get_simplecputype(); + + case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm) + return 0x0701; // Core i7 + + case CPU_MODEL_FIELDS: // Lynnfield, Clarksfield, Jasper + if (strstr(Platform->CPU.BrandString, "Core(TM) i5")) + return 0x601; // Core i5 + return 0x701; // Core i7 + + case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) (Havendale, Auburndale) + if (strstr(Platform->CPU.BrandString, "Core(TM) i5")) + return 0x601; // Core i5 + return 0x0701; // Core i7 + + case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) (Clarkdale, Arrandale) + if (strstr(Platform->CPU.BrandString, "Core(TM) i3")) + return 0x901; // Core i3 + if (strstr(Platform->CPU.BrandString, "Core(TM) i5")) + return 0x601; // Core i5 + return 0x0701; // Core i7 + + case CPU_MODEL_WESTMERE: // Intel Core i7 LGA1366 (32nm) 6 Core (Gulftown, Westmere-EP, Westmere-WS) + case CPU_MODEL_WESTMERE_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ??? + return 0x0701; // Core i7 + + case 0x19: // Intel Core i5 650 @3.20 Ghz + return 0x601; // Core i5 + } + } + } + } + + return sm_get_simplecputype(); +} + +static int sm_get_memtype (const char *name, int table_num) +{ + int map; + + if (table_num < MAX_RAM_SLOTS) { + map = Platform->DMI.DIMM[table_num]; + if (Platform->RAM.DIMM[map].InUse && Platform->RAM.DIMM[map].Type != 0) { + DBG("RAM Detected Type = %d\n", Platform->RAM.DIMM[map].Type); + return Platform->RAM.DIMM[map].Type; + } + } + + return SMB_MEM_TYPE_DDR2; +} + +static int sm_get_memspeed (const char *name, int table_num) +{ + int map; + + if (table_num < MAX_RAM_SLOTS) { + map = Platform->DMI.DIMM[table_num]; + if (Platform->RAM.DIMM[map].InUse && Platform->RAM.DIMM[map].Frequency != 0) { + DBG("RAM Detected Freq = %d Mhz\n", Platform->RAM.DIMM[map].Frequency); + return Platform->RAM.DIMM[map].Frequency; + } + } + + return 800; +} + +static const char *sm_get_memvendor (const char *name, int table_num) +{ + int map; + + if (table_num < MAX_RAM_SLOTS) { + map = Platform->DMI.DIMM[table_num]; + if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].Vendor) > 0) { + DBG("RAM Detected Vendor[%d]='%s'\n", table_num, Platform->RAM.DIMM[map].Vendor); + return Platform->RAM.DIMM[map].Vendor; + } + } + return "N/A"; +} + +static const char *sm_get_memserial (const char *name, int table_num) +{ + int map; + + if (table_num < MAX_RAM_SLOTS) { + map = Platform->DMI.DIMM[table_num]; + if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].SerialNo) > 0) { + DBG("name = %s, map=%d, RAM Detected SerialNo[%d]='%s'\n", name ? name : "", + map, table_num, Platform->RAM.DIMM[map].SerialNo); + return Platform->RAM.DIMM[map].SerialNo; + } + } + return "N/A"; +} + +static const char *sm_get_mempartno (const char *name, int table_num) +{ + int map; + + if (table_num < MAX_RAM_SLOTS) { + map = Platform->DMI.DIMM[table_num]; + if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].PartNo) > 0) { + DBG("Ram Detected PartNo[%d]='%s'\n", table_num, Platform->RAM.DIMM[map].PartNo); + return Platform->RAM.DIMM[map].PartNo; + } + } + return "N/A"; +} + +static int sm_one (int tablen) +{ + return 1; +} + +struct smbios_property smbios_properties[]= +{ + {.name="SMbiosvendor", .table_type= 0, .value_type=SMSTRING, .offset=0x04, .auto_str=sm_get_defstr }, + {.name="SMbiosversion", .table_type= 0, .value_type=SMSTRING, .offset=0x05, .auto_str=sm_get_defstr }, + {.name="SMbiosdate", .table_type= 0, .value_type=SMSTRING, .offset=0x08, .auto_str=sm_get_defstr }, + {.name="SMmanufacter", .table_type= 1, .value_type=SMSTRING, .offset=0x04, .auto_str=sm_get_defstr }, + {.name="SMproductname", .table_type= 1, .value_type=SMSTRING, .offset=0x05, .auto_str=sm_get_defstr }, + {.name="SMsystemversion", .table_type= 1, .value_type=SMSTRING, .offset=0x06, .auto_str=sm_get_defstr }, + {.name="SMserial", .table_type= 1, .value_type=SMSTRING, .offset=0x07, .auto_str=sm_get_defstr }, + {.name="SMUUID", .table_type= 1, .value_type=SMOWORD, .offset=0x08, .auto_oword=sm_get_defstr}, + {.name="SMfamily", .table_type= 1, .value_type=SMSTRING, .offset=0x1a, .auto_str=sm_get_defstr }, + {.name="SMboardmanufacter", .table_type= 2, .value_type=SMSTRING, .offset=0x04, .auto_str=sm_get_defstr }, + {.name="SMboardproduct", .table_type= 2, .value_type=SMSTRING, .offset=0x05, .auto_str=sm_get_defstr }, + {.name="SMexternalclock", .table_type= 4, .value_type=SMWORD, .offset=0x12, .auto_int=sm_get_fsb }, + {.name="SMmaximalclock", .table_type= 4, .value_type=SMWORD, .offset=0x14, .auto_int=sm_get_cpu }, + {.name="SMmemdevloc", .table_type=17, .value_type=SMSTRING, .offset=0x10, .auto_str=0 }, + {.name="SMmembankloc", .table_type=17, .value_type=SMSTRING, .offset=0x11, .auto_str=0 }, + {.name="SMmemtype", .table_type=17, .value_type=SMBYTE, .offset=0x12, .auto_int=sm_get_memtype}, + {.name="SMmemspeed", .table_type=17, .value_type=SMWORD, .offset=0x15, .auto_int=sm_get_memspeed}, + {.name="SMmemmanufacter", .table_type=17, .value_type=SMSTRING, .offset=0x17, .auto_str=sm_get_memvendor}, + {.name="SMmemserial", .table_type=17, .value_type=SMSTRING, .offset=0x18, .auto_str=sm_get_memserial}, + {.name="SMmempart", .table_type=17, .value_type=SMSTRING, .offset=0x1A, .auto_str=sm_get_mempartno}, + {.name="SMcputype", .table_type=131,.value_type=SMWORD, .offset=0x04, .auto_int=sm_get_cputype}, + {.name="SMbusspeed", .table_type=132,.value_type=SMWORD, .offset=0x04, .auto_int=sm_get_bus_speed} +}; + +struct smbios_table_description smbios_table_descriptions[]= +{ + {.type=kSMBTypeBIOSInformation, .len=0x18, .numfunc=sm_one}, + {.type=kSMBTypeSystemInformation, .len=0x1b, .numfunc=sm_one}, + {.type=kSMBTypeBaseBoard, .len=0x0f, .numfunc=sm_one}, //except kSMBBaseBoardProcessorMemoryModule + {.type=kSMBTypeProcessorInformation, .len=0x2a, .numfunc=sm_one}, +//kSMBTypeMemoryModule len=12 obsolete but Used by AppleSMBIOS +//kSMBTypeSystemSlot len=13 Used by AppleSMBIOS +//kSMBTypePhysicalMemoryArray len=15 Used by AppleSMBIOS + {.type=kSMBTypeMemoryDevice, .len=0x24, .numfunc=0}, +//Slice - we are not ready to fill the data +// {.type=kSMBTypeFirmwareVolume, .len=0x56, .numfunc=0}, +// {.type=kSMBTypeMemorySPD, .len=0x0c, .numfunc=0}, + {.type=kSMBTypeOemProcessorType, .len=0x06, .numfunc=sm_one}, + {.type=kSMBTypeOemProcessorBusSpeed, .len=0x06, .numfunc=sm_one} +}; +/* Apple known 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, + + // Apple Specific Structures +kSMBTypeFirmwareVolume = 128, +kSMBTypeMemorySPD = 130, +kSMBTypeOemProcessorType = 131, +kSMBTypeOemProcessorBusSpeed = 132 +}; + + */ + +// getting smbios addr with fast compare ops, late checksum testing ... +#define COMPARE_DWORD(a,b) ( *((u_int32_t *) a) == *((u_int32_t *) b) ) +static const char * const SMTAG = "_SM_"; +static const char* const DMITAG= "_DMI_"; + +static struct SMBEntryPoint *getAddressOfSmbiosTable(void) +{ + struct SMBEntryPoint *smbios; + /* + * The logic is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking + * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_"). + */ + smbios = (struct SMBEntryPoint*) SMBIOS_RANGE_START; + while (smbios <= (struct SMBEntryPoint *)SMBIOS_RANGE_END) { + if (COMPARE_DWORD(smbios->anchor, SMTAG) && + COMPARE_DWORD(smbios->dmi.anchor, DMITAG) && + smbios->dmi.anchor[4]==DMITAG[4] && + checksum8(smbios, sizeof(struct SMBEntryPoint)) == 0) + { + return smbios; + } + smbios = (struct SMBEntryPoint*) ( ((char*) smbios) + 16 ); + } + printf("ERROR: Unable to find SMBIOS!\n"); + pause(); + return NULL; +} + +/** Compute necessary space requirements for new smbios */ +static struct SMBEntryPoint *smbios_dry_run(struct SMBEntryPoint *origsmbios) +{ + struct SMBEntryPoint *ret; + char *smbiostables; + char *tablesptr; + int origsmbiosnum; + int i, j; + int tablespresent[256]; + bool do_auto=true; + + bzero(tablespresent, sizeof(tablespresent)); + + getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig); + + ret = (struct SMBEntryPoint *)AllocateKernelMemory(sizeof(struct SMBEntryPoint)); + if (origsmbios) { + smbiostables = (char *)origsmbios->dmi.tableAddress; + origsmbiosnum = origsmbios->dmi.structureCount; + } else { + smbiostables = NULL; + origsmbiosnum = 0; + } + + // _SM_ + ret->anchor[0] = 0x5f; + ret->anchor[1] = 0x53; + ret->anchor[2] = 0x4d; + ret->anchor[3] = 0x5f; + ret->entryPointLength = sizeof(*ret); + ret->majorVersion = 2; + ret->minorVersion = 1; + ret->maxStructureSize = 0; // will be calculated later in this function + ret->entryPointRevision = 0; + for (i=0;i<5;i++) { + ret->formattedArea[i] = 0; + } + //_DMI_ + ret->dmi.anchor[0] = 0x5f; + ret->dmi.anchor[1] = 0x44; + ret->dmi.anchor[2] = 0x4d; + ret->dmi.anchor[3] = 0x49; + ret->dmi.anchor[4] = 0x5f; + ret->dmi.tableLength = 0; // will be calculated later in this function + ret->dmi.tableAddress = 0; // will be initialized in smbios_real_run() + ret->dmi.structureCount = 0; // will be calculated later in this function + ret->dmi.bcdRevision = 0x21; + tablesptr = smbiostables; + + // add stringlen of overrides to original stringlen, update maxStructure size adequately, + // update structure count and tablepresent[type] with count of type. + if (smbiostables) { + for (i=0; ilength; + stringsptr = tablesptr; + for (; tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++); + tablesptr += 2; + stringlen = tablesptr - stringsptr - 1; + if (stringlen == 1) { + stringlen = 0; + } + for (j=0; jtype] + 1); + if (smbios_properties[j].table_type == cur->type && + smbios_properties[j].value_type == SMSTRING && + (getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig) || + getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig))) + { + stringlen += size + 1; + } else if (smbios_properties[j].table_type == cur->type && + smbios_properties[j].value_type == SMSTRING && + do_auto && smbios_properties[j].auto_str) + { + stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[cur->type])) + 1; + } + } + if (stringlen == 0) { + stringlen = 1; + } + stringlen++; + if (ret->maxStructureSize < cur->length+stringlen) { + ret->maxStructureSize=cur->length+stringlen; + } + ret->dmi.tableLength += cur->length+stringlen; + ret->dmi.structureCount++; + tablespresent[cur->type]++; + } + } + // Add eventually table types whose detected count would be < required count, and update ret header with: + // new stringlen addons, structure count, and tablepresent[type] count adequately + for (i=0; ismbiosConfig)) { + numnec = -1; + } + if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc) { + numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type); + } + while (tablespresent[smbios_table_descriptions[i].type] < numnec) { + int stringlen = 0; + for (j=0; jsmbiosConfig) || + getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))) + { + stringlen += size + 1; + } else if (smbios_properties[j].table_type == smbios_table_descriptions[i].type && + smbios_properties[j].value_type==SMSTRING && + do_auto && smbios_properties[j].auto_str) + { + stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type])) + 1; + } + } + if (stringlen == 0) { + stringlen = 1; + } + stringlen++; + if (ret->maxStructureSize < smbios_table_descriptions[i].len+stringlen) { + ret->maxStructureSize = smbios_table_descriptions[i].len + stringlen; + } + ret->dmi.tableLength += smbios_table_descriptions[i].len + stringlen; + ret->dmi.structureCount++; + tablespresent[smbios_table_descriptions[i].type]++; + } + } + return ret; +} + +/** From the origsmbios detected by getAddressOfSmbiosTable() to newsmbios whose entrypoint + * struct has been created by smbios_dry_run, update each table struct content of new smbios + * int the new allocated table address of size newsmbios->tablelength. + */ +static void smbios_real_run(struct SMBEntryPoint * origsmbios, struct SMBEntryPoint * newsmbios) +{ + char *smbiostables; + char *tablesptr, *newtablesptr; + int origsmbiosnum=0; + // bitmask of used handles + uint8_t handles[8192]; + uint16_t nexthandle=0; + int i, j; + int tablespresent[256]; + bool do_auto=true; + + static bool done = false; // IMPROVEME: called twice via getSmbios(), but only the second call can get all necessary info ! + + extern void dumpPhysAddr(const char * title, void * a, int len); + + bzero(tablespresent, sizeof(tablespresent)); + bzero(handles, sizeof(handles)); + + getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig); + + newsmbios->dmi.tableAddress = (uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength); + if (origsmbios) { + smbiostables = (char *)origsmbios->dmi.tableAddress; + origsmbiosnum = origsmbios->dmi.structureCount; + } else { + smbiostables = NULL; + origsmbiosnum = 0; + } + tablesptr = smbiostables; + newtablesptr = (char *)newsmbios->dmi.tableAddress; + + // if old smbios exists then update new smbios with old smbios original content first + if (smbiostables) { + for (i=0; ihandle) / 8] |= 1 << ((oldcur->handle) % 8); + + // copy table length from old table to new table but not the old strings + memcpy(newcur,oldcur, oldcur->length); + + tablesptr += oldcur->length; + stringsptr = tablesptr; + newtablesptr += oldcur->length; + + // calculate the number of strings in the old content + for (;tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++) { + if (tablesptr[0] == 0) { + nstrings++; + } + } + if (tablesptr != stringsptr) { + nstrings++; + } + tablesptr += 2; + + // copy the old strings to new table + memcpy(newtablesptr, stringsptr, tablesptr-stringsptr); + + // point to next possible space for a string (deducting the second 0 char at the end) + newtablesptr += tablesptr - stringsptr - 1; + if (nstrings == 0) { // if no string was found rewind to the first 0 char of the 0,0 terminator + newtablesptr--; + } + + // now for each property in the table update the overrides if any (auto or user) + for (j=0; jtype] + 1); + if (smbios_properties[j].table_type == newcur->type) { + switch (smbios_properties[j].value_type) { + case SMSTRING: + if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) || + getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)) + { + memcpy(newtablesptr, str, size); + newtablesptr[size] = 0; + newtablesptr += size + 1; + *((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings; + } else if (do_auto && smbios_properties[j].auto_str) { + str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]); + size = strlen(str); + memcpy(newtablesptr, str, size); + newtablesptr[size] = 0; + newtablesptr += size + 1; + *((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings; + } + break; + + case SMOWORD: + if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) || + getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)) + { + //int k=0, t=0, kk=0; + //const char *ptr = str; + verbose("Set SMUUID to %s\n", str); + //memset(((char*)newcur) + smbios_properties[j].offset, 0, 16); + EFI_GUID* p = getUUIDFromString(str); + memcpy(((char*)newcur) + smbios_properties[j].offset, p, 16); + /* + while (ptr-str=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) { + ptr += 2; + } + for (;ptr-str='0' && *ptr<='9') { + (t=(t<<4)|(*ptr-'0')),kk++; + } + if (*ptr>='a' && *ptr<='f') { + (t=(t<<4)|(*ptr-'a'+10)),kk++; + } + if (*ptr>='A' && *ptr<='F') { + (t=(t<<4)|(*ptr-'A'+10)),kk++; + } + if (kk == 2) { + *((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t; + k++; + kk = 0; + t = 0; + } + } + */ + } + break; + + case SMBYTE: + if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) || + getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig)) + { + *((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num; + } else if (do_auto && smbios_properties[j].auto_int) { + *((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]); + } + break; + + case SMWORD: + if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) || + getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig)) + { + *((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num; + } else if (do_auto && smbios_properties[j].auto_int) { + *((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]); + } + break; + } + } + } + if (nstrings == 0) { + newtablesptr[0] = 0; + newtablesptr++; + } + newtablesptr[0] = 0; + newtablesptr++; + tablespresent[newcur->type]++; + } + } + + // for each eventual complementary table not present in the original smbios, do the overrides + for (i=0; ismbiosConfig)) { + numnec = -1; + } + if (numnec == -1 && do_auto && smbios_table_descriptions[i].numfunc) { + numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type); + } + while (tablespresent[smbios_table_descriptions[i].type] < numnec) { + struct smbios_table_header *newcur = (struct smbios_table_header *) newtablesptr; + int nstrings = 0; + + memset(newcur,0, smbios_table_descriptions[i].len); + while (handles[(nexthandle)/8] & (1 << ((nexthandle) % 8))) { + nexthandle++; + } + newcur->handle = nexthandle; + handles[nexthandle / 8] |= 1 << (nexthandle % 8); + newcur->type = smbios_table_descriptions[i].type; + newcur->length = smbios_table_descriptions[i].len; + newtablesptr += smbios_table_descriptions[i].len; + for (j=0; jtype] + 1); + if (smbios_properties[j].table_type == newcur->type) { + switch (smbios_properties[j].value_type) { + case SMSTRING: + if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) || + getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)) + { + memcpy(newtablesptr, str, size); + newtablesptr[size] = 0; + newtablesptr += size + 1; + *((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings; + } else if (do_auto && smbios_properties[j].auto_str) { + str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]); + size = strlen(str); + memcpy(newtablesptr, str, size); + newtablesptr[size] = 0; + newtablesptr += size + 1; + *((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings; + } + break; + + case SMOWORD: + if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) || + getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)) + { + EFI_GUID* p = getUUIDFromString(str); + memcpy(((char*)newcur) + smbios_properties[j].offset, p, 16); +/* + int k=0, t=0, kk=0; + const char *ptr = str; + verbose("Set SMUUID to %s\n", str); + + memset(((char*)newcur) + smbios_properties[j].offset, 0, 16); + while (ptr-str=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) { + ptr += 2; + } + for (;ptr-str='0' && *ptr<='9') { + (t=(t<<4)|(*ptr-'0')),kk++; + } + if (*ptr>='a' && *ptr<='f') { + (t=(t<<4)|(*ptr-'a'+10)),kk++; + } + if (*ptr>='A' && *ptr<='F') { + (t=(t<<4)|(*ptr-'A'+10)),kk++; + } + if (kk == 2) { + *((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t; + k++; + kk = 0; + t = 0; + } + } + */ + } + break; + + case SMBYTE: + if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) || + getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig)) + { + *((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num; + } else if (do_auto && smbios_properties[j].auto_int) { + *((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]); + } + break; + + case SMWORD: + if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) || + getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig)) + { + *((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num; + } else if (do_auto && smbios_properties[j].auto_int) { + *((uint16_t*)(((char*)newcur)+smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]); + } + break; + } + } + } + if (nstrings == 0) { + newtablesptr[0] = 0; + newtablesptr++; + } + newtablesptr[0] = 0; + newtablesptr++; + tablespresent[smbios_table_descriptions[i].type]++; + } + } + + // calculate new checksums + newsmbios->dmi.checksum = 0; + newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi)); + newsmbios->checksum = 0; + newsmbios->checksum = 256 - checksum8(newsmbios, sizeof(*newsmbios)); + + if (!done) { + verbose("Patched DMI Table\n"); + done=true; + } +} + +#define MAX_DMI_TABLES 96 +typedef struct DmiNumAssocTag { + struct DMIHeader * 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 + +/** + * Get a table structure entry from a type specification and a smbios address + * return NULL if table is not found + */ +static void getSmbiosTableStructure(struct SMBEntryPoint *smbios) +{ + struct DMIHeader * dmihdr=NULL; + SMBByte* p; + int i; + + if (ftTablePairInit && smbios!=NULL) { + ftTablePairInit = false; +#if DEBUG_SMBIOS + verbose(">>> SMBIOSAddr=0x%08x\n", smbios); + verbose(">>> DMI: addr=0x%08x, len=%d, count=%d\n", smbios->dmi.tableAddress, + smbios->dmi.tableLength, smbios->dmi.structureCount); +#endif + p = (SMBByte *) smbios->dmi.tableAddress; + for (i=0; + i < smbios->dmi.structureCount && + p + 4 <= (SMBByte *)smbios->dmi.tableAddress + smbios->dmi.tableLength; + i++) { + dmihdr = (struct DMIHeader *) p; + +#if DEBUG_SMBIOS + // verbose(">>>>>> DMI(%d): type=0x%02x, len=0x%d\n",i,dmihdr->type,dmihdr->length); +#endif + if (dmihdr->length < 4 || dmihdr->type == 127 /* EOT */) break; + if (DmiTablePairCount < MAX_DMI_TABLES) { + DmiTablePair[DmiTablePairCount].dmi = dmihdr; + DmiTablePair[DmiTablePairCount].type = dmihdr->type; + DmiTablePairCount++; + } + else { + verbose("DMI table entries list is full! Next entries won't be stored.\n"); + } +#if DEBUG_SMBIOS + verbose("DMI header found for table type %d, length = %d\n", dmihdr->type, dmihdr->length); +#endif + p = p + dmihdr->length; + while ((p - (SMBByte *)smbios->dmi.tableAddress + 1 < smbios->dmi.tableLength) && (p[0] != 0x00 || p[1] != 0x00)) { + p++; + } + p += 2; + } + + } +} + +void getSmbiosMacModel(void) +{ +#define MAX_MODEL_LEN 32 + + //Slice - I want to use MacModel for ACPITables so I need char* representation + const char *value = getStringForKey("SMproductname", &bootInfo->smbiosConfig); + int i, n=0, first=0, rev1=0, rev2=0; + for (i=0; i<8; i++) + { + char c = value[i]; + if (isalpha(c)) + { + MacModel[i]=c; + n++; + } else + if ((c) >= '0' && (c) <= '9') + { + if (first) + { + rev1 = rev1 * 10 + (int)(c) & 0xf; + } else + rev2 = rev2 * 10 + (int)(c) & 0xf; + } else + first = 1; + // printf("char=%c first=%d rev1=%d rev2=%d\n", c, first, rev1, rev2); + } + for (i=n; i<8; i++) { + MacModel[i] = 0x20; + } + ModelRev = (rev2 << 16) + rev1; +// ModelLength = (len + 1) * 2; +// printf("Model=%s %08x\n", MacModel, ModelRev); +// getc(); + +} + + static struct SMBEntryPoint *orig = NULL; // cached + static struct SMBEntryPoint *patched = NULL; // cached + +/** Get original or new smbios entry point, if successful, the addresses are cached for next time */ +struct SMBEntryPoint *getSmbios(int which) +{ + + // whatever we are called with orig or new flag, initialize asap both structures + switch (which) { + case SMBIOS_ORIGINAL: + if (orig==NULL) { + orig = getAddressOfSmbiosTable(); + getSmbiosTableStructure(orig); // generate tables entry list for fast table finding + } + return orig; + case SMBIOS_PATCHED: + if (orig==NULL && (orig = getAddressOfSmbiosTable())==NULL ) { + verbose("Could not find original SMBIOS !!\n"); + pause(); + } else { + patched = smbios_dry_run(orig); + if(patched==NULL) { + verbose("Could not create new SMBIOS !!\n"); + pause(); + } + else { + smbios_real_run(orig, patched); + } + } + getSmbiosMacModel(); //Dunno if it is a right place to do that + return patched; + default: + verbose("ERROR: invalid option for getSmbios() !!\n"); + break; + } + + return NULL; +} + +/** Find first original dmi Table with a particular type */ +struct DMIHeader* FindFirstDmiTableOfType(int type, int minlength) +{ + current_pos = 0; //static variable + + return FindNextDmiTableOfType(type, minlength); +}; + +/** Find next original dmi Table with a particular type */ +struct DMIHeader* 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 +}; + +#if 1 //NOTUSED //Slice -- it is used? +const char * smbiosStringAtIndex(DMIHeader* smHeader, int index, int* length ) +{ + const char * last = 0; + const char * next = (const char *) smHeader + smHeader->length; + + if ( length ) *length = 0; + while ( index-- ) + { + last = 0; + const char * cp = 0; + for ( cp = next; *cp || cp[1]; cp++ ) + { + if ( *cp == '\0' ) + { + last = next; + next = cp + 1; + break; + } + } + if ( last == 0 ) break; + } + + if ( last ) + { + while (*last == ' ') last++; + if (length) + { + UInt8 len; + for ( len = next - last - 1; len && last[len - 1] == ' '; len-- ) + ; + *length = len; // number of chars not counting the terminating NULL + } + } + + return last ? last : ""; +} + + +void getSmbiosProductName() +{ +// struct SMBEntryPoint *smbios; + DMISystemInformation *p; + char* tempString; + int tmpLen; + +// smbios = getSmbios(SMBIOS_ORIGINAL); +// if (smbios==NULL) return 0; + + p = (DMISystemInformation*) FindFirstDmiTableOfType(1, 0x19); // Type 1: (3.3.2) System Information + if (p==NULL) return; // NULL; + + + tempString = (char*)smbiosStringAtIndex((DMIHeader*)p, p->productName, &tmpLen); + tempString[tmpLen] = 0; + + gSMBIOSBoardModel = malloc(tmpLen + 1); + if(gSMBIOSBoardModel) + { + strncpy(gSMBIOSBoardModel, tempString, tmpLen); + Node* node = DT__FindNode("/", false); + DT__AddProperty(node, "orig-model", tmpLen, gSMBIOSBoardModel); + } + verbose("Actual model name is '%s'\n", tempString); +} +#endif + +//Slice +//#define MEGA 1000000LL - now in mem.h +void scan_cpu_DMI(void) //PlatformInfo_t *p) +{ + // int i=0; + int maxClock = 0; + struct DMIHeader * dmihdr = NULL; + struct DMIProcessorInformation* cpuInfo; // Type 4 + + for (dmihdr = FindFirstDmiTableOfType(4, 30); dmihdr; dmihdr = FindNextDmiTableOfType(4, 30)) + { + cpuInfo = (struct DMIProcessorInformation*)dmihdr; + if (cpuInfo->processorType != 3) { // CPU + continue; + } + //TODO validate +#if 1 //NOTYET + msglog("Platform CPU Info:\n FSB=%d\n MaxSpeed=%d\n CurrentSpeed=%d\n", Platform->CPU.FSBFrequency/MEGA, Platform->CPU.TSCFrequency/MEGA, Platform->CPU.CPUFrequency/MEGA); + + if ((cpuInfo->externalClock) && (cpuInfo->externalClock < 400)) { //<400MHz + Platform->CPU.FSBFrequency = (cpuInfo->externalClock) * MEGA; + } + maxClock = cpuInfo->maximumClock; + if (cpuInfo->maximumClock < cpuInfo->currentClock) { + maxClock = cpuInfo->currentClock; + } + if ((maxClock) && (maxClock < 10000)) { //<10GHz + Platform->CPU.TSCFrequency = maxClock * MEGA; + } + if ((cpuInfo->currentClock) && (cpuInfo->currentClock < 10000)) { //<10GHz + Platform->CPU.CPUFrequency = cpuInfo->currentClock * MEGA; + } +#endif + msglog("DMI CPU Info:\n FSB=%d\n MaxSpeed=%d\n CurrentSpeed=%d\n", cpuInfo->externalClock, cpuInfo->maximumClock, cpuInfo->currentClock); + msglog("DMI CPU Info 2:\n Family=%x\n Socket=%x\n Cores=%d Enabled=%d Threads=%d\n", cpuInfo->processorFamily, cpuInfo->processorUpgrade, cpuInfo->coreCount, cpuInfo->coreEnabled, cpuInfo->Threads); +#if 1 //NOTYET + if ((cpuInfo->coreCount) && (cpuInfo->coreCountCPU.NoCores)) { + if (cpuInfo->coreEnabled < cpuInfo->coreCount) { + cpuInfo->coreCount = cpuInfo->coreEnabled; + } + Platform->CPU.NoCores = cpuInfo->coreCount; + } + if ((cpuInfo->Threads) && (cpuInfo->ThreadsCPU.NoThreads)) { + Platform->CPU.NoThreads = cpuInfo->Threads; + } +#endif + + return; + } + + return; +} +//Slice - check other DMI info +bool scanDMI(void) +{ + struct DMIHeader * dmihdr = NULL; + struct DMISystemEnclosure* encInfo; // Type 3 + + for (dmihdr = FindFirstDmiTableOfType(3, 13); dmihdr; dmihdr = FindNextDmiTableOfType(3, 13)) + { + encInfo = (struct DMISystemEnclosure*)dmihdr; + msglog("DMI Chassis Info:\n Type=%x\n Boot-up State=%x\n Power Supply=%x Thermal State=%x\n", encInfo->type, encInfo->bootupState, encInfo->powerSupplyState, encInfo->thermalState); + switch (encInfo->type) { + case 1: + case 2: + return FALSE; + case 3: + case 4: + case 6: + case 7: + Platform->CPU.Mobile = FALSE; + break; + case 8: + case 9: + case 0x0A: + case 0x0B: + case 0x0E: + Platform->CPU.Mobile = TRUE; + break; + + default: + break; + } + return TRUE; + } + return FALSE; +} Index: branches/slice/old749m/i386/libsaio/ufs.h =================================================================== --- branches/slice/old749m/i386/libsaio/ufs.h (revision 0) +++ branches/slice/old749m/i386/libsaio/ufs.h (revision 1174) @@ -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/old749m/i386/libsaio/nbp_cmd.h =================================================================== --- branches/slice/old749m/i386/libsaio/nbp_cmd.h (revision 0) +++ branches/slice/old749m/i386/libsaio/nbp_cmd.h (revision 1174) @@ -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/old749m/i386/libsaio/smbios_patcher.h =================================================================== --- branches/slice/old749m/i386/libsaio/smbios_patcher.h (revision 0) +++ branches/slice/old749m/i386/libsaio/smbios_patcher.h (revision 1174) @@ -0,0 +1,66 @@ +/* + * Copyright 2008 mackerintel + */ +/* + * AsereBLN: cleanup + */ + +#ifndef __LIBSAIO_SMBIOS_PATCHER_H +#define __LIBSAIO_SMBIOS_PATCHER_H + +#include "libsaio.h" +#include "SMBIOS.h" + +extern char MacModel[8]; +extern unsigned int ModelRev; +extern uint64_t smbios_p; + + +/* 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_RANGE_START 0x000F0000 +#define SMBIOS_RANGE_END 0x000FFFFF + +#define SMBIOS_ORIGINAL 0 +#define SMBIOS_PATCHED 1 + +struct smbios_table_header +{ + uint8_t type; + uint8_t length; + uint16_t handle; +} __attribute__ ((packed)); + +struct smbios_property +{ + const char *name; + uint8_t table_type; + enum {SMSTRING, SMWORD, SMBYTE, SMOWORD} value_type; + int offset; + int (*auto_int) (const char *name, int table_num); + const char *(*auto_str) (const char *name, int table_num); + const char *(*auto_oword) (const char *name, int table_num); +}; + +struct smbios_table_description +{ + uint8_t type; + int len; + int (*numfunc)(int tablen); +}; + +/** call with flag SMBIOS_ORIGINAL to get orig. entrypoint + or call with flag SMBIOS_PATCHED to get patched smbios entrypoint +*/ +extern struct SMBEntryPoint *getSmbios(int); +extern struct DMIHeader* FindNextDmiTableOfType(int type, int minlen); +extern struct DMIHeader* FindFirstDmiTableOfType(int type, int minlen); +extern void getSmbiosProductName(); +const char *smbiosStringAtIndex(DMIHeader*, int index, int *length ); +extern bool scanDMI(void); +extern void scan_cpu_DMI(void); //PlatformInfo_t *); //Slice + + +#endif /* !__LIBSAIO_SMBIOS_PATCHER_H */ Index: branches/slice/old749m/i386/libsaio/bios.s =================================================================== --- branches/slice/old749m/i386/libsaio/bios.s (revision 0) +++ branches/slice/old749m/i386/libsaio/bios.s (revision 1174) @@ -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/old749m/i386/libsaio/pci_root.c =================================================================== --- branches/slice/old749m/i386/libsaio/pci_root.c (revision 0) +++ branches/slice/old749m/i386/libsaio/pci_root.c (revision 1174) @@ -0,0 +1,116 @@ +/* + * Copyright 2009 netkas + */ + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +//#include "acpi_patcher.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 && ibootConfig)) { + if (isdigit(val[0])) rootuid = val[0] - '0'; + goto out; + } + /* Chameleon compatibility */ + else if (getValueForKey("PciRoot", &val, &len, &bootInfo->bootConfig)) { + if (isdigit(val[0])) rootuid = val[0] - '0'; + goto out; + } + /* PCEFI compatibility */ + else if (getValueForKey("-pci0", &val, &len, &bootInfo->bootConfig)) { + rootuid = 0; + goto out; + } + else if (getValueForKey("-pci1", &val, &len, &bootInfo->bootConfig)) { + 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/old749m/i386/libsaio/aml_generator.c =================================================================== --- branches/slice/old749m/i386/libsaio/aml_generator.c (revision 0) +++ branches/slice/old749m/i386/libsaio/aml_generator.c (revision 1174) @@ -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!"); + return false; + case AML_CHUNK_NAME: + if (parent->First) + { + verbose("aml_add_to_parent: name node supports only one child node!"); + return false; + } + break; + + default: + break; + } + + if (!parent->First) + parent->First = node; + + if (parent->Last) + parent->Last->Next = node; + + parent->Last = node; + + return TRUE; + } + + return FALSE; +} + +struct aml_chunk* aml_create_node(struct aml_chunk* parent) +{ + struct aml_chunk* node = (struct aml_chunk*)malloc(sizeof(struct aml_chunk)); + + aml_add_to_parent(parent, node); + + return node; +} + +void aml_destroy_node(struct aml_chunk* node) +{ + // Delete child nodes + struct aml_chunk* child = node->First; + + while (child) + { + struct aml_chunk* next = child->Next; + + if (child->Buffer) + free(child->Buffer); + + free(child); + + child = next; + } + + // Free node + if (node->Buffer) + free(node->Buffer); + + free(node); +} + +struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_NONE; + node->Length = size; + node->Buffer = malloc(node->Length); + memcpy(node->Buffer, buffer, node->Length); + } + + return node; +} + +struct aml_chunk* aml_add_byte(struct aml_chunk* parent, unsigned char value) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_BYTE; + + node->Length = 1; + node->Buffer = malloc(node->Length); + node->Buffer[0] = value; + } + + return node; +} + +struct aml_chunk* aml_add_word(struct aml_chunk* parent, unsigned int value) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_WORD; + node->Length = 2; + node->Buffer = malloc(node->Length); + node->Buffer[0] = value & 0xff; + node->Buffer[1] = value >> 8; + } + + return node; +} + +struct aml_chunk* aml_add_dword(struct aml_chunk* parent, unsigned long value) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_DWORD; + node->Length = 4; + node->Buffer = malloc(node->Length); + node->Buffer[0] = value & 0xff; + node->Buffer[1] = (value >> 8) & 0xff; + node->Buffer[2] = (value >> 16) & 0xff; + node->Buffer[3] = (value >> 24) & 0xff; + } + + return node; +} + +struct aml_chunk* aml_add_qword(struct aml_chunk* parent, unsigned long long value) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_QWORD; + node->Length = 8; + node->Buffer = malloc(node->Length); + node->Buffer[0] = value & 0xff; + node->Buffer[1] = (value >> 8) & 0xff; + node->Buffer[2] = (value >> 16) & 0xff; + node->Buffer[3] = (value >> 24) & 0xff; + node->Buffer[4] = (value >> 32) & 0xff; + node->Buffer[5] = (value >> 40) & 0xff; + node->Buffer[6] = (value >> 48) & 0xff; + node->Buffer[7] = (value >> 56) & 0xff; + } + + return node; +} + +unsigned int aml_fill_simple_name(char* buffer, const char* name) +{ + if (strlen(name) < 4) + { + verbose("aml_fill_simple_name: simple name %s has incorrect lengh! Must be 4\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...", 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/old749m/i386/libsaio/pci_root.h =================================================================== --- branches/slice/old749m/i386/libsaio/pci_root.h (revision 0) +++ branches/slice/old749m/i386/libsaio/pci_root.h (revision 1174) @@ -0,0 +1,14 @@ +/* + * Copyright 2008 mackerintel + */ + +#ifndef __LIBSAIO_PCI_ROOT_H +#define __LIBSAIO_PCI_ROOT_H + +#include "libsaio.h" + + +extern int getPciRootUID(void); +//unsigned int findpciroot(unsigned char * dsdt,int len); + +#endif /* !__LIBSAIO_DSDT_PATCHER_H */ Index: branches/slice/old749m/i386/libsaio/aml_generator.h =================================================================== --- branches/slice/old749m/i386/libsaio/aml_generator.h (revision 0) +++ branches/slice/old749m/i386/libsaio/aml_generator.h (revision 1174) @@ -0,0 +1,63 @@ +/* + * 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" +//#include "ACPIPatcher.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/old749m/i386/libsaio/memvendors.h =================================================================== --- branches/slice/old749m/i386/libsaio/memvendors.h (revision 0) +++ branches/slice/old749m/i386/libsaio/memvendors.h (revision 1174) @@ -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/old749m/i386/libsaio/msdos_private.h =================================================================== --- branches/slice/old749m/i386/libsaio/msdos_private.h (revision 0) +++ branches/slice/old749m/i386/libsaio/msdos_private.h (revision 1174) @@ -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/old749m/i386/libsaio/table.c =================================================================== --- branches/slice/old749m/i386/libsaio/table.c (revision 0) +++ branches/slice/old749m/i386/libsaio/table.c (revision 1174) @@ -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/old749m/i386/libsaio/device_inject.c =================================================================== --- branches/slice/old749m/i386/libsaio/device_inject.c (revision 0) +++ branches/slice/old749m/i386/libsaio/device_inject.c (revision 1174) @@ -0,0 +1,401 @@ +/* + * 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...) verbose(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=0, cnt2=0; + + static char DEVICE_PROPERTIES_PROP[] = "device-properties"; + + /* Generate devprop string. + */ + uint32_t strlength = 0; + 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->bootConfig) && 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))) { + verbose("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 + { + verbose("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 + { + verbose("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 */ +//Slice - now it is not needed? +int devprop_add_network_template(struct DevPropDevice *device, uint16_t vendor_id) +{ + if(!device) + return 0; + uint8_t builtin = 0x0; + char tmp[10]; + 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; + sprintf(tmp, "Slot-%x",devices_number); // 1 - vga card. FIXME - for 2+ vgas + if(!devprop_add_value(device, "AAPL,slot-name", (uint8_t*)&tmp, strlen(tmp))) + 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/old749m/i386/libsaio/device_inject.h =================================================================== --- branches/slice/old749m/i386/libsaio/device_inject.h (revision 0) +++ branches/slice/old749m/i386/libsaio/device_inject.h (revision 1174) @@ -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 uint32_t devices_number; +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/old749m/i386/libsaio/fdisk.h =================================================================== --- branches/slice/old749m/i386/libsaio/fdisk.h (revision 0) +++ branches/slice/old749m/i386/libsaio/fdisk.h (revision 1174) @@ -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/old749m/i386/libsaio/ntfs.c =================================================================== --- branches/slice/old749m/i386/libsaio/ntfs.c (revision 0) +++ branches/slice/old749m/i386/libsaio/ntfs.c (revision 1174) @@ -0,0 +1,345 @@ +/* + * 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@ + */ +#ifndef OPTION_ROM +#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; +} +#endif \ No newline at end of file Index: branches/slice/old749m/i386/libsaio/ufs_byteorder.c =================================================================== --- branches/slice/old749m/i386/libsaio/ufs_byteorder.c (revision 0) +++ branches/slice/old749m/i386/libsaio/ufs_byteorder.c (revision 1174) @@ -0,0 +1,171 @@ +/* + * 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 +#include +#include +#include +#include +#include "ufs_byteorder.h" +#include "libsaio.h" + +#define swapBigLongToHost(thing) ((thing) = OSSwapBigToHostInt32(thing)) +#define swapBigShortToHost(thing) ((thing) = OSSwapBigToHostInt16(thing)) +#define byte_swap_longlong(thing) ((thing) = OSSwapBigToHostInt64(thing)) +#define byte_swap_int(thing) ((thing) = OSSwapBigToHostInt32(thing)) +#define byte_swap_short(thing) ((thing) = OSSwapBigToHostInt16(thing)) + +#if UNUSED +void +byte_swap_longlongs(unsigned long long *array, int count) +{ + register unsigned long long i; + + for (i = 0; i < (unsigned long long)count; i++) + byte_swap_longlong(array[i]); +} +#endif + +void +byte_swap_ints(unsigned int *array, int count) +{ + register int i; + + for (i = 0; i < count; i++) + byte_swap_int(array[i]); +} + +void +byte_swap_shorts(unsigned short *array, int count) +{ + register int i; + + for (i = 0; i < count; i++) + byte_swap_short(array[i]); +} + +#if UNUSED +static void +swapBigIntsToHost(unsigned int *array, int count) +{ + register int i; + + for (i = 0; i < count; i++) + swapBigLongToHost(array[i]); +} + +static void +swapBigShortToHosts(unsigned short *array, int count) +{ + register int i; + + for (i = 0; i < count; i++) + swapBigShortToHost(array[i]); +} +#endif + +void +byte_swap_superblock(struct fs *sb) +{ + u_int16_t * usptr; + unsigned long size; + + byte_swap_ints(((u_int32_t *)&sb->fs_firstfield), 52); + byte_swap_int(sb->fs_cgrotor); + byte_swap_int(sb->fs_cpc); + byte_swap_shorts((u_int16_t *)sb->fs_opostbl, 16 * 8); + byte_swap_ints((u_int32_t *)sb->fs_sparecon, 50); + byte_swap_ints((u_int32_t *)&sb->fs_contigsumsize, 3); +#if UNUSED + byte_swap_longlongs((u_int64_t *)&sb->fs_maxfilesize,3); +#endif + byte_swap_ints((u_int32_t *)&sb->fs_state, 6); + + /* Got these magic numbers from mkfs.c in newfs */ + if (sb->fs_nrpos != 8 || sb->fs_cpc > 16) { + usptr = (u_int16_t *)((u_int8_t *)(sb) + (sb)->fs_postbloff); + size = sb->fs_cpc * sb->fs_nrpos; + byte_swap_shorts(usptr,size); /* fs_postbloff */ + } +} + + +/* This value should correspond to the value set in the ffs_mounts */ + +#define RESYMLNKLEN 60 + +void +byte_swap_dinode_in(struct dinode *di) +{ + int i; + + di->di_mode = OSSwapInt16(di->di_mode); + di->di_nlink = OSSwapInt16(di->di_nlink); +#ifdef LFS + di->di_u.inumber = OSSwapInt32(di->di_u.inumber); +#else + di->di_u.oldids[0] = OSSwapInt16(di->di_u.oldids[0]); + di->di_u.oldids[1] = OSSwapInt16(di->di_u.oldids[1]); +#endif + di->di_size = OSSwapInt64(di->di_size); + di->di_atime = OSSwapInt32(di->di_atime); + di->di_atimensec = OSSwapInt32(di->di_atimensec); + di->di_mtime = OSSwapInt32(di->di_mtime); + di->di_mtimensec = OSSwapInt32(di->di_mtimensec); + di->di_ctime = OSSwapInt32(di->di_ctime); + di->di_ctimensec = OSSwapInt32(di->di_ctimensec); + if (((di->di_mode & IFMT) != IFLNK ) || (di->di_size > RESYMLNKLEN)) { + for (i=0; i < NDADDR; i++) /* direct blocks */ + di->di_db[i] = OSSwapInt32(di->di_db[i]); + for (i=0; i < NIADDR; i++) /* indirect blocks */ + di->di_ib[i] = OSSwapInt32(di->di_ib[i]); + } + di->di_flags = OSSwapInt32(di->di_flags); + di->di_blocks = OSSwapInt32(di->di_blocks); + di->di_gen = OSSwapInt32(di->di_gen); + di->di_uid = OSSwapInt32(di->di_uid); + di->di_gid = OSSwapInt32(di->di_gid); + di->di_spare[0] = OSSwapInt32(di->di_spare[0]); + di->di_spare[1] = OSSwapInt32(di->di_spare[1]); +} + +void +byte_swap_dir_block_in(char *addr, int count) +{ + register struct direct * ep = (struct direct *) addr; + register int entryoffsetinblk = 0; + + while (entryoffsetinblk < count) { + ep = (struct direct *) (entryoffsetinblk + addr); + swapBigLongToHost(ep->d_ino); + swapBigShortToHost(ep->d_reclen); + entryoffsetinblk += ep->d_reclen; + if (ep->d_reclen < 12) /* handle garbage in dirs */ + break; + } +} Index: branches/slice/old749m/i386/libsaio/sys.c =================================================================== --- branches/slice/old749m/i386/libsaio/sys.c (revision 0) +++ branches/slice/old749m/i386/libsaio/sys.c (revision 1174) @@ -0,0 +1,1139 @@ +/* + * 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 + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "disk.h" +#include "ramdisk.h" +#include "xml.h" +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +# include +#else +# include +#endif +#include +#if 0 /* No OS X release has ever included this. */ +#include +#else +/* copied from uuid/namespace.h, just like BootX's fs.c does. */ +UUID_DEFINE( kFSUUIDNamespaceSHA1, 0xB3, 0xE2, 0x0F, 0x39, 0xF2, 0x92, 0x11, 0xD6, 0x97, 0xA4, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC ); +#endif + +#ifdef UNUSED +extern int multiboot_partition; +extern int multiboot_partition_set; +#endif + +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) { + 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) { + verbose("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 (MAX = %d)", NFILES); + // 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) + { +#ifndef OPTION_ROM + bvr = nbpScanBootVolumes(biosdev, count); + if (bvr != NULL) + { + gBootFileType = kNetworkDeviceType; + } +#endif + } + 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); + verbose("scanVolume %d\n", hd); + + hd++; + } + + // Also scanning CD/DVD drive. + // if (biosDevIsCDROM(gBIOSDev)) + if (biosDevIsCDROM(gBIOSDev)) // 0 = CDROM + { + bvCount = 0; + //scanBootVolumes(gBIOSDev, &bvCount); + scanBootVolumes(gBIOSDev, &bvCount); + msglog("biosDevIsCDROM and bvCount=%d\n", bvCount); + } + + *count = bvCount; //Slice - ! + +} + +//========================================================================== + +BVRef selectBootVolume( BVRef chain ) +{ + bool filteredChain = false; + bool foundPrimary = false; + BVRef bvr, bvr1 = 0, bvr2 = 0; + + if (chain->filtered) filteredChain = true; + +#ifdef UNUSED + if (multiboot_partition_set) + for ( bvr = chain; bvr; bvr = bvr->next ){ + msglog("Check muiltiboot: biosdev=%d type=0x%x flags=0x%x part_no=%d\n", + bvr->biosdev, bvr->type, bvr->flags, bvr->part_no); + if ( bvr->part_no == multiboot_partition && bvr->biosdev == gBIOSDev ) + return bvr; + } +#endif + /* + * 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->bootConfig)); + if (val) { + for ( bvr = chain; bvr; bvr = bvr->next ) { + if (matchVolumeToString(bvr, val, false)) { + free(val); + return bvr; + } + } + free(val); + } + + /* + * Scannig the volume chain backwards and trying to find + * a HFS+ volume with valid boot record signature. + * If not found any active partition then we will + * select this volume as the boot volume. + */ + for ( bvr = chain; bvr; bvr = bvr->next ) + { +// msglog("scanning chain: biosdev=%d type=0x%x flags=0x%x part_no=%d\n", +// bvr->biosdev, bvr->type, bvr->flags, bvr->part_no); + 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 standard 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; + } + //msglog("foundPrimary and flags bvr1=%x bvr2=%x\n", bvr1->flags, bvr2->flags);//foundPrimary and flags bvr1=a bvr2=4b + } + + 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. +#ifndef OPTION_ROM + if (biosdev == kPseudoBIOSDevRAMDisk) + { + if (gRAMDiskVolume) + bvr1 = gRAMDiskVolume; + } + else +#endif + if (biosdev == kPseudoBIOSDevBooter) + { +#ifndef OPTION_ROM + if (gRAMDiskVolume != NULL && gRAMDiskBTAliased) + bvr1 = gRAMDiskVolume; + else +#endif + 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/old749m/i386/libsaio/load.c =================================================================== --- branches/slice/old749m/i386/libsaio/load.c (revision 0) +++ branches/slice/old749m/i386/libsaio/load.c (revision 1174) @@ -0,0 +1,343 @@ +/* + * 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); + + +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 + verbose("magic: %x\n", (unsigned)mH->magic); + verbose("cputype: %x\n", (unsigned)mH->cputype); + verbose("cpusubtype: %x\n", (unsigned)mH->cpusubtype); + verbose("filetype: %x\n", (unsigned)mH->filetype); + verbose("ncmds: %x\n", (unsigned)mH->ncmds); + verbose("sizeofcmds: %x\n", (unsigned)mH->sizeofcmds); + verbose("flags: %x\n", (unsigned)mH->flags); + getc(); +#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 + verbose("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; + } + 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; + } + + if (vmsize == 0 || filesize == 0) { + *load_addr = ~0; + *load_size = 0; + return 0; + } + +#if DEBUG + verbose("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); + getc(); +#endif + + 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") == 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); + + #if defined(__DARWIN_UNIX03) && __DARWIN_UNIX03 + *entry = i386ThreadState->__eip; + #else + *entry = i386ThreadState->eip; + #endif + 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); + + #if defined(__DARWIN_UNIX03) && __DARWIN_UNIX03 + *entry = x86_64ThreadState->__rip; + #else + *entry = x86_64ThreadState->rip; + #endif + 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 + verbose("symoff: %x, nsyms: %x, stroff: %x, strsize: %x\n", + symTab->symoff, symTab->nsyms, symTab->stroff, symTab->strsize); + getc (); +#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/old749m/i386/libsaio/nbp.c =================================================================== --- branches/slice/old749m/i386/libsaio/nbp.c (revision 0) +++ branches/slice/old749m/i386/libsaio/nbp.c (revision 1174) @@ -0,0 +1,146 @@ +/* + * 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 OPTION_ROM +#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 +#endif Index: branches/slice/old749m/i386/libsaio/ntfs.h =================================================================== --- branches/slice/old749m/i386/libsaio/ntfs.h (revision 0) +++ branches/slice/old749m/i386/libsaio/ntfs.h (revision 1174) @@ -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/old749m/i386/libsaio/ufs_byteorder.h =================================================================== --- branches/slice/old749m/i386/libsaio/ufs_byteorder.h (revision 0) +++ branches/slice/old749m/i386/libsaio/ufs_byteorder.h (revision 1174) @@ -0,0 +1,56 @@ +/* + * 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 +#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/old749m/i386/libsaio/acpi.h =================================================================== --- branches/slice/old749m/i386/libsaio/acpi.h (revision 0) +++ branches/slice/old749m/i386/libsaio/acpi.h (revision 1174) @@ -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/old749m/i386/libsaio/sl.h =================================================================== --- branches/slice/old749m/i386/libsaio/sl.h (revision 0) +++ branches/slice/old749m/i386/libsaio/sl.h (revision 1174) @@ -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/old749m/i386/libsaio/platform.c =================================================================== --- branches/slice/old749m/i386/libsaio/platform.c (revision 0) +++ branches/slice/old749m/i386/libsaio/platform.c (revision 1174) @@ -0,0 +1,59 @@ +/* + * platform.c + * + * AsereBLN: cleanup + */ + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "pci.h" +#include "platform.h" +//#include "cpu.h" +#include "modules.h" +#include "efi.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; +BLESS_EFI_LOAD_OPTION* BootOrder; +/** 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; + + execute_hook("ScanMemory", NULL, NULL, NULL, NULL); + 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/old749m/i386/libsaio/cpu.c =================================================================== --- branches/slice/old749m/i386/libsaio/cpu.c (revision 0) +++ branches/slice/old749m/i386/libsaio/cpu.c (revision 1174) @@ -0,0 +1,546 @@ +/* + * Copyright 2008 Islam Ahmed Zaid. All rights reserved. + * AsereBLN: 2009: cleanup and bugfix + */ + +#include "libsaio.h" +#include "platform.h" +//#include "mem.h" +#include "smbios_patcher.h" +#include "cpu.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) +{ + PlatformInfo_t *p = Platform; + int i = 0; + uint8_t turbo = 0; + uint64_t tscFrequency, fsbFrequency, cpuFrequency; + uint64_t msr; //, flex_ratio; + uint8_t maxcoef, maxdiv, currcoef, currdiv, mindiv; + + maxcoef = maxdiv = currcoef = currdiv = mindiv = 0; + +#if DEBUG_CPU + printf("Enter cpuid_info\n"); + pause(); +#endif + cpuid_update_generic_info(); + +#if DEBUG_CPU + printf("...OK\n"); + pause(); +#endif + +#if OLDMETHOD + /* get cpuid values */ + for( ; i <= 3; i++) + { + do_cpuid(i, p->CPU.CPUID[i]); + } + + 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; + DBG("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.NoThreads = bitfield(p->CPU.CPUID[CPUID_1][1], 23, 16); + p->CPU.NoCores = bitfield(p->CPU.CPUID[CPUID_4][0], 31, 26) + 1; + + p->CPU.Model += (p->CPU.ExtModel << 4); + + /* get brand string (if supported) */ + /* Copyright: from Apple's XNU cpuid.c */ + if (p->CPU.CPUID[CPUID_80][0] > 0x80000004) { + uint32_t reg[4]; + char str[128], *s; + /* + * The brand string 48 bytes (max), guaranteed to + * be NUL terminated. + */ + do_cpuid(0x80000002, reg); + bcopy((char *)reg, &str[0], 16); + do_cpuid(0x80000003, reg); + bcopy((char *)reg, &str[16], 16); + do_cpuid(0x80000004, reg); + bcopy((char *)reg, &str[32], 16); + for (s = str; *s != '\0'; s++) { + if (*s != ' ') break; + } + + strlcpy(p->CPU.BrandString, s, sizeof(p->CPU.BrandString)); + + if (!strncmp(p->CPU.BrandString, CPU_STRING_UNKNOWN, min(sizeof(p->CPU.BrandString), strlen(CPU_STRING_UNKNOWN) + 1))) { + /* + * This string means we have a firmware-programmable brand string, + * and the firmware couldn't figure out what sort of CPU we have. + */ + p->CPU.BrandString[0] = '\0'; + } + } + + /* setup features */ + p->CPU.Features |= (CPU_FEATURE_MMX | CPU_FEATURE_SSE | CPU_FEATURE_SSE2 | CPU_FEATURE_MSR) & p->CPU.CPUID[CPUID_1][3]; + p->CPU.Features |= (CPU_FEATURE_SSE3 | CPU_FEATURE_SSE41 | CPU_FEATURE_SSE42) & p->CPU.CPUID[CPUID_1][2]; + p->CPU.Features |= (CPU_FEATURE_EM64T) & p->CPU.CPUID[CPUID_81][3]; + + + //if ((CPU_FEATURE_HTT & p->CPU.CPUID[CPUID_1][3]) != 0) { + if (p->CPU.NoThreads > p->CPU.NoCores) { + p->CPU.Features |= CPU_FEATURE_HTT; + } +#else //Slice + p->CPU.Vendor = *(UInt32*)&cpuid_info()->cpuid_vendor; + p->CPU.Signature = cpuid_info()->cpuid_signature; + p->CPU.Stepping = cpuid_info()->cpuid_stepping; + p->CPU.Model = cpuid_info()->cpuid_model; + p->CPU.Family = cpuid_info()->cpuid_family; + p->CPU.ExtModel = cpuid_info()->cpuid_extmodel; + p->CPU.ExtFamily = cpuid_info()->cpuid_extfamily; +// 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); + + strlcpy(p->CPU.BrandString, cpuid_info()->cpuid_brand_string, sizeof(p->CPU.BrandString)); + DBG("CPU: BrandString %s\n", p->CPU.BrandString); + p->CPU.Features = cpuid_info()->cpuid_features; + p->CPU.NoCores = cpuid_info()->core_count; + p->CPU.NoThreads = cpuid_info()->thread_count; +// DBG("CPU: MaxCoef/CurrCoef: 0x%x/0x%x\n", p->CPU.MaxCoef, p->CPU.CurrCoef); +// 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 + +#endif + + tscFrequency = measure_tsc_frequency(); + DBG("measure_tsc_frequency = %dMHz\n", tscFrequency / MEGA); + fsbFrequency = 0; + cpuFrequency = 0; + + if ((p->CPU.Vendor == 0x756E6547 /* Intel */) && + ((p->CPU.Family == 0x06) || + (p->CPU.Family == 0x0f))) + { + if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || + (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03)) + { + /* Nehalem CPU model */ + if (p->CPU.Family == 0x06 && (p->CPU.Model == 0x1a || p->CPU.Model == 0x1e || + p->CPU.Model == 0x1f || p->CPU.Model == 0x25 || + p->CPU.Model == 0x19 || p->CPU.Model == 0x2c)) + { + msr = rdmsr64(MSR_PLATFORM_INFO); + DBG("msr(0x%04x): platform_info %08x-%08x\n", MSR_PLATFORM_INFO, + (msr >> 32) & 0xffffffff, msr & 0xffffffff); + mindiv = (msr >> 40) & 0xff; + maxcoef = (msr >> 8) & 0xff; + + msr = rdmsr64(MSR_TURBO_RATIO); + turbo = msr & 0x7f; + //Slice - doesn't work + /* + 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; + if (currcoef > flex_ratio) { + currcoef = flex_ratio; + } + }*/ + msr = rdmsr64(MSR_IA32_PERF_STATUS); + if (msr) { + currcoef = msr & 0x1f; + } + + if (!currcoef) { + currcoef = maxcoef; + } + + if (currcoef < mindiv) { + currcoef = mindiv; + } + + if (currcoef) { + fsbFrequency = (tscFrequency / currcoef); + } + cpuFrequency = tscFrequency; + } + else //not nehalem + { + //Slice - it is not FSB frequency. It is System Bus Speed: FSB = SBS * 4; + if (p->CPU.Family != 0x0d){ + msr = rdmsr64(MSR_FSB_FREQ); + switch (msr & 7) { + case 0: + fsbFrequency = 266670 * 1000; + break; + case 1: + fsbFrequency = 133330 * 1000; + break; + case 2: + fsbFrequency = 200000 * 1000; + break; + case 3: + fsbFrequency = 166670 * 1000; + break; + case 4: + fsbFrequency = 333330 * 1000; + break; + case 5: + fsbFrequency = 200000 * 1000; + break; + case 6: + fsbFrequency = 400000 * 1000; + break; + default: + fsbFrequency = 0; + break; + } + DBG("msr(0x%04x): MSR_FSB_FREQ %d.%dMHz\n", MSR_FSB_FREQ, + fsbFrequency/MEGA, (fsbFrequency%MEGA)/1000); + } + + msr = rdmsr64(MSR_PLATFORM_INFO); //info only? + uint32_t m2 = msr >> 32; + DBG("msr(0x%04x): platform_info %08x-%08x\n", MSR_PLATFORM_INFO, + m2 & 0xffffffff, msr & 0xffffffff); + turbo = (m2 >> 8) & 0x1f; + + msr = rdmsr64(MSR_IA32_PERF_STATUS); + m2 = msr >> 32; + DBG("msr(0x%04x): MSR_IA32_PERF_STATUS %08x-%08x\n", MSR_IA32_PERF_STATUS, + m2 & 0xffffffff, msr & 0xffffffff); + + currcoef = (msr >> 8) & 0x1f; + mindiv = (msr >> 24) & 0xf; + if (currcoef < mindiv) { + currcoef = mindiv; + } + + /* 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 (!fsbFrequency) { + 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; + } + } +#endif + else if(p->CPU.Vendor == 0x746e6543 && p->CPU.Family == 6) + { + switch (p->CPU.Model) { + case CPU_VIA_NANO: + // NOTE: TSC is constant, irrelevent of speed steping + break; + default: + break; + } + + msr = rdmsr64(MSR_NANO_FCR2); + verbose("MSR_IA32_EBL_CR_POWERON Returns 0x%X 0x%X\n", msr >> 32, msr & 0xffffffff); + + //msr = msr >> 32; + msr |= VIA_ALTERNATIVE_VENDOR_BIT; + //msr = msr << 32; + + verbose("MSR_IA32_EBL_CR_POWERON Returns 0x%X 0x%X\n", msr >> 32, msr & 0xffffffff); + wrmsr64(MSR_NANO_FCR2, msr); + msr = rdmsr64(MSR_NANO_FCR2); + verbose("MSR_IA32_EBL_CR_POWERON Returns 0x%X 0x%X\n", msr >> 32, msr & 0xffffffff); + + + /* get cpuid values */ + for( ; i <= 3; i++) + { + do_cpuid(i, p->CPU.CPUID[i]); + } + //int numcpuid_supported = p->CPU.CPUID[CPUID_0][0]; // max number cpuid call + //int numextcpuid = p->CPU.CPUID[CPUID_80][0]; + //p->CPU.Features = 0; + // bitfield(p->CPU.CPUID[CPUID_1][1], 0, 0) FEATURE_C + + // CPUID_0 -> largest cpuid val in EAX + // CPUID_0 -> rem = vendor string + /* + CPUID_1 EDX: + 0 -> FPU + 1 -> VME + 2 -> DE + 3 -> PSE + 4 -> TSC + 5 -> MSR + 6 -> PAE + 7 -> MCE + 8 -> CX8 + 9 -> APIC + 10 -> Reserved + 11 -> Fast Call + 12 -> MTTR + 13 -> PGE + 14 -> MCA + 15 -> CMOV + 16 -> PAT + 17 -> PSE36 + 18 -> Serial Number + 23 -> MMX + 24 -> FXSR + 25 -> SSE + */ + + //CPUID_80 -> largest excpuid value in EAX + //CPUID_81,EAX -> Signature + //CPUID_80,EDX -> Ext Features + //CPUID_82 -> CPU String + //CPUID_83 -> CPU String + //CPUID_84 -> CPU String + p->CPU.NoThreads = p->CPU.NoCores; + + } + + if (!fsbFrequency) { + fsbFrequency = (DEFAULT_FSB * 1000); + cpuFrequency = tscFrequency; + msglog("CPU: fsb=0 ! using the default value 100MHz !\n"); + } + +/* + 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.NoThreads = bitfield(p->CPU.CPUID[CPUID_1][1], 23, 16); +*/ + + + p->CPU.MaxCoef = turbo; + p->CPU.MaxDiv = maxdiv; + p->CPU.MinCoef = mindiv; + 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, turbo); + 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/old749m/i386/libsaio/platform.h =================================================================== --- branches/slice/old749m/i386/libsaio/platform.h (revision 0) +++ branches/slice/old749m/i386/libsaio/platform.h (revision 1174) @@ -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 +#define CPU_MODEL_MEROM 0x0F +#define CPU_MODEL_PENRYN 0x17 +#define CPU_MODEL_NEHALEM 0x1A +#define CPU_MODEL_ATOM 0x1C +#define CPU_MODEL_FIELDS 0x1E /* Lynnfield, Clarksfield, Jasper */ +#define CPU_MODEL_DALES 0x1F /* Havendale, Auburndale */ +#define CPU_MODEL_DALES_32NM 0x25 /* Clarkdale, Arrandale */ +#define CPU_MODEL_WESTMERE 0x2C /* Gulftown, Westmere-EP, Westmere-WS */ +#define CPU_MODEL_NEHALEM_EX 0x2E +#define CPU_MODEL_WESTMERE_EX 0x2F + +/* CPU Features */ +// NOTE: Theses are currently mapped to the actual bit in the cpuid value +#define CPU_FEATURE_MMX bit(23) // MMX Instruction Set +#define CPU_FEATURE_SSE bit(25) // SSE Instruction Set +#define CPU_FEATURE_SSE2 bit(26) // SSE2 Instruction Set +#define CPU_FEATURE_SSE3 bit(0) // SSE3 Instruction Set +#define CPU_FEATURE_SSE41 bit(19) // SSE41 Instruction Set +#define CPU_FEATURE_SSE42 bit(20) // SSE42 Instruction Set +#define CPU_FEATURE_EM64T bit(29) // 64Bit Support +#define CPU_FEATURE_HTT bit(28) // HyperThreading +#define CPU_FEATURE_MSR bit(5) // MSR Support + +// NOTE: Determine correct bit for bellow (28 is already in use) +#define CPU_FEATURE_MOBILE bit(1) // Mobile CPU +//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 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 polulated 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/old749m/i386/libsaio/disk.c =================================================================== --- branches/slice/old749m/i386/libsaio/disk.c (revision 0) +++ branches/slice/old749m/i386/libsaio/disk.c (revision 1174) @@ -0,0 +1,2027 @@ +/* + * 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. + */ + +// Allow UFS_SUPPORT to be overridden with preprocessor option. +#ifndef UFS_SUPPORT +// zef: Disabled UFS support +#define UFS_SUPPORT 0 +#endif + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "fdisk.h" +#if UFS_SUPPORT +#include "ufs.h" +#endif +#include "hfs.h" +#include "ntfs.h" +#include "msdos.h" +#include "ext2fs.h" + +#include "xml.h" +#include "disk.h" + +#include +#include +#include +typedef struct gpt_hdr gpt_hdr; +typedef struct gpt_ent gpt_ent; + +// For EFI_GUID +#include "efi.h" +#include "efi_tables.h" + +#define BPS 512 /* sector size of the device */ +#define PROBEFS_SIZE BPS * 4 /* buffer size for filesystem probe */ +#define CD_BPS 2048 /* CD-ROM block size */ +#define N_CACHE_SECS (BIOS_LEN / BPS) /* Must be a multiple of 4 for CD-ROMs */ +#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); +} + +//========================================================================== + +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; +} + +//========================================================================== + +// HFS+ GUID in LE form +EFI_GUID const GPT_HFS_GUID = { 0x48465300, 0x0000, 0x11AA, 0xAA, 0x11, {0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC } }; +// turbo - also our booter partition +EFI_GUID const GPT_BOOT_GUID = { 0x426F6F74, 0x0000, 0x11AA, 0xAA, 0x11, {0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC } }; +// turbo - or an efi system partition +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 } }; +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; + verbose("diskScanFDiskBootVolumes %d\n", biosdev); + /* 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; +#ifndef OPTION_ROM + 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; +#endif + 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; +#ifndef OPTION_ROM + else if (EX2Probe(probeBuffer)) + result = FDISK_LINUX; + else if (NTFSProbe(probeBuffer)) + result = FDISK_NTFS; +#endif + 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) + { +#ifndef OPTION_ROM + 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; +#endif + 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; + } + + } +} +#ifndef OPTION_ROM +void rescanBIOSDevice(int biosdev) +{ + struct DiskBVMap *oldMap = diskResetBootVolumes(biosdev); + CacheReset(); + diskFreeMap(oldMap); + oldMap = NULL; + scanBootVolumes(biosdev, 0); +} +#endif + +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->bootConfig); + 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 + for (bvr = chain; bvr; bvr = bvr->next) + { + msglog(" bvr: %x, dev: %x, part: %d, flags: %x, vis: %d\n", bvr, bvr->biosdev, bvr->part_no, bvr->flags, bvr->visible); + } + msglog("count: %d\n", bvCount); +// getc(); +#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[] = +{ +#ifndef OPTION_ROM + { FDISK_NTFS, "Windows NTFS" }, +#endif + { FDISK_DOS12, "Windows FAT12" }, + { FDISK_DOS16B, "Windows FAT16" }, + { FDISK_DOS16S, "Windows FAT16" }, + { FDISK_DOS16SLBA, "Windows FAT16" }, + { FDISK_SMALLFAT32, "Windows FAT32" }, + { FDISK_FAT32, "Windows FAT32" }, +#ifndef OPTION_ROM + { FDISK_LINUX, "Linux" }, +#endif + { 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" etc; ... + */ + +bool getVolumeLabelAlias(BVRef bvr, char* str, long strMaxLen) +{ + char *aliasList, *entryStart, *entryNext; + + if ( !str || strMaxLen <= 0) + return false; + + aliasList = XMLDecode(getStringForKey(kRenamePartition, &bootInfo->bootConfig)); + if ( !aliasList ) + return false; + + for ( entryStart = entryNext = aliasList; + entryNext && *entryNext; + entryStart = entryNext ) + { + char *volStart, *volEnd, *aliasStart; + long volLen, aliasLen; + + // Delimit current entry + entryNext = strchr(entryStart, ';'); + if ( entryNext ) + { + *entryNext = '\0'; + entryNext++; + } + + volStart = strbreak(entryStart, &volEnd, &volLen); + if(!volLen) + continue; + + aliasStart = strbreak(volEnd, 0, &aliasLen); + if(!aliasLen) + continue; + + if ( matchVolumeToString(bvr, volStart, volLen) ) + { + strncat(str, aliasStart, min(strMaxLen, aliasLen)); + free(aliasList); + + return true; + } + } + + free(aliasList); + return false; +} + +void getBootVolumeDescription( BVRef bvr, char * str, long strMaxLen, bool 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 ); +} +#ifndef OPTION_ROM + +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; +} +#endif + +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/old749m/i386/libsaio/pci_setup.c =================================================================== --- branches/slice/old749m/i386/libsaio/pci_setup.c (revision 0) +++ branches/slice/old749m/i386/libsaio/pci_setup.c (revision 1174) @@ -0,0 +1,29 @@ +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "pci.h" +#include "modules.h" + +#define DEBUG_PCI 0 + +#if DEBUG_PCI +#define DBG(x...) msglog(x) +#else +#define DBG(x...) +#endif + + +void setup_pci_devs(pci_dt_t *pci_dt) +{ + pci_dt_t *current = pci_dt; + + + while (current) + { + 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/old749m/i386/libsaio/cpu.h =================================================================== --- branches/slice/old749m/i386/libsaio/cpu.h (revision 0) +++ branches/slice/old749m/i386/libsaio/cpu.h (revision 1174) @@ -0,0 +1,551 @@ +/* + * Copyright 2008 Islam Ahmed Zaid. All rights reserved. + * AsereBLN: 2009: cleanup and bugfix + */ + +#ifndef __LIBSAIO_CPU_H +#define __LIBSAIO_CPU_H + +#include "libsaio.h" + +#define CPU_VIA_C3 0x07 +#define CPU_VIA_C3_Ezra_T 0x08 + +#define CPU_VIA_NANO 0x0F + + + +extern void scan_cpu(); //PlatformInfo_t *); + +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define quad(hi,lo) (((uint64_t)(hi)) << 32 | (lo)) + + +#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) + +#define CPUID_VID_INTEL "GenuineIntel" +#define CPUID_VID_AMD "AuthenticAMD" + +#define CPUID_STRING_UNKNOWN "Unknown CPU Typ" + +#define _Bit(n) (1ULL << n) +#define _HBit(n) (1ULL << ((n)+32)) + +/* + * The CPUID_FEATURE_XXX values define 64-bit values + * returned in %ecx:%edx to a CPUID request with %eax of 1: + */ +#define CPUID_FEATURE_FPU _Bit(0) /* Floating point unit on-chip */ +#define CPUID_FEATURE_VME _Bit(1) /* Virtual Mode Extension */ +#define CPUID_FEATURE_DE _Bit(2) /* Debugging Extension */ +#define CPUID_FEATURE_PSE _Bit(3) /* Page Size Extension */ +#define CPUID_FEATURE_TSC _Bit(4) /* Time Stamp Counter */ +#define CPUID_FEATURE_MSR _Bit(5) /* Model Specific Registers */ +#define CPUID_FEATURE_PAE _Bit(6) /* Physical Address Extension */ +#define CPUID_FEATURE_MCE _Bit(7) /* Machine Check Exception */ +#define CPUID_FEATURE_CX8 _Bit(8) /* CMPXCHG8B */ +#define CPUID_FEATURE_APIC _Bit(9) /* On-chip APIC */ +#define CPUID_FEATURE_SEP _Bit(11) /* Fast System Call */ +#define CPUID_FEATURE_MTRR _Bit(12) /* Memory Type Range Register */ +#define CPUID_FEATURE_PGE _Bit(13) /* Page Global Enable */ +#define CPUID_FEATURE_MCA _Bit(14) /* Machine Check Architecture */ +#define CPUID_FEATURE_CMOV _Bit(15) /* Conditional Move Instruction */ +#define CPUID_FEATURE_PAT _Bit(16) /* Page Attribute Table */ +#define CPUID_FEATURE_PSE36 _Bit(17) /* 36-bit Page Size Extension */ +#define CPUID_FEATURE_PSN _Bit(18) /* Processor Serial Number */ +#define CPUID_FEATURE_CLFSH _Bit(19) /* CLFLUSH Instruction supported */ +#define CPUID_FEATURE_DS _Bit(21) /* Debug Store */ +#define CPUID_FEATURE_ACPI _Bit(22) /* Thermal monitor and Clock Ctrl */ +#define CPUID_FEATURE_MMX _Bit(23) /* MMX supported */ +#define CPUID_FEATURE_FXSR _Bit(24) /* Fast floating pt save/restore */ +#define CPUID_FEATURE_SSE _Bit(25) /* Streaming SIMD extensions */ +#define CPUID_FEATURE_SSE2 _Bit(26) /* Streaming SIMD extensions 2 */ +#define CPUID_FEATURE_SS _Bit(27) /* Self-Snoop */ +#define CPUID_FEATURE_HTT _Bit(28) /* Hyper-Threading Technology */ +#define CPUID_FEATURE_TM _Bit(29) /* Thermal Monitor (TM1) */ +#define CPUID_FEATURE_PBE _Bit(31) /* Pend Break Enable */ + +#define CPUID_FEATURE_SSE3 _HBit(0) /* Streaming SIMD extensions 3 */ +#define CPUID_FEATURE_PCLMULQDQ _HBit(1) /* PCLMULQDQ Instruction */ + +#define CPUID_FEATURE_MONITOR _HBit(3) /* Monitor/mwait */ +#define CPUID_FEATURE_DSCPL _HBit(4) /* Debug Store CPL */ +#define CPUID_FEATURE_VMX _HBit(5) /* VMX */ +#define CPUID_FEATURE_SMX _HBit(6) /* SMX */ +#define CPUID_FEATURE_EST _HBit(7) /* Enhanced SpeedsTep (GV3) */ +#define CPUID_FEATURE_TM2 _HBit(8) /* Thermal Monitor 2 */ +#define CPUID_FEATURE_SSSE3 _HBit(9) /* Supplemental SSE3 instructions */ +#define CPUID_FEATURE_CID _HBit(10) /* L1 Context ID */ + +#define CPUID_FEATURE_CX16 _HBit(13) /* CmpXchg16b instruction */ +#define CPUID_FEATURE_xTPR _HBit(14) /* Send Task PRiority msgs */ +#define CPUID_FEATURE_PDCM _HBit(15) /* Perf/Debug Capability MSR */ + +#define CPUID_FEATURE_DCA _HBit(18) /* Direct Cache Access */ +#define CPUID_FEATURE_SSE4_1 _HBit(19) /* Streaming SIMD extensions 4.1 */ +#define CPUID_FEATURE_SSE4_2 _HBit(20) /* Streaming SIMD extensions 4.2 */ +#define CPUID_FEATURE_xAPIC _HBit(21) /* Extended APIC Mode */ +#define CPUID_FEATURE_POPCNT _HBit(23) /* POPCNT instruction */ +#define CPUID_FEATURE_AES _HBit(25) /* AES instructions */ +#define CPUID_FEATURE_VMM _HBit(31) /* VMM (Hypervisor) present */ + +/* + * The CPUID_EXTFEATURE_XXX values define 64-bit values + * returned in %ecx:%edx to a CPUID request with %eax of 0x80000001: + */ +#define CPUID_EXTFEATURE_SYSCALL _Bit(11) /* SYSCALL/sysret */ +#define CPUID_EXTFEATURE_XD _Bit(20) /* eXecute Disable */ +#define CPUID_EXTFEATURE_1GBPAGE _Bit(26) /* 1G-Byte Page support */ +#define CPUID_EXTFEATURE_RDTSCP _Bit(27) /* RDTSCP */ +#define CPUID_EXTFEATURE_EM64T _Bit(29) /* Extended Mem 64 Technology */ + +//#define CPUID_EXTFEATURE_LAHF _HBit(20) /* LAFH/SAHF instructions */ +// New definition with Snow kernel +#define CPUID_EXTFEATURE_LAHF _HBit(0) /* LAHF/SAHF instructions */ +/* + * The CPUID_EXTFEATURE_XXX values define 64-bit values + * returned in %ecx:%edx to a CPUID request with %eax of 0x80000007: + */ +#define CPUID_EXTFEATURE_TSCI _Bit(8) /* TSC Invariant */ + +#define CPUID_CACHE_SIZE 16 /* Number of descriptor values */ + +#define CPUID_MWAIT_EXTENSION _Bit(0) /* enumeration of WMAIT extensions */ +#define CPUID_MWAIT_BREAK _Bit(1) /* interrupts are break events */ + + + + +#define MSR_IA32_PLATFORM_ID 0x0017 +#define MSR_P4_EBC_FREQUENCY_ID 0x002C +#define MSR_CORE_THREAD_COUNT 0x0035 +#define MSR_IA32_PERF_STATUS 0x0198 +#define MSR_IA32_PERF_CONTROL 0x0199 +#define MSR_IA32_EXT_CONFIG 0x00EE +#define MSR_FLEX_RATIO 0x0194 //Slice - not used +#define MSR_FSB_FREQ 0x00CD //Slice - not used +#define MSR_PLATFORM_INFO 0x00CE // for i7 it gives min and max +#define MSR_TURBO_RATIO 0x01AD //Slice - for i7 +#define MSR_IA32_EBL_CR_POWERON 0x002A //Meklort - for VIA +#define K8_FIDVID_STATUS 0xC0010042 +#define K10_COFVID_STATUS 0xC0010071 + +/* Centaur-Hauls/IDT defined MSRs. */ +#define MSR_IDT_FCR1 0x00000107 +#define MSR_IDT_FCR2 0x00000108 +#define MSR_IDT_FCR3 0x00000109 +#define MSR_IDT_FCR4 0x0000010a + +#define MSR_IDT_MCR0 0x00000110 +#define MSR_IDT_MCR1 0x00000111 +#define MSR_IDT_MCR2 0x00000112 +#define MSR_IDT_MCR3 0x00000113 +#define MSR_IDT_MCR4 0x00000114 +#define MSR_IDT_MCR5 0x00000115 +#define MSR_IDT_MCR6 0x00000116 +#define MSR_IDT_MCR7 0x00000117 +#define MSR_IDT_MCR_CTRL 0x00000120 + +/* VIA Nano defined MSTs */ +#define MSR_NANO_FCR1 0x1204 // This MSR contains control bits and family, model, etc. +#define MSR_NANO_FCR2 0x1206 // This MSR contains part of the vendor string +#define MSR_NANO_FCR3 0x1207 // This MSR contains part of the vendor string +#define VIA_ALTERNATIVE_VENDOR_BIT (1 << 8) // This bit in MSR_IDT_FCR1 enables alternative vendor string + +/* VIA Cyrix defined MSRs */ +#define MSR_VIA_FCR 0x00001107 +#define MSR_VIA_LONGHAUL 0x0000110a +#define MSR_VIA_RNG 0x0000110b +#define MSR_VIA_BCR2 0x00001147 + + + +#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) + +typedef enum { eax, ebx, ecx, edx } cpuid_register_t; +/* + * Cache ID descriptor structure, used to parse CPUID leaf 2. + * Note: not used in kernel. + */ +typedef enum { Lnone, L1I, L1D, L2U, L3U, LCACHE_MAX } cache_type_t ; +typedef struct { + unsigned char value; /* Descriptor value */ + cache_type_t type; /* Cache type */ + unsigned int size; /* Cache size */ + unsigned int linesize; /* Cache line size */ + const char *description; /* Cache description */ +} cpuid_cache_desc_t; + + +#define CACHE_DESC(value,type,size,linesize,text) \ +{ value, type, size, linesize, text } + +/* Physical CPU info - this is exported out of the kernel (kexts), so be wary of changes */ +typedef struct { + char cpuid_vendor[16]; + char cpuid_brand_string[48]; + const char *cpuid_model_string; + + cpu_type_t cpuid_type; /* this is *not* a cpu_type_t in our */ + uint8_t cpuid_family; + uint8_t cpuid_model; + uint8_t cpuid_extmodel; + uint8_t cpuid_extfamily; + uint8_t cpuid_stepping; + uint64_t cpuid_features; + uint64_t cpuid_extfeatures; + uint32_t cpuid_signature; + uint8_t cpuid_brand; + + uint32_t cache_size[LCACHE_MAX]; + uint32_t cache_linesize; + + uint8_t cache_info[64]; /* list of cache descriptors */ + + uint32_t cpuid_cores_per_package; + uint32_t cpuid_logical_per_package; + uint32_t cache_sharing[LCACHE_MAX]; + uint32_t cache_partitions[LCACHE_MAX]; + + cpu_type_t cpuid_cpu_type; /* */ + cpu_subtype_t cpuid_cpu_subtype; /* */ + + /* Monitor/mwait Leaf: */ + uint32_t cpuid_mwait_linesize_min; + uint32_t cpuid_mwait_linesize_max; + uint32_t cpuid_mwait_extensions; + uint32_t cpuid_mwait_sub_Cstates; + + /* Thermal and Power Management Leaf: */ + boolean_t cpuid_thermal_sensor; + boolean_t cpuid_thermal_dynamic_acceleration; + uint32_t cpuid_thermal_thresholds; + boolean_t cpuid_thermal_ACNT_MCNT; + + /* Architectural Performance Monitoring Leaf: */ + uint8_t cpuid_arch_perf_version; + uint8_t cpuid_arch_perf_number; + uint8_t cpuid_arch_perf_width; + uint8_t cpuid_arch_perf_events_number; + uint32_t cpuid_arch_perf_events; + uint8_t cpuid_arch_perf_fixed_number; + uint8_t cpuid_arch_perf_fixed_width; + + /* Cache details: */ + uint32_t cpuid_cache_linesize; + uint32_t cpuid_cache_L2_associativity; + uint32_t cpuid_cache_size; + + /* Virtual and physical address aize: */ + uint32_t cpuid_address_bits_physical; + uint32_t cpuid_address_bits_virtual; + + uint32_t cpuid_microcode_version; + + /* Numbers of tlbs per processor [i|d, small|large, level0|level1] */ + uint32_t cpuid_tlb[2][2][2]; +#define TLB_INST 0 +#define TLB_DATA 1 +#define TLB_SMALL 0 +#define TLB_LARGE 1 + uint32_t cpuid_stlb; + + uint32_t core_count; + uint32_t thread_count; + + /* Max leaf ids available from CPUID */ + uint32_t cpuid_max_basic; + uint32_t cpuid_max_ext; +} i386_cpu_info_t; + +static i386_cpu_info_t cpuid_cpu_info; + +static i386_cpu_info_t *cpuid_info(void) +{ + return &cpuid_cpu_info; +} + + +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; +} + +static void cpuid_update_generic_info() +{ + uint32_t cpuid_reg[4]; + uint32_t max_extid; + char str[128]; + char* p; + i386_cpu_info_t* info_p = cpuid_info(); + + /* Get vendor */ + do_cpuid(0, cpuid_reg); + bcopy((char *)&cpuid_reg[ebx], &info_p->cpuid_vendor[0], 4); /* ug */ + bcopy((char *)&cpuid_reg[ecx], &info_p->cpuid_vendor[8], 4); + bcopy((char *)&cpuid_reg[edx], &info_p->cpuid_vendor[4], 4); + info_p->cpuid_vendor[12] = 0; + + /* Get extended CPUID results */ + do_cpuid(0x80000000, cpuid_reg); + max_extid = cpuid_reg[eax]; + + /* Check to see if we can get the brand string */ + if (max_extid >= 0x80000004) { + /* + * The brand string is up to 48 bytes and is guaranteed to be + * NUL terminated. + */ + do_cpuid(0x80000002, cpuid_reg); + bcopy((char *)cpuid_reg, &str[0], 16); + do_cpuid(0x80000003, cpuid_reg); + bcopy((char *)cpuid_reg, &str[16], 16); + do_cpuid(0x80000004, cpuid_reg); + bcopy((char *)cpuid_reg, &str[32], 16); + for (p = str; *p != '\0'; p++) { + if (*p != ' ') break; + } + strncpy(info_p->cpuid_brand_string, p, + sizeof(info_p->cpuid_brand_string)); + + if (!strncmp(info_p->cpuid_brand_string, CPUID_STRING_UNKNOWN, + min(sizeof(info_p->cpuid_brand_string), + strlen(CPUID_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. + */ + info_p->cpuid_brand_string[0] = '\0'; + } + } + + /* Get cache and addressing info */ + if (max_extid >= 0x80000006) { + do_cpuid(0x80000006, cpuid_reg); + info_p->cpuid_cache_linesize = bitfield(cpuid_reg[ecx], 7, 0); + info_p->cpuid_cache_L2_associativity = bitfield(cpuid_reg[ecx], 15, 12); + info_p->cpuid_cache_size = bitfield(cpuid_reg[ecx], 31, 16); + do_cpuid(0x80000008, cpuid_reg); + info_p->cpuid_address_bits_physical = bitfield(cpuid_reg[eax], 7, 0); + info_p->cpuid_address_bits_virtual = bitfield(cpuid_reg[eax], 15, 8); + } + + /* Get processor signature and decode */ + do_cpuid(1, cpuid_reg); + info_p->cpuid_signature = cpuid_reg[eax]; + info_p->cpuid_stepping = bitfield(cpuid_reg[eax], 3, 0); + info_p->cpuid_model = bitfield(cpuid_reg[eax], 7, 4); + info_p->cpuid_family = bitfield(cpuid_reg[eax], 11, 8); + info_p->cpuid_type = bitfield(cpuid_reg[eax], 13, 12); + info_p->cpuid_extmodel = bitfield(cpuid_reg[eax], 19, 16); + info_p->cpuid_extfamily = bitfield(cpuid_reg[eax], 27, 20); + info_p->cpuid_brand = bitfield(cpuid_reg[ebx], 7, 0); + info_p->cpuid_features = quad(cpuid_reg[ecx], cpuid_reg[edx]); + + /* Fold extensions into family/model */ + if (info_p->cpuid_family == 0x0f) { + info_p->cpuid_family += info_p->cpuid_extfamily; + } + if (info_p->cpuid_family == 0x0f || info_p->cpuid_family== 0x06) { + info_p->cpuid_model += (info_p->cpuid_extmodel << 4); + } + + if (info_p->cpuid_features & CPUID_FEATURE_HTT) { + info_p->cpuid_logical_per_package = bitfield(cpuid_reg[ebx], 23, 16); + } else { + info_p->cpuid_logical_per_package = 1; + } + + if (max_extid >= 0x80000001) { + do_cpuid(0x80000001, cpuid_reg); + info_p->cpuid_extfeatures = quad(cpuid_reg[ecx], cpuid_reg[edx]); + } + + if (info_p->cpuid_extfeatures & CPUID_FEATURE_MONITOR) { + + do_cpuid(5, cpuid_reg); + info_p->cpuid_mwait_linesize_min = cpuid_reg[eax]; + info_p->cpuid_mwait_linesize_max = cpuid_reg[ebx]; + info_p->cpuid_mwait_extensions = cpuid_reg[ecx]; + info_p->cpuid_mwait_sub_Cstates = cpuid_reg[edx]; + + do_cpuid(6, cpuid_reg); + info_p->cpuid_thermal_sensor = bitfield(cpuid_reg[eax], 0, 0); + info_p->cpuid_thermal_dynamic_acceleration = + bitfield(cpuid_reg[eax], 1, 1); + info_p->cpuid_thermal_thresholds = bitfield(cpuid_reg[ebx], 3, 0); + info_p->cpuid_thermal_ACNT_MCNT = bitfield(cpuid_reg[ecx], 0, 0); + + do_cpuid(0xa, cpuid_reg); + info_p->cpuid_arch_perf_version = bitfield(cpuid_reg[eax], 7, 0); + info_p->cpuid_arch_perf_number = bitfield(cpuid_reg[eax],15, 8); + info_p->cpuid_arch_perf_width = bitfield(cpuid_reg[eax],23,16); + info_p->cpuid_arch_perf_events_number = bitfield(cpuid_reg[eax],31,24); + info_p->cpuid_arch_perf_events = cpuid_reg[ebx]; + info_p->cpuid_arch_perf_fixed_number = bitfield(cpuid_reg[edx], 4, 0); + info_p->cpuid_arch_perf_fixed_width = bitfield(cpuid_reg[edx],12, 5); + + } + + do_cpuid(4, cpuid_reg); + info_p->cpuid_cores_per_package = bitfield(cpuid_reg[eax], 31, 26) + 1; + + if (info_p->cpuid_cores_per_package == 0) { + info_p->cpuid_cores_per_package = 1; + + } + + switch (info_p->cpuid_model) + { + case 0x1C: + { + //uint64_t msr = rdmsr64(MSR_CORE_THREAD_COUNT); + info_p->core_count = 1; //bitfield((uint32_t)msr, 19, 16); + info_p->thread_count = 2; //bitfield((uint32_t)msr, 15, 0); + } + break; + case 0x19: // some i5 ??? + case 0x1A: // Intel Core i7 LGA1366 (45nm) + case 0x1E: // Intel Core i5, i7 LGA1156 (45nm) + case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm) + { + uint64_t msr = rdmsr64(MSR_CORE_THREAD_COUNT); + info_p->core_count = bitfield((uint32_t)msr, 31, 16); + info_p->thread_count = bitfield((uint32_t)msr, 15, 0); + } break; + case 0x2C: // Intel Core i7 LGA1366 (32nm) 6 Core + case 0x1F: + case 0x2F: + { + uint64_t msr = rdmsr64(MSR_CORE_THREAD_COUNT); + info_p->core_count = bitfield((uint32_t)msr, 19, 16); + info_p->thread_count = bitfield((uint32_t)msr, 15, 0); + break; + } + + default: + { + do_cpuid(1, cpuid_reg); + info_p->core_count = bitfield(cpuid_reg[1], 23, 16); + } break; + } + if (info_p->core_count == 0) { + info_p->core_count = info_p->cpuid_cores_per_package; + info_p->thread_count = info_p->cpuid_logical_per_package; + } + +} + + +#endif /* !__LIBSAIO_CPU_H */ Index: branches/slice/old749m/i386/libsaio/disk.h =================================================================== --- branches/slice/old749m/i386/libsaio/disk.h (revision 0) +++ branches/slice/old749m/i386/libsaio/disk.h (revision 1174) @@ -0,0 +1,14 @@ +/* + * disk.h + * Chameleon + * + * Created by Daniel Miranda on 27/07/10. + * Copyright 2010 __MyCompanyName__. All rights reserved. + * + */ +#ifndef __LIBSAIO_DISK_H +#define __LIBSAIO_DISK_H + +bool matchVolumeToString( BVRef bvr, const char* match, long strMaxLen); + +#endif /* __LIBSAIO_DISK_H */ \ No newline at end of file Property changes on: branches/slice/old749m/i386/libsaio/disk.h ___________________________________________________________________ Added: svn:executable + * Index: branches/slice/old749m/i386/libsaio/cache.c =================================================================== --- branches/slice/old749m/i386/libsaio/cache.c (revision 0) +++ branches/slice/old749m/i386/libsaio/cache.c (revision 1174) @@ -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/old749m/i386/libsaio/pci.c =================================================================== --- branches/slice/old749m/i386/libsaio/pci.c (revision 0) +++ branches/slice/old749m/i386/libsaio/pci.c (revision 1174) @@ -0,0 +1,208 @@ +/* + * + * Copyright 2008 by Islam M. Ahmed Zaid. All rights reserved. + * + */ + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "pci.h" +#include "pci_root.h" + +#ifndef DEBUG_PCI +#define DEBUG_PCI 0 +#endif + +#if DEBUG_PCI +#define DBG(x...) verbose(x) +#else +#define DBG(x...) msglog(x) +#endif + +//static +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; +} + +#ifndef OPTION_ROM +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; + } +} +#endif Index: branches/slice/old749m/i386/libsaio/stringTable.c =================================================================== --- branches/slice/old749m/i386/libsaio/stringTable.c (revision 0) +++ branches/slice/old749m/i386/libsaio/stringTable.c (revision 1174) @@ -0,0 +1,855 @@ +/* + * 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 "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: [ ...] [