Chameleon

Chameleon Commit Details

Date:2012-08-05 00:38:41 (11 years 7 months ago)
Author:ErmaC
Commit:2037
Parents: 2036
Message:This revision is devoted to Samantha, AKA DHP or Revogirl in the OSx86 scene. A young talent we lost prematurely. Part of her work will now live on in the Chameleon source code. Changes: code cleaned, improvements taken from Revoboot. http://www.insanelymac.com/forum/index.php?showtopic=259090
Changes:
M/branches/ErmaC/Trunk/i386/libsaio/platform.h
M/branches/ErmaC/Trunk/i386/libsaio/disk.c
M/branches/ErmaC/Trunk/i386/libsaio/device_inject.c
M/branches/ErmaC/Trunk/i386/boot2/lzss.c
M/branches/ErmaC/Trunk/i386/boot2/options.c
M/branches/ErmaC/Trunk/i386/libsaio/device_inject.h
M/branches/ErmaC/Trunk/i386/libsaio/xml.c
M/branches/ErmaC/Trunk/i386/libsaio/bios.h
M/branches/ErmaC/Trunk/i386/libsaio/console.c
M/branches/ErmaC/Trunk/i386/libsaio/fdisk.h
M/branches/ErmaC/Trunk/i386/libsaio/xml.h
M/branches/ErmaC/Trunk/i386/libsaio/efi.h
M/branches/ErmaC/Trunk/i386/libsaio/vbe.c
M/branches/ErmaC/Trunk/CHANGES
M/branches/ErmaC/Trunk/i386/libsaio/sys.c
M/branches/ErmaC/Trunk/i386/libsaio/device_tree.c
M/branches/ErmaC/Trunk/i386/libsaio/hfs.c
M/branches/ErmaC/Trunk/i386/libsaio/biosfn.c
M/branches/ErmaC/Trunk/i386/boot2/drivers.c
M/branches/ErmaC/Trunk/i386/libsaio/device_tree.h
M/branches/ErmaC/Trunk/i386/libsaio/saio_types.h
M/branches/ErmaC/Trunk/i386/libsaio/memvendors.h
M/branches/ErmaC/Trunk/i386/boot2/prompt.c
M/branches/ErmaC/Trunk/i386/libsaio/hfs.h
M/branches/ErmaC/Trunk/i386/libsa/memory.h
M/branches/ErmaC/Trunk/i386/libsaio/spd.c
M/branches/ErmaC/Trunk/i386/libsaio/hfs_compare.c
M/branches/ErmaC/Trunk/i386/libsaio/cpu.c
M/branches/ErmaC/Trunk/i386/libsaio/md5c.c
M/branches/ErmaC/Trunk/i386/libsaio/fake_efi.c
M/branches/ErmaC/Trunk/i386/libsaio/spd.h
M/branches/ErmaC/Trunk/i386/libsa/zalloc.c
M/branches/ErmaC/Trunk/i386/libsaio/fake_efi.h
M/branches/ErmaC/Trunk/i386/libsa/prf.c
M/branches/ErmaC/Trunk/i386/libsaio/cache.c
M/branches/ErmaC/Trunk/i386/libsaio/gma.c
M/branches/ErmaC/Trunk/i386/libsa/efi_tables.c
M/branches/ErmaC/Trunk/i386/boot2/boot.c
M/branches/ErmaC/Trunk/i386/libsa/libsa.h
M/branches/ErmaC/Trunk/i386/boot2/boot2.s
M/branches/ErmaC/Trunk/i386/libsa/printf.c
M/branches/ErmaC/Trunk/i386/boot2/boot.h
M/branches/ErmaC/Trunk/i386/libsaio/pci.c
M/branches/ErmaC/Trunk/i386/libsaio/bootstruct.h
M/branches/ErmaC/Trunk/i386/libsa/string.c
M/branches/ErmaC/Trunk/i386/libsaio/stringTable.c
M/branches/ErmaC/Trunk/i386/libsaio/load.c
M/branches/ErmaC/Trunk/i386/libsaio/sl.h
M/branches/ErmaC/Trunk/i386/libsaio/allocate.c
M/branches/ErmaC/Trunk/Chameleon.xcodeproj/project.pbxproj

File differences

branches/ErmaC/Trunk/Chameleon.xcodeproj/project.pbxproj
12881288
12891289
12901290
1291
1292
1293
1294
1295
1296
1297
12981291
12991292
13001293
......
13771370
13781371
13791372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
13801434
13811435
13821436
......
32163270
32173271
32183272
3219
3220
3221
32223273
32233274
32243275
32253276
32263277
32273278
3279
3280
3281
32283282
32293283
32303284
......
34333487
34343488
34353489
3436
3437
3438
3490
3491
34393492
34403493
34413494
......
35523605
35533606
35543607
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
35833608
35843609
35853610
......
36993724
37003725
37013726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
37023802
37033803
37043804
B0056DD911F3868000754B65 /* text_scroll_next.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = text_scroll_next.png; sourceTree = "<group>"; };
B0056DDA11F3868000754B65 /* text_scroll_prev.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = text_scroll_prev.png; sourceTree = "<group>"; };
B0056DDB11F3868000754B65 /* theme.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = theme.plist; sourceTree = "<group>"; };
B0056DFD11F3868000754B65 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = "<group>"; };
B0056DFE11F3868000754B65 /* theme.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = theme.plist; sourceTree = "<group>"; };
B0056E0011F3868000754B65 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = "<group>"; };
B0056E0111F3868000754B65 /* theme.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = theme.plist; sourceTree = "<group>"; };
B0056E0311F3868000754B65 /* font_small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = font_small.png; sourceTree = "<group>"; };
B0056E0411F3868000754B65 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = "<group>"; };
B0056E0511F3868000754B65 /* theme.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = theme.plist; sourceTree = "<group>"; };
B0056E0811F3868000754B65 /* Users_Guide0.4.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = Users_Guide0.4.pdf; sourceTree = "<group>"; };
B0056E0911F3868000754B65 /* Users_Guide_v0.3.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = Users_Guide_v0.3.pdf; sourceTree = "<group>"; };
B0056E0A11F3868000754B65 /* UsersGuide-v0.2.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = "UsersGuide-v0.2.pdf"; sourceTree = "<group>"; };
B43E407714EE869800CD79F9 /* device_hfsplus_ml.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_hfsplus_ml.png; sourceTree = "<group>"; };
B43E407814EE869A00CD79F9 /* device_hfsraid_ml_o.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_hfsraid_ml_o.png; sourceTree = "<group>"; };
B43E407914EE869C00CD79F9 /* device_hfsraid_ml.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = device_hfsraid_ml.png; sourceTree = "<group>"; };
B442D9F515C216C900985ED1 /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = background.png; path = embed/background.png; sourceTree = "<group>"; };
B442D9F615C216C900985ED1 /* boot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = boot.png; path = embed/boot.png; sourceTree = "<group>"; };
B442D9F715C216C900985ED1 /* device_cdrom.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_cdrom.png; path = embed/device_cdrom.png; sourceTree = "<group>"; };
B442D9F815C216C900985ED1 /* device_ext3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_ext3.png; path = embed/device_ext3.png; sourceTree = "<group>"; };
B442D9F915C216C900985ED1 /* device_fat.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_fat.png; path = embed/device_fat.png; sourceTree = "<group>"; };
B442D9FA15C216C900985ED1 /* device_generic.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_generic.png; path = embed/device_generic.png; sourceTree = "<group>"; };
B442D9FB15C216C900985ED1 /* device_hfsplus.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_hfsplus.png; path = embed/device_hfsplus.png; sourceTree = "<group>"; };
B442D9FC15C216C900985ED1 /* device_hfsraid.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_hfsraid.png; path = embed/device_hfsraid.png; sourceTree = "<group>"; };
B442D9FD15C216C900985ED1 /* device_ntfs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_ntfs.png; path = embed/device_ntfs.png; sourceTree = "<group>"; };
B442D9FE15C216C900985ED1 /* device_scroll_next.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_scroll_next.png; path = embed/device_scroll_next.png; sourceTree = "<group>"; };
B442D9FF15C216C900985ED1 /* device_scroll_prev.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_scroll_prev.png; path = embed/device_scroll_prev.png; sourceTree = "<group>"; };
B442DA0015C216C900985ED1 /* device_selection.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_selection.png; path = embed/device_selection.png; sourceTree = "<group>"; };
B442DA0115C216C900985ED1 /* font_console.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = font_console.png; path = embed/font_console.png; sourceTree = "<group>"; };
B442DA0215C216C900985ED1 /* font_small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = font_small.png; path = embed/font_small.png; sourceTree = "<group>"; };
B442DA0315C216C900985ED1 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = logo.png; path = embed/logo.png; sourceTree = "<group>"; };
B442DA0415C216C900985ED1 /* menu_boot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_boot.png; path = embed/menu_boot.png; sourceTree = "<group>"; };
B442DA0515C216C900985ED1 /* menu_help.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_help.png; path = embed/menu_help.png; sourceTree = "<group>"; };
B442DA0615C216C900985ED1 /* menu_ignore_caches_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_ignore_caches_disabled.png; path = embed/menu_ignore_caches_disabled.png; sourceTree = "<group>"; };
B442DA0715C216C900985ED1 /* menu_ignore_caches.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_ignore_caches.png; path = embed/menu_ignore_caches.png; sourceTree = "<group>"; };
B442DA0815C216C900985ED1 /* menu_memory_info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_memory_info.png; path = embed/menu_memory_info.png; sourceTree = "<group>"; };
B442DA0915C216C900985ED1 /* menu_selection.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_selection.png; path = embed/menu_selection.png; sourceTree = "<group>"; };
B442DA0A15C216C900985ED1 /* menu_single_user_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_single_user_disabled.png; path = embed/menu_single_user_disabled.png; sourceTree = "<group>"; };
B442DA0B15C216C900985ED1 /* menu_single_user.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_single_user.png; path = embed/menu_single_user.png; sourceTree = "<group>"; };
B442DA0C15C216C900985ED1 /* menu_verbose_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_verbose_disabled.png; path = embed/menu_verbose_disabled.png; sourceTree = "<group>"; };
B442DA0D15C216C900985ED1 /* menu_verbose.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_verbose.png; path = embed/menu_verbose.png; sourceTree = "<group>"; };
B442DA0E15C216C900985ED1 /* menu_video_info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_video_info.png; path = embed/menu_video_info.png; sourceTree = "<group>"; };
B442DA0F15C216C900985ED1 /* progress_bar_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = progress_bar_background.png; path = embed/progress_bar_background.png; sourceTree = "<group>"; };
B442DA1015C216C900985ED1 /* progress_bar.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = progress_bar.png; path = embed/progress_bar.png; sourceTree = "<group>"; };
B442DA1115C216C900985ED1 /* text_scroll_next.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = text_scroll_next.png; path = embed/text_scroll_next.png; sourceTree = "<group>"; };
B442DA1215C216C900985ED1 /* text_scroll_prev.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = text_scroll_prev.png; path = embed/text_scroll_prev.png; sourceTree = "<group>"; };
B442DA1315C216C900985ED1 /* theme.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = theme.plist; path = embed/theme.plist; sourceTree = "<group>"; };
B442DA1415C216E500985ED1 /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = background.png; path = legacy/background.png; sourceTree = "<group>"; };
B442DA1515C216E500985ED1 /* boot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = boot.png; path = legacy/boot.png; sourceTree = "<group>"; };
B442DA1615C216E500985ED1 /* device_cdrom.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_cdrom.png; path = legacy/device_cdrom.png; sourceTree = "<group>"; };
B442DA1715C216E500985ED1 /* device_ext3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_ext3.png; path = legacy/device_ext3.png; sourceTree = "<group>"; };
B442DA1815C216E500985ED1 /* device_fat.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_fat.png; path = legacy/device_fat.png; sourceTree = "<group>"; };
B442DA1915C216E500985ED1 /* device_generic.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_generic.png; path = legacy/device_generic.png; sourceTree = "<group>"; };
B442DA1A15C216E500985ED1 /* device_hfsplus.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_hfsplus.png; path = legacy/device_hfsplus.png; sourceTree = "<group>"; };
B442DA1B15C216E500985ED1 /* device_ntfs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_ntfs.png; path = legacy/device_ntfs.png; sourceTree = "<group>"; };
B442DA1C15C216E500985ED1 /* device_scroll_next.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_scroll_next.png; path = legacy/device_scroll_next.png; sourceTree = "<group>"; };
B442DA1D15C216E500985ED1 /* device_scroll_prev.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_scroll_prev.png; path = legacy/device_scroll_prev.png; sourceTree = "<group>"; };
B442DA1E15C216E500985ED1 /* device_selection.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = device_selection.png; path = legacy/device_selection.png; sourceTree = "<group>"; };
B442DA1F15C216E500985ED1 /* font_console.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = font_console.png; path = legacy/font_console.png; sourceTree = "<group>"; };
B442DA2015C216E500985ED1 /* font_small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = font_small.png; path = legacy/font_small.png; sourceTree = "<group>"; };
B442DA2115C216E500985ED1 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = logo.png; path = legacy/logo.png; sourceTree = "<group>"; };
B442DA2215C216E500985ED1 /* menu_boot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_boot.png; path = legacy/menu_boot.png; sourceTree = "<group>"; };
B442DA2315C216E500985ED1 /* menu_help.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_help.png; path = legacy/menu_help.png; sourceTree = "<group>"; };
B442DA2415C216E500985ED1 /* menu_ignore_caches_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_ignore_caches_disabled.png; path = legacy/menu_ignore_caches_disabled.png; sourceTree = "<group>"; };
B442DA2515C216E500985ED1 /* menu_ignore_caches.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_ignore_caches.png; path = legacy/menu_ignore_caches.png; sourceTree = "<group>"; };
B442DA2615C216E500985ED1 /* menu_memory_info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_memory_info.png; path = legacy/menu_memory_info.png; sourceTree = "<group>"; };
B442DA2715C216E500985ED1 /* menu_selection.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_selection.png; path = legacy/menu_selection.png; sourceTree = "<group>"; };
B442DA2815C216E500985ED1 /* menu_single_user_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_single_user_disabled.png; path = legacy/menu_single_user_disabled.png; sourceTree = "<group>"; };
B442DA2915C216E500985ED1 /* menu_single_user.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_single_user.png; path = legacy/menu_single_user.png; sourceTree = "<group>"; };
B442DA2A15C216E500985ED1 /* menu_verbose_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_verbose_disabled.png; path = legacy/menu_verbose_disabled.png; sourceTree = "<group>"; };
B442DA2B15C216E500985ED1 /* menu_verbose.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_verbose.png; path = legacy/menu_verbose.png; sourceTree = "<group>"; };
B442DA2C15C216E500985ED1 /* menu_video_info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menu_video_info.png; path = legacy/menu_video_info.png; sourceTree = "<group>"; };
B442DA2D15C216E500985ED1 /* progress_bar_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = progress_bar_background.png; path = legacy/progress_bar_background.png; sourceTree = "<group>"; };
B442DA2E15C216E500985ED1 /* progress_bar.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = progress_bar.png; path = legacy/progress_bar.png; sourceTree = "<group>"; };
B442DA2F15C216E500985ED1 /* text_scroll_next.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = text_scroll_next.png; path = legacy/text_scroll_next.png; sourceTree = "<group>"; };
B442DA3015C216E500985ED1 /* text_scroll_prev.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = text_scroll_prev.png; path = legacy/text_scroll_prev.png; sourceTree = "<group>"; };
B442DA3115C216E500985ED1 /* theme.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = theme.plist; path = legacy/theme.plist; sourceTree = "<group>"; };
B4526097153EFCE90018E994 /* ar.po */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ar.po; sourceTree = "<group>"; };
B4526098153EFCE90018E994 /* bg.po */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = bg.po; sourceTree = "<group>"; };
B4526099153EFCE90018E994 /* bs.po */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = bs.po; sourceTree = "<group>"; };
B0056CFC11F3868000754B65 /* graphics.c */,
B0056CFD11F3868000754B65 /* graphics.h */,
B0056CFE11F3868000754B65 /* gui.c */,
6DBAFD1313B0D21E0047ED33 /* modules_support.s */,
6DBAFD1413B0D21E0047ED33 /* modules.c */,
6DBAFD1513B0D21E0047ED33 /* modules.h */,
B0056CFF11F3868000754B65 /* gui.h */,
B0056D0011F3868000754B65 /* IOHibernatePrivate.h */,
B0056D0111F3868000754B65 /* lzss.c */,
B0056D0211F3868000754B65 /* Makefile */,
B0056D0311F3868000754B65 /* mboot.c */,
B0056D0411F3868000754B65 /* mboot.h */,
6DBAFD1313B0D21E0047ED33 /* modules_support.s */,
6DBAFD1413B0D21E0047ED33 /* modules.c */,
6DBAFD1513B0D21E0047ED33 /* modules.h */,
B0056D0511F3868000754B65 /* multiboot.h */,
B0056D0611F3868000754B65 /* options.c */,
B0056D0711F3868000754B65 /* picopng.c */,
children = (
B0056DBC11F3868000754B65 /* bullet */,
B0056DDC11F3868000754B65 /* default */,
B0056DFC11F3868000754B65 /* msi_netbook */,
B0056DFF11F3868000754B65 /* pinktink */,
B0056E0211F3868000754B65 /* twilight */,
B442D9F315C2164800985ED1 /* embed */,
B442D9F415C2166000985ED1 /* legacy */,
);
path = themes;
sourceTree = "<group>";
path = default;
sourceTree = "<group>";
};
B0056DFC11F3868000754B65 /* msi_netbook */ = {
isa = PBXGroup;
children = (
B0056DFD11F3868000754B65 /* logo.png */,
B0056DFE11F3868000754B65 /* theme.plist */,
);
path = msi_netbook;
sourceTree = "<group>";
};
B0056DFF11F3868000754B65 /* pinktink */ = {
isa = PBXGroup;
children = (
B0056E0011F3868000754B65 /* logo.png */,
B0056E0111F3868000754B65 /* theme.plist */,
);
path = pinktink;
sourceTree = "<group>";
};
B0056E0211F3868000754B65 /* twilight */ = {
isa = PBXGroup;
children = (
B0056E0311F3868000754B65 /* font_small.png */,
B0056E0411F3868000754B65 /* logo.png */,
B0056E0511F3868000754B65 /* theme.plist */,
);
path = twilight;
sourceTree = "<group>";
};
B0056E0611F3868000754B65 /* doc */ = {
isa = PBXGroup;
children = (
name = lxdialog;
sourceTree = "<group>";
};
B442D9F315C2164800985ED1 /* embed */ = {
isa = PBXGroup;
children = (
B442D9F515C216C900985ED1 /* background.png */,
B442D9F615C216C900985ED1 /* boot.png */,
B442D9F715C216C900985ED1 /* device_cdrom.png */,
B442D9F815C216C900985ED1 /* device_ext3.png */,
B442D9F915C216C900985ED1 /* device_fat.png */,
B442D9FA15C216C900985ED1 /* device_generic.png */,
B442D9FB15C216C900985ED1 /* device_hfsplus.png */,
B442D9FC15C216C900985ED1 /* device_hfsraid.png */,
B442D9FD15C216C900985ED1 /* device_ntfs.png */,
B442D9FE15C216C900985ED1 /* device_scroll_next.png */,
B442D9FF15C216C900985ED1 /* device_scroll_prev.png */,
B442DA0015C216C900985ED1 /* device_selection.png */,
B442DA0115C216C900985ED1 /* font_console.png */,
B442DA0215C216C900985ED1 /* font_small.png */,
B442DA0315C216C900985ED1 /* logo.png */,
B442DA0415C216C900985ED1 /* menu_boot.png */,
B442DA0515C216C900985ED1 /* menu_help.png */,
B442DA0615C216C900985ED1 /* menu_ignore_caches_disabled.png */,
B442DA0715C216C900985ED1 /* menu_ignore_caches.png */,
B442DA0815C216C900985ED1 /* menu_memory_info.png */,
B442DA0915C216C900985ED1 /* menu_selection.png */,
B442DA0A15C216C900985ED1 /* menu_single_user_disabled.png */,
B442DA0B15C216C900985ED1 /* menu_single_user.png */,
B442DA0C15C216C900985ED1 /* menu_verbose_disabled.png */,
B442DA0D15C216C900985ED1 /* menu_verbose.png */,
B442DA0E15C216C900985ED1 /* menu_video_info.png */,
B442DA0F15C216C900985ED1 /* progress_bar_background.png */,
B442DA1015C216C900985ED1 /* progress_bar.png */,
B442DA1115C216C900985ED1 /* text_scroll_next.png */,
B442DA1215C216C900985ED1 /* text_scroll_prev.png */,
B442DA1315C216C900985ED1 /* theme.plist */,
);
name = embed;
sourceTree = "<group>";
};
B442D9F415C2166000985ED1 /* legacy */ = {
isa = PBXGroup;
children = (
B442DA1415C216E500985ED1 /* background.png */,
B442DA1515C216E500985ED1 /* boot.png */,
B442DA1615C216E500985ED1 /* device_cdrom.png */,
B442DA1715C216E500985ED1 /* device_ext3.png */,
B442DA1815C216E500985ED1 /* device_fat.png */,
B442DA1915C216E500985ED1 /* device_generic.png */,
B442DA1A15C216E500985ED1 /* device_hfsplus.png */,
B442DA1B15C216E500985ED1 /* device_ntfs.png */,
B442DA1C15C216E500985ED1 /* device_scroll_next.png */,
B442DA1D15C216E500985ED1 /* device_scroll_prev.png */,
B442DA1E15C216E500985ED1 /* device_selection.png */,
B442DA1F15C216E500985ED1 /* font_console.png */,
B442DA2015C216E500985ED1 /* font_small.png */,
B442DA2115C216E500985ED1 /* logo.png */,
B442DA2215C216E500985ED1 /* menu_boot.png */,
B442DA2315C216E500985ED1 /* menu_help.png */,
B442DA2415C216E500985ED1 /* menu_ignore_caches_disabled.png */,
B442DA2515C216E500985ED1 /* menu_ignore_caches.png */,
B442DA2615C216E500985ED1 /* menu_memory_info.png */,
B442DA2715C216E500985ED1 /* menu_selection.png */,
B442DA2815C216E500985ED1 /* menu_single_user_disabled.png */,
B442DA2915C216E500985ED1 /* menu_single_user.png */,
B442DA2A15C216E500985ED1 /* menu_verbose_disabled.png */,
B442DA2B15C216E500985ED1 /* menu_verbose.png */,
B442DA2C15C216E500985ED1 /* menu_video_info.png */,
B442DA2D15C216E500985ED1 /* progress_bar_background.png */,
B442DA2E15C216E500985ED1 /* progress_bar.png */,
B442DA2F15C216E500985ED1 /* text_scroll_next.png */,
B442DA3015C216E500985ED1 /* text_scroll_prev.png */,
B442DA3115C216E500985ED1 /* theme.plist */,
);
name = legacy;
sourceTree = "<group>";
};
B4526096153EFCE90018E994 /* po */ = {
isa = PBXGroup;
children = (
branches/ErmaC/Trunk/i386/libsaio/fake_efi.h
11
2
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
326
427
528
......
932
1033
1134
12
35
1336
/*
* Copyright 2007 David F. Elliott. 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. 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.
*
* Copyright 2007 David F. Elliott.
* All rights reserved.
*
*/
#ifndef __LIBSAIO_FAKE_EFI_H
#define MAX_CONFIGURATION_TABLE_ENTRIES 10
extern void setupFakeEfi(void);
#endif /* !__LIBSAIO_FAKE_EFI_H */
branches/ErmaC/Trunk/i386/libsaio/xml.c
6767
6868
6969
70
71
72
73
74
75
76
70
71
72
73
74
75
76
77
7778
7879
7980
80
81
82
83
84
81
82
83
84
85
86
8587
8688
8789
8890
8991
9092
91
92
93
94
95
96
97
98
99
93
94
95
96
97
98
99
100
101
102
100103
101104
102105
103
104
105
106
107
108
109
106110
107111
108112
......
126130
127131
128132
129
130
133
131134
132
135
136
137
138
133139
134
135
136
137
138
139
140
141
140
141
142
143
144
145
146
142147
143
144
145
146
147
148
148
149
150
151
152
153
154
155
156
157
158
159
149160
150161
151162
return "";
}
struct Module {
struct Module *nextModule;
long willLoad;
TagPtr dict;
char *plistAddr;
long plistLength;
char *driverPath;
struct Module
{
struct Module *nextModule;
longwillLoad;
TagPtrdict;
char* plistAddr;
longplistLength;
char* driverPath;
};
typedef struct Module Module, *ModulePtr;
struct DriverInfo {
char *plistAddr;
long plistLength;
void *moduleAddr;
long moduleLength;
struct DriverInfo
{
char* plistAddr;
longplistLength;
void* moduleAddr;
longmoduleLength;
};
typedef struct DriverInfo DriverInfo, *DriverInfoPtr;
#define kDriverPackageSignature1 'MKXT'
#define kDriverPackageSignature2 'MOSX'
struct DriversPackage {
unsigned long signature1;
unsigned long signature2;
unsigned long length;
unsigned long adler32;
unsigned long version;
unsigned long numDrivers;
unsigned long reserved1;
unsigned long reserved2;
struct DriversPackage
{
unsigned long signature1;
unsigned long signature2;
unsigned long length;
unsigned long adler32;
unsigned long version;
unsigned long numDrivers;
unsigned long reserved1;
unsigned long reserved2;
};
typedef struct DriversPackage DriversPackage;
enum {
kCFBundleType2,
kCFBundleType3
enum
{
kCFBundleType2,
kCFBundleType3
};
//==========================================================================
// XMLGetProperty
TagPtr
XMLGetProperty( TagPtr dict, const char * key )
TagPtr XMLGetProperty(TagPtr dict, const char * key)
{
TagPtr tagList, tag;
if (dict->type != kTagTypeDict)
{
return 0;
}
if (dict->type != kTagTypeDict) return 0;
tag = 0;
tagList = dict->tag;
while (tagList)
{
tag = tagList;
tagList = tag->tagNext;
TagPtr tag = 0;
TagPtr 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;
if ((tag->type != kTagTypeKey) || (tag->string == 0))
{
continue;
}
if (!strcmp(tag->string, key))
{
return tag->tag;
}
}
return 0;
}
//==========================================================================
branches/ErmaC/Trunk/i386/libsaio/console.c
6969
7070
7171
72
73
72
73
7474
7575
7676
......
8383
8484
8585
86
86
8787
8888
8989
......
9191
9292
9393
94
94
9595
9696
9797
......
100100
101101
102102
103
103104
105
104106
105107
108
106109
110
107111
108112
109113
......
116120
117121
118122
123
119124
125
120126
121127
122128
......
136142
137143
138144
139
145
140146
141
147
142148
143149
144150
145
151
146152
147153
148154
149155
150
156
151157
152
153
154
155
158
159
160
161
162
163
164
165
156166
157167
158168
......
171181
172182
173183
174
184
175185
176186
187
177188
189
178190
191
179192
193
180194
181195
182196
......
194208
195209
196210
197
211
198212
199213
200214
......
202216
203217
204218
205
206
219
220
207221
208222
209223
210224
211
225
212226
213227
214228
215229
216230
217231
232
218233
234
219235
220236
237
221238
239
222240
223241
224242
225243
226244
227245
228
229
246
247
230248
231249
232250
233251
234
235
236
252
253
254
237255
256
238257
239
258
259
260
240261
262
241263
242
264
243265
244266
245267
......
248270
249271
250272
251
273
274
252275
253
276
277
278
254279
255280
256281
struct putc_info //Azi: exists on gui.c & printf.c
{
char * str;
char * last_str;
char * str;
char * last_str;
};
static int
return 0;
}
*(pi->str)++ = c;
return c;
return c;
}
void initBooterLog(void)
msgbuf = malloc(BOOTER_LOG_SIZE);
bzero(msgbuf, BOOTER_LOG_SIZE);
cursor = msgbuf;
msglog("%s\n", "Enoch by ErmaC (r" I386BOOT_CHAMELEONREVISION ")" " [" I386BOOT_BUILDDATE "]");
msglog("%s\n", "Enoch (r" I386BOOT_CHAMELEONREVISION ")" " [" I386BOOT_BUILDDATE "]");
}
void msglog(const char * fmt, ...)
struct putc_info pi;
if (!msgbuf)
{
return;
}
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE)))
{
return;
}
va_start(ap, fmt);
pi.str = cursor;
void setupBooterLog(void)
{
if (!msgbuf)
{
return;
}
Node *node = DT__FindNode("/", false);
if (node)
}
if ( c == '\n' )
{
{
bios_putchar('\r');
}
}
bios_putchar(c);
return c;
return c;
}
int getc()
{
int c = bgetc();
int c = bgetc();
if ((c & 0xff) == 0)
return c;
else
return (c & 0xff);
if ((c & 0xff) == 0)
{
return c;
}
else
{
return (c & 0xff);
}
}
// Read and echo a character from console. This doesn't echo backspace
int printf(const char * fmt, ...)
{
va_list ap;
va_list ap;
va_start(ap, fmt);
if (bootArgs->Video.v_display == VGA_TEXT_MODE)
{
prf(fmt, ap, putchar, 0);
}
else
{
vprf(fmt, ap);
}
{
/* Kabyl: BooterLog */
}
va_end(ap);
return 0;
return 0;
}
int verbose(const char * fmt, ...)
va_list ap;
va_start(ap, fmt);
if (gVerboseMode)
{
if (gVerboseMode)
{
if (bootArgs->Video.v_display == VGA_TEXT_MODE)
prf(fmt, ap, putchar, 0);
else
vprf(fmt, ap);
}
}
{
/* Kabyl: BooterLog */
struct putc_info pi;
if (!msgbuf)
{
return 0;
}
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE)))
{
return 0;
}
pi.str = cursor;
pi.last_str = 0;
prf(fmt, ap, sputc, &pi);
cursor += strlen((char *)cursor);
}
va_end(ap);
return(0);
va_end(ap);
return(0);
}
int error(const char * fmt, ...)
{
va_list ap;
gErrors = true;
va_start(ap, fmt);
va_list ap;
gErrors = true;
va_start(ap, fmt);
if (bootArgs->Video.v_display == VGA_TEXT_MODE)
{
prf(fmt, ap, putchar, 0);
else
}
else
{
vprf(fmt, ap);
}
va_end(ap);
return(0);
return(0);
}
void stop(const char * fmt, ...)
printf("\n");
va_start(ap, fmt);
if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
if (bootArgs->Video.v_display == VGA_TEXT_MODE)
{
prf(fmt, ap, putchar, 0);
} else {
}
else
{
vprf(fmt, ap);
}
va_end(ap);
branches/ErmaC/Trunk/i386/libsaio/xml.h
2525
2626
2727
28
29
30
31
32
33
34
35
36
37
38
28
29
30
31
32
33
34
35
36
37
38
39
3940
4041
4142
......
7071
7172
7273
73
74
75
76
77
74
75
76
77
78
79
7880
7981
8082
#ifndef __LIBSAIO_XML_H
#define __LIBSAIO_XML_H
enum xmltype {
kTagTypeNone = 0,
kTagTypeDict,
kTagTypeKey,
kTagTypeString,
kTagTypeInteger,
kTagTypeData,
kTagTypeDate,
kTagTypeFalse,
kTagTypeTrue,
kTagTypeArray
enum xmltype
{
kTagTypeNone = 0,
kTagTypeDict,
kTagTypeKey,
kTagTypeString,
kTagTypeInteger,
kTagTypeData,
kTagTypeDate,
kTagTypeFalse,
kTagTypeTrue,
kTagTypeArray
};
struct string_ref
#define kPropIONameMatch ("IONameMatch")
/*
struct Tag {
long type;
char *string;
struct Tag *tag;
struct Tag *tagNext;
struct Tag
{
long type;
char *string;
struct Tag *tag;
struct Tag *tagNext;
};
typedef struct Tag Tag, *TagPtr;
*/
branches/ErmaC/Trunk/i386/libsaio/efi.h
11
22
33
4
5
64
75
86
......
2321
2422
2523
26
2724
2825
2926
......
7168
7269
7370
74
7571
76
72
7773
7874
7975
......
8278
8379
8480
85
8681
87
8882
8983
9084
......
123117
124118
125119
126
127120
128121
129122
130123
131124
132125
133
126
127
134128
135129
136130
......
143137
144138
145139
146
140
141
147142
148143
149144
......
159154
160155
161156
162
157
158
163159
164160
165161
......
173169
174170
175171
176
172
177173
178
174
179175
180176
181177
182
178
183179
184
180
185181
186182
187183
......
202198
203199
204200
205
206
207
208
209
210
201
202
203
204
205
206
207
211208
212209
213
214210
215
211
216212
217213
218214
219215
220216
221217
222
218
223219
224
220
225221
226222
227223
228224
229
225
230226
231
227
232228
233229
234230
......
263259
264260
265261
266
262
267263
268
264
269265
270266
271267
......
302298
303299
304300
305
301
306302
307
308
303
304
305
309306
310307
311308
......
371368
372369
373370
374
375371
376
377
378
379
380
381
382
372
373
374
375
376
383377
384
385
378
386379
387380
388381
......
403396
404397
405398
406
407
399
400
401
408402
409
410
411
412
413
414
415
403
404
405
406
407
416408
417
418
419
420
421
409
422410
423
424
425
426
427
428
411
412
429413
430
431
432
433
434
435414
415
416
417
418
419
420
421
422
423
436424
437
438
439
440
441
442
425
426
427
428
429
430
443431
444432
445433
446434
447
448
435
436
437
449438
450
451
452
453
454
455
456
457439
458
459
460
461
462
440
463441
464
465
466
467
468
469
442
443
444
445
470446
471
472
473
474
475
447
476448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
477463
478
479
480
481
482
483
464
465
466
467
468
469
484470
485471
486472
......
488474
489475
490476
491
492
493
477
478
479
480
494481
495482
496
497
498
483
484
485
486
499487
500488
501
489
502490
503
491
504492
505493
506494
507495
508496
509497
510
511
498
499
500
512501
513
514
502
503
515504
516
517
505
506
518507
519
520
508
509
521510
522
523
511
512
524513
525
526
514
515
527516
528
529
517
518
530519
531520
532521
533
534
522
523
524
535525
536
537
526
527
538528
539
529
530
531
540532
541
542
533
534
543535
544
545
536
537
546538
547
548
539
540
549541
550
551
552
553
554
555
542
543
556544
557545
558546
/*
* 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
* 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
*/
//
// Modifiers for EFI Runtime and Boot Services
//
#define EFI_RUNTIMESERVICE
#define EFIAPI
#define IN
#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_WARN_DELETE_FAILURE EFIWARN (2)
#define EFI_WARN_WRITE_FAILURE EFIWARN (3)
#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN (4)
//
// EFI Specification Revision information
//
#define EFI_SPECIFICATION_MAJOR_REVISION 1
#define EFI_SPECIFICATION_MINOR_REVISION 10
typedef struct {
typedef struct
{
EFI_UINT32 Data1;
EFI_UINT16 Data2;
EFI_UINT16 Data3;
#define EFI_GLOBAL_VARIABLE_GUID \
{0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C} }
typedef union {
typedef union
{
EFI_GUID Guid;
EFI_UINT8 Raw[16];
} EFI_GUID_UNION;
// Nanosecond: 0 - 999,999,999
// TimeZone: -1440 to 1440 or 2047
//
typedef struct {
typedef struct
{
EFI_UINT16 Year;
EFI_UINT8 Month;
EFI_UINT8 Day;
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 {
EfiMaxMemoryType
} EFI_MEMORY_TYPE;
typedef struct {
EFI_UINT64 Signature;
EFI_UINT32 Revision;
EFI_UINT32 HeaderSize;
EFI_UINT32 CRC32;
EFI_UINT32 Reserved;
typedef struct
{
EFI_UINT64Signature;
EFI_UINT32Revision;
EFI_UINT32HeaderSize;
EFI_UINT32CRC32;
EFI_UINT32Reserved;
} __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;
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
IN VOID * Data
) __attribute__((regparm(0)));
//
// EFI Time
//
typedef struct {
typedef struct
{
EFI_UINT32 Resolution;
EFI_UINT32 Accuracy;
EFI_BOOLEAN SetsToZero;
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.
//
// 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
#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;
typedef struct
{
EFI_TABLE_HEADERHdr;
//
// Time services
//
EFI_PTR32 GetTime;
EFI_PTR32 SetTime;
EFI_PTR32 GetWakeupTime;
EFI_PTR32 SetWakeupTime;
// Time Services
EFI_PTR32GetTime;
EFI_PTR32SetTime;
EFI_PTR32GetWakeupTime;
EFI_PTR32SetWakeupTime;
//
// Virtual memory services
//
EFI_PTR32 SetVirtualAddressMap;
EFI_PTR32 ConvertPointer;
// Virtual Memory Services
//
// Variable services
//
EFI_PTR32 GetVariable;
EFI_PTR32 GetNextVariableName;
EFI_PTR32 SetVariable;
EFI_PTR32 SetVirtualAddressMap;
EFI_PTR32 ConvertPointer;
//
// Misc
//
EFI_PTR32 GetNextHighMonotonicCount;
EFI_PTR32 ResetSystem;
// Variable Services
EFI_PTR32 GetVariable;
EFI_PTR32 GetNextVariableName;
EFI_PTR32 SetVariable;
// Miscellaneous Services
EFI_PTR32 GetNextHighMonotonicCount;
EFI_PTR32 ResetSystem;
#ifdef TIANO_EXTENSION_FLAG
//
// ////////////////////////////////////////////////////
// Extended EFI Services
//////////////////////////////////////////////////////
//
EFI_PTR32 ReportStatusCode;
// ////////////////////////////////////////////////////
// Extended EFI Services
//////////////////////////////////////////////////////
EFI_PTR32 ReportStatusCode;
#endif
} __attribute__((aligned(8))) EFI_RUNTIME_SERVICES_32;
typedef struct {
EFI_TABLE_HEADER Hdr;
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;
// Time services
//
// Variable services
//
EFI_PTR64 GetVariable;
EFI_PTR64 GetNextVariableName;
EFI_PTR64 SetVariable;
EFI_PTR64 GetTime;
EFI_PTR64 SetTime;
EFI_PTR64 GetWakeupTime;
EFI_PTR64 SetWakeupTime;
//
// Misc
//
EFI_PTR64 GetNextHighMonotonicCount;
EFI_PTR64 ResetSystem;
// 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;
// ////////////////////////////////////////////////////
// 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;
typedef struct
{
EFI_GUID VendorGuid;
EFI_PTR32 VendorTable;
} EFI_CONFIGURATION_TABLE_32;
typedef struct {
EFI_GUID VendorGuid;
EFI_PTR64 VendorTable;
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;
typedef struct EFI_SYSTEM_TABLE_32
{
EFI_TABLE_HEADER Hdr;
EFI_PTR32 FirmwareVendor;
EFI_UINT32 FirmwareRevision;
EFI_PTR32 FirmwareVendor;
EFI_UINT32 FirmwareRevision;
EFI_HANDLE32 ConsoleInHandle;
EFI_PTR32 ConIn;
EFI_HANDLE32 ConsoleInHandle;
EFI_PTR32 ConIn;
EFI_HANDLE32 ConsoleOutHandle;
EFI_PTR32 ConOut;
EFI_HANDLE32 ConsoleOutHandle;
EFI_PTR32 ConOut;
EFI_HANDLE32 StandardErrorHandle;
EFI_PTR32 StdErr;
EFI_HANDLE32 StandardErrorHandle;
EFI_PTR32 StdErr;
EFI_PTR32 RuntimeServices;
EFI_PTR32 BootServices;
EFI_PTR32 RuntimeServices;
EFI_PTR32 BootServices;
EFI_UINT32 NumberOfTableEntries;
EFI_PTR32 ConfigurationTable;
EFI_UINT32 NumberOfTableEntries;
EFI_PTR32 ConfigurationTable;
} __attribute__((aligned(8))) EFI_SYSTEM_TABLE_32;
typedef struct EFI_SYSTEM_TABLE_64 {
EFI_TABLE_HEADER Hdr;
typedef struct EFI_SYSTEM_TABLE_64
{
EFI_TABLE_HEADER Hdr;
EFI_PTR64 FirmwareVendor;
EFI_UINT32 FirmwareRevision;
EFI_PTR64 FirmwareVendor;
EFI_UINT32 FirmwareRevision;
EFI_UINT32 __pad;
EFI_UINT32 __pad;
EFI_HANDLE64 ConsoleInHandle;
EFI_PTR64 ConIn;
EFI_HANDLE64 ConsoleInHandle;
EFI_PTR64 ConIn;
EFI_HANDLE64 ConsoleOutHandle;
EFI_PTR64 ConOut;
EFI_HANDLE64 ConsoleOutHandle;
EFI_PTR64 ConOut;
EFI_HANDLE64 StandardErrorHandle;
EFI_PTR64 StdErr;
EFI_HANDLE64 StandardErrorHandle;
EFI_PTR64 StdErr;
EFI_PTR64 RuntimeServices;
EFI_PTR64 BootServices;
EFI_PTR64 RuntimeServices;
EFI_PTR64 BootServices;
EFI_UINT64 NumberOfTableEntries;
EFI_PTR64 ConfigurationTable;
EFI_UINT64 NumberOfTableEntries;
EFI_PTR64 ConfigurationTable;
} __attribute__((aligned(8))) EFI_SYSTEM_TABLE_64;
#endif /* _PEXPERT_I386_EFI_H */
branches/ErmaC/Trunk/i386/libsaio/vbe.c
2929
3030
3131
32
33
34
35
36
32
33
34
35
36
37
38
39
3740
3841
3942
4043
41
42
44
45
46
4347
4448
4549
4650
4751
48
49
52
53
54
55
5056
5157
5258
5359
5460
55
56
61
62
63
64
5765
5866
5967
6068
6169
62
63
64
65
6670
67
71
72
73
6874
6975
7076
7177
7278
73
79
80
7481
7582
7683
77
84
85
86
87
7888
7989
8090
......
8292
8393
8494
95
8596
8697
8798
99
100
101
88102
89103
90104
......
95109
96110
97111
112
113
114
98115
99116
100117
......
102119
103120
104121
122
105123
106124
107125
126
108127
109128
110129
#include "libsaio.h"
#include "vbe.h"
/*
* Various inline routines for video I/O
*/
static inline void
outi (int port, int index, int val)
// Various inline routines for video I/O
static biosBuf_t bb;
//==============================================================================
static inline void outi(int port, int index, int val)
{
outw (port, (val << 8) | index);
}
static inline void
outib (int port, int index, int val)
//==============================================================================
static inline void outib(int port, int index, int val)
{
outb (port, index);
outb (port + 1, val);
}
static inline int
ini (int port, int index)
//==============================================================================
static inline int ini(int port, int index)
{
outb (port, index);
return inb (port + 1);
}
static inline void
rmwi (int port, int index, int clear, int set)
//==============================================================================
static inline void rmwi(int port, int index, int clear, int set)
{
outb (port, index);
outb (port + 1, (inb (port + 1) & ~clear) | set);
}
/*
* Globals
*/
static biosBuf_t bb;
int getVBEInfo( void * infoBlock )
//==============================================================================
int getVBEInfo(void * infoBlock)
{
bb.intno = 0x10;
bb.eax.rr = funcGetControllerInfo;
bb.es = SEG( infoBlock );
bb.edi.rr = OFF( infoBlock );
bios( &bb );
bios(&bb);
return(bb.eax.r.h);
}
int getVBEModeInfo( int mode, void * minfo_p )
//==============================================================================
int getVBEModeInfo(int mode, void * minfo_p)
{
bb.intno = 0x10;
bb.eax.rr = funcGetModeInfo;
bb.es = SEG(minfo_p);
bb.edi.rr = OFF(minfo_p);
bios(&bb);
return(bb.eax.r.h);
}
//==============================================================================
int getVBEDACFormat(unsigned char *format)
{
bb.intno = 0x10;
return(bb.eax.r.h);
}
//==============================================================================
int setVBEDACFormat(unsigned char format)
{
bb.intno = 0x10;
bb.ebx.r.l = subfuncSet;
bb.ebx.r.h = format;
bios(&bb);
return(bb.eax.r.h);
}
/*
* Default GTF parameter values.
*/
branches/ErmaC/Trunk/i386/libsaio/bootstruct.h
6262
6363
6464
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
8084
8185
82
83
84
85
86
87
88
89
90
91
8692
8793
8894
/*
* 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;
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
typedef struct
{
unsigned long address; // address where driver was loaded
unsigned long size; // number of bytes
unsigned long type; // driver type
} driver_config_t;
/*
branches/ErmaC/Trunk/i386/libsaio/device_tree.c
11
2
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
323
424
525
626
7
27
828
929
1030
1131
1232
13
14
15
33
34
35
36
1637
1738
1839
1940
20
21
22
41
42
43
44
2345
2446
2547
2648
2749
28
50
51
2952
3053
3154
......
4871
4972
5073
51
52
53
54
74
75
76
77
78
5579
5680
5781
5882
5983
6084
61
85
6286
6387
64
65
88
89
90
91
6692
67
93
6894
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
95
9196
92
93
94
97
98
99
100
95101
96
97
98
99
100
101
102
103
102
104103
105
106
107
108
104
105
106
107
109108
110
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
111152
112153
113
114
154
155
156
157
115158
116
159
117160
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
161
162
163
142164
143
144
145
146
147
148
149
150
151
152
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
153214
154215
155
156
216
217
218
219
157220
158
159
221
222
160223
161
162
224
225
226
227
228
163229
164
165
230
231
166232
167233
168
169
234
235
236
237
170238
171
172
173
174
175
176
177
178
179
180
181
182
183
239
240
241
242
243
244
245
246
247
248
249
250
251
184252
185253
254
186255
187
188
256
189257
190
191
258
192259
193
194
260
261
195262
196
197
198
199
200
201
263
202264
203
204
205
206
207
208
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
209281
210
211
212
213
214
282
283
284
285
215286
216287
217
218
288
289
290
291
219292
220
221
222
223
293
294
295
296
224297
225
298
299
300
301
226302
227
228
303
304
229305
230
231
232
233
234
235
236
237
238
306
307
308
309
310
311
312
313
314
239315
240
241
242
243
316
244317
245
318
319
320
321
322
323
324
325
246326
247327
248
249
250
328
329
330
251331
252332
253333
254334
255335
256
257
336
258337
259
260
338
339
261340
262
341
342
263343
264
344
345
346
347
265348
266349
267
268
269
350
270351
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
289383
290384
291
292
385
386
387
388
293389
294
390
295391
296
297
298
299
300
301
302
303
304
305
392
393
394
395
396
397
398
399
400
401
402
403
404
306405
307406
308
309
407
408
409
410
310411
311
312
313
314
412
413
414
415
315416
316
417
317418
318
319
320
419
420
321421
322
323
324
422
325423
326
327
424
425
426
427
428
429
430
328431
329
330
331
332
333
432
433
434
435
334436
335
336
337
338
339
340
341
342
343
344
345
437
346438
347
348
349
350
351
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
352472
353473
354474
355475
356
357
476
477
478
358479
359
360
480
481
361482
362
363
364
483
484
485
486
365487
366
367
368
369
370
371
372
373
374
375
376
377
378
379
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
380511
381512
382
383
513
514
515
516
384517
385
386
387
388
518
519
520
521
522
523
524
525
389526
390527
391
392
528
393529
394
395
530
531
396532
397533
398
399
534
400535
401
402
403
404
405
536
537
538
539
540
406541
407
408
409
542
543
544
410545
411
412
413
414
415
416
417
418
419
420
421
546
547
548
549
550
551
552
553
554
555
556
557
558
422559
423
560
424561
425562
426
427
563
428564
429
565
430566
431
567
432568
433
434
435
436
437
438
439
440
441
569
570
571
572
573
574
575
576
577
578
579
442580
443581
444
445
582
446583
447
584
448585
449586
450587
451588
452589
453590
454
455
456
457
458
459
460
461
591
592
593
594
595
596
597
598
462599
463
600
464601
465
466
467
468
602
603
604
605
469606
470
471
472
473
607
608
609
610
474611
475
476
477
478
612
613
614
615
479616
480
481
617
618
482619
483
620
484621
485
622
486623
487
624
488625
489
626
490627
491
628
492629
493
630
494631
495
632
496633
497
634
498635
499
500
501
502
636
637
638
639
640
641
642
643
644
645
646
503647
504
505
506
507
508
509
510
648
649
511650
512
513
514
515
516
517
651
652
653
654
655
656
657
658
518659
519
520
521
522
523
524
525
526
527
528
529
530
531
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
532675
533676
534
677
535678
536679
537680
/*
* Copyright (c) 2005 Apple Computer, Inc. All Rights Reserved.
* Copyright (c) 2005 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@
*/
#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
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
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)*/
// Entry Name Definitions (Entry Names are C-Strings).
enum {
kDTMaxEntryNameLength = 31 /* Max length of a C-String Entry Name (terminator not included) */
};
#define RoundToLong(x)(((x) + 3) & ~3)
static struct _DTSizeInfo {
uint32_t numNodes;
uint32_t numProperties;
uint32_t totalPropertySize;
static struct _DTSizeInfo
{
uint32_tnumNodes;
uint32_tnumProperties;
uint32_ttotalPropertySize;
} DTInfo;
#define kAllocSize 4096
static Node *rootNode;
static Node *freeNodes, *allocedNodes;
static Node * freeNodes, *allocedNodes;
static Property *freeProperties, *allocedProperties;
Property *
DT__AddProperty(Node *node, const char *name, uint32_t length, void *value)
//==============================================================================
Property * DT__AddProperty(Node *node, const char *name, uint32_t length, void *value)
{
Property *prop;
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);
if (buf == 0) return 0;
int i;
DPRINTF("Allocating more free properties\n");
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;
DPRINTF("DT__AddProperty([Node '%s'], '%s', %d, 0x%x)\n", DT__GetName(node), name, length, value);
prop->name = name;
prop->length = length;
prop->value = value;
if (freeProperties == NULL)
{
void *buf = malloc(kAllocSize);
int i;
// 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("Allocating more free properties\n");
DPRINTF("Done [0x%x]\n", prop);
DTInfo.numProperties++;
DTInfo.totalPropertySize += RoundToLong(length);
if (buf == 0)
{
return 0;
}
return prop;
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 * DT__AddChild(Node *parent, const char *name)
{
Node *node;
Node *node;
if (freeNodes == NULL) {
void *buf = malloc(kAllocSize);
if (buf == 0) return 0;
int i;
DPRINTF("Allocating more free nodes\n");
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 (freeNodes == NULL)
{
void *buf = malloc(kAllocSize);
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;
if (buf == 0)
{
return 0;
}
int i;
DPRINTF("Allocating more free nodes\n");
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)
//==============================================================================
void DT__FreeProperty(Property *prop)
{
prop->next = freeProperties;
freeProperties = prop;
prop->next = freeProperties;
freeProperties = prop;
}
void
DT__FreeNode(Node *node)
//==============================================================================
void DT__FreeNode(Node *node)
{
node->next = freeNodes;
freeNodes = node;
node->next = freeNodes;
freeNodes = node;
}
void
DT__Initialize(void)
//==============================================================================
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");
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.
* Free up memory used by in-memory representation of device tree.
*/
void
DT__Finalize(void)
void DT__Finalize(void)
{
Node *node;
Property *prop;
Node *node;
Property *prop;
DPRINTF("DT__Finalize\n");
for (prop = allocedProperties; prop != NULL; prop = prop->next) {
free(prop->value);
}
allocedProperties = NULL;
freeProperties = NULL;
DPRINTF("DT__Finalize\n");
for (node = allocedNodes; node != NULL; node = node->next) {
free((void *)node->children);
}
allocedNodes = NULL;
freeNodes = NULL;
rootNode = NULL;
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;
// XXX leaks any created strings
DTInfo.numNodes = 0;
DTInfo.numProperties = 0;
DTInfo.totalPropertySize = 0;
}
static void *
FlattenNodes(Node *node, void *buffer)
//==============================================================================
static void * FlattenNodes(Node *node, void *buffer)
{
Property *prop;
DeviceTreeNode *flatNode;
DeviceTreeNodeProperty *flatProp;
int count;
Property *prop;
DeviceTreeNode *flatNode;
DeviceTreeNodeProperty *flatProp;
int count;
if (node == 0) return buffer;
if (node == 0)
{
return buffer;
}
flatNode = (DeviceTreeNode *)buffer;
buffer += sizeof(DeviceTreeNode);
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, 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);
}
for (count = 0, node = node->children; node != 0; count++, node = node->next) {
buffer = FlattenNodes(node, buffer);
}
flatNode->nChildren = count;
flatNode->nProperties = count;
return buffer;
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.
/*==============================================================================
* 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)
void DT__FlattenDeviceTree(void **buffer_p, uint32_t *length)
{
uint32_t totalSize;
void *buf;
uint32_t totalSize;
void * buf;
DPRINTF("DT__FlattenDeviceTree(0x%x, 0x%x)\n", buffer_p, length);
DPRINTF("DT__FlattenDeviceTree(0x%x, 0x%x)\n", buffer_p, length);
#if DEBUG
if (buffer_p) DT__PrintTree(rootNode);
if (buffer_p)
{
DT__PrintTree(rootNode);
}
#endif
totalSize = DTInfo.numNodes * sizeof(DeviceTreeNode) +
DTInfo.numProperties * sizeof(DeviceTreeNodeProperty) +
DTInfo.totalPropertySize;
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;
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)
//==============================================================================
char * DT__GetName(Node *node)
{
Property *prop;
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)";
//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 * DT__FindNode(const char *path, bool createIfMissing)
{
Node *node, *child;
DTPropertyNameBuf nameBuf;
char *bp;
int i;
Node *node, *child;
DTPropertyNameBuf nameBuf;
char *bp;
int i;
DPRINTF("DT__FindNode('%s', %d)\n", path, createIfMissing);
DPRINTF("DT__FindNode('%s', %d)\n", path, createIfMissing);
// Start at root
node = rootNode;
DPRINTF("root = 0x%x\n", rootNode);
// Start at root
node = rootNode;
while (node) {
// Skip leading slash
while (*path == '/') path++;
DPRINTF("root = 0x%x\n", rootNode);
for (i=0, bp = nameBuf; ++i < kDTMaxEntryNameLength && *path && *path != '/'; bp++, path++) *bp = *path;
*bp = '\0';
while (node)
{
// Skip leading slash
while (*path == '/')
{
path++;
}
if (nameBuf[0] == '\0') {
// last path entry
break;
}
DPRINTF("Node '%s'\n", nameBuf);
for (i = 0, bp = nameBuf; ++i < kDTMaxEntryNameLength && *path && *path != '/'; bp++, path++)
{
*bp = *path;
}
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);
*bp = '\0';
child = DT__AddChild(node, str);
}
node = child;
}
return node;
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)
//==============================================================================
void DT__PrintNode(Node *node, int level)
{
char spaces[10], *cp = spaces;
Property *prop;
char spaces[10], *cp = spaces;
Property *prop;
if (level > 9) level = 9;
while (level--) *cp++ = ' ';
*cp = '\0';
if (level > 9)
{
level = 9;
}
printf("%s===Node===\n", spaces);
for (prop = node->properties; prop; prop = prop->next) {
char c = *((char *)prop->value);
if (prop->length < 64 && (
strcmp(prop->name, "name") == 0 ||
(c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') || c == '_')) {
printf("%s Property '%s' [%d] = '%s'\n", spaces, prop->name, prop->length, prop->value);
} else {
printf("%s Property '%s' [%d] = (data)\n", spaces, prop->name, prop->length);
}
}
printf("%s==========\n", spaces);
while (level--)
{
*cp++ = ' ';
}
*cp = '\0';
printf("%s===Node===\n", spaces);
for (prop = node->properties; prop; prop = prop->next)
{
char c = *((char *)prop->value);
if (prop->length < 64 && (strcmp(prop->name, "name") == 0 || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'))
{
printf("%s Property '%s' [%d] = '%s'\n", spaces, prop->name, prop->length, prop->value);
}
else
{
printf("%s Property '%s' [%d] = (data)\n", spaces, prop->name, prop->length);
}
}
printf("%s==========\n", spaces);
}
static void
_PrintTree(Node *node, int level)
//==============================================================================
static void _PrintTree(Node *node, int level)
{
DT__PrintNode(node, level);
level++;
for (node = node->children; node; node = node->next)
_PrintTree(node, level);
DT__PrintNode(node, level);
level++;
for (node = node->children; node; node = node->next)
{
_PrintTree(node, level);
}
}
void
DT__PrintTree(Node *node)
void DT__PrintTree(Node *node)
{
if (node == 0) node = rootNode;
_PrintTree(node, 0);
if (node == 0) node = rootNode;
_PrintTree(node, 0);
}
void
DT__PrintFlattenedNode(DTEntry entry, int level)
void DT__PrintFlattenedNode(DTEntry entry, int level)
{
char spaces[10], *cp = spaces;
DTPropertyIterator propIter;
char *name;
void *prop;
int propSize;
char spaces[10], *cp = spaces;
DTPropertyIterator propIter;
char *name;
void *prop;
int propSize;
if (level > 9) level = 9;
while (level--) *cp++ = ' ';
*cp = '\0';
if (level > 9) level = 9;
while (level--) *cp++ = ' ';
*cp = '\0';
printf("%s===Entry %p===\n", spaces, entry);
if (kSuccess != DTCreatePropertyIterator(entry, &propIter)) {
printf("Couldn't create property iterator\n");
return;
}
while( kSuccess == DTIterateProperties( propIter, &name)) {
if( kSuccess != DTGetProperty( entry, name, &prop, &propSize ))
continue;
printf("%s Property %s = %s\n", spaces, name, prop);
}
DTDisposePropertyIterator(propIter);
printf("%s===Entry %p===\n", spaces, entry);
if (kSuccess != DTCreatePropertyIterator(entry, &propIter))
{
printf("Couldn't create property iterator\n");
return;
}
while( kSuccess == DTIterateProperties( propIter, &name))
{
if( kSuccess != DTGetProperty( entry, name, &prop, &propSize ))
continue;
printf("%s Property %s = %s\n", spaces, name, prop);
}
DTDisposePropertyIterator(propIter);
printf("%s==========\n", spaces);
printf("%s==========\n", spaces);
}
static void
_PrintFlattenedTree(DTEntry entry, int level)
static void _PrintFlattenedTree(DTEntry entry, int level)
{
DTEntryIterator entryIter;
DTEntryIterator entryIter;
PrintFlattenedNode(entry, level);
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);
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)
void DT__PrintFlattenedTree(DTEntry entry)
{
_PrintFlattenedTree(entry, 0);
_PrintFlattenedTree(entry, 0);
}
int
main(int argc, char **argv)
{
DTEntry dtEntry;
DTPropertyIterator propIter;
DTEntryIterator entryIter;
void*prop;
intpropSize;
char*name;
void *flatTree;
uint32_t flatSize;
DTEntrydtEntry;
DTPropertyIteratorpropIter;
DTEntryIteratorentryIter;
void*prop;
intpropSize;
char*name;
void*flatTree;
uint32_tflatSize;
Node *node;
Node *node;
node = AddChild(NULL, "device-tree");
AddProperty(node, "potato", 4, "foo");
AddProperty(node, "chemistry", 4, "bar");
AddProperty(node, "physics", 4, "baz");
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(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 = 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");
node = FindNode("/this/is/a/test", 1);
AddProperty(node, "dddd", 12, "abcdefghijk");
printf("In-memory tree:\n\n");
printf("In-memory tree:\n\n");
PrintTree(rootNode);
PrintTree(rootNode);
FlattenDeviceTree(&flatTree, &flatSize);
FlattenDeviceTree(&flatTree, &flatSize);
printf("Flat tree = %p, size %d\n", flatTree, flatSize);
printf("Flat tree = %p, size %d\n", flatTree, flatSize);
dtEntry = (DTEntry)flatTree;
dtEntry = (DTEntry)flatTree;
printf("\n\nPrinting flat tree\n\n");
printf("\n\nPrinting flat tree\n\n");
DTInit(dtEntry);
DTInit(dtEntry);
PrintFlattenedTree((DTEntry)flatTree);
PrintFlattenedTree((DTEntry)flatTree);
#if 0
printf("=== Entry %p ===\n", dtEntry);
if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter)) {
printf("Couldn't create property iterator\n");
return 1;
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);
}
while( kSuccess == DTIterateProperties( propIter, &name)) {
if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))
continue;
printf(" Property %s = %s\n", name, prop);
}
DTDisposePropertyIterator(propIter);
printf("========\n");
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 != 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);
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;
return 0;
}
#endif
branches/ErmaC/Trunk/i386/libsaio/hfs.c
7777
7878
7979
80
81
82
83
80
81
8482
85
86
87
88
89
83
84
9085
9186
9287
93
94
88
9589
96
97
90
9891
9992
10093
......
10598
10699
107100
108
109
101
110102
111103
104
105
112106
113107
114108
......
117111
118112
119113
114
115
116
120117
121118
122119
......
124121
125122
126123
124
125
126
127127
128128
129
130
131
132
129
130
131
132
133133
134134
135135
136
137
136
137
138138
139139
140140
141141
142
143
144
142145
143146
144
145
147
148
146149
147
150
151
148152
149
153
150154
151
152
155
156
153157
154158
155
156
157
158
159
160
161
162
163
159164
160165
161
162
163
164
165
166
167
166
167
168
169
170
171
172
168173
169174
170175
......
177182
178183
179184
180
181
185
186
187
182188
183
184
185
189
190
191
186192
187193
188194
......
194200
195201
196202
197
198
203
199204
200205
201206
202207
203208
204
205
206
207
209
210
211
212
213
208214
209
210
215
216
211217
212218
213219
......
219225
220226
221227
222
223
224
225
226
227
228
229
230
231
232
233
228234
229235
230236
......
248254
249255
250256
251
252
253
254
257
258
259
260
261
255262
256
263
257264
258265
266
267
268
259269
260270
261271
......
267277
268278
269279
270
271
280
281
282
283
284
272285
273286
274
275
276
277
278
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
279312
280
281
282
283
284
313
285314
286
287
288
289
290
291315
292316
293317
......
307331
308332
309333
310
311
312
334
313335
314
315
336
316337
317
338
318339
319
340
341
342
343
320344
321
322
323
324
325
326
327
328
329
330
331
345
346
347
348
332349
333
334
335
336
337
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
338365
339
340
341
366
367
368
369
342370
343
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
344405
345406
346
347
407
408
409
410
348411
349412
350413
......
353416
354417
355418
356
419
420
421
422
357423
358
359
360
424
425
426
361427
362
363
364
428
429
430
365431
366
432
367433
368
434
369435
370
371
436
437
372438
373439
374440
375
376
441
442
443
377444
378
379
380
381
382
445
446
447
448
449
383450
384
451
385452
386
387
388
389
390
391
392
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
393482
394
395
396
397
398
483
399484
400
401
402
403
404
485
486
487
488
489
490
491
492
405493
406
407
408
409
410
411
412494
413
414
415
495
496
497
416498
417
418
499
500
419501
420502
503
504
505
421506
422507
423
424
508
509
425510
511
512
513
426514
427515
428516
517
518
429519
430520
431521
432522
433
434
435
436
437
523
524
525
526
527
438528
439
440
441
442
443
444
445
446
447
529
530
531
532
533
534
535
536
537
538
539
540
448541
449
450
451
452
542
543
544
545
546
453547
454
455
456
548
549
550
551
457552
458
459
460
461
553
554
555
556
557
558
559
462560
463
464
561
465562
466
563
467564
468565
469
470
566
567
568
569
471570
472
473
571
572
474573
475
574
476575
477
478
479
480
481
482
576
577
578
579
580
581
483582
484
485
486
487
488
489
490
583
584
585
586
587
588
491589
492
493
494
495
496
497
498
499
590
591
592
593
594
595
596
597
598
500599
501
502
503
504
505
506
507
508
509
510
511
600
601
602
603
604
605
606
607
608
609
610
512611
513612
514613
......
519618
520619
521620
522
621
523622
524
525
526
527
528
623
624
625
626
627
529628
530
629
630
631
632
633
634
531635
532636
533
534
637
638
639
640
535641
536
537
538
539
642
643
644
645
540646
541
542
543
544
647
648
649
650
651
652
545653
546
547
548
654
549655
550
551
656
657
658
659
660
552661
553
554
555
556
662
557663
558
664
665
559666
560
561
562
563
564
565
667
566668
567
568
569
669
670
671
672
570673
571
572
573
574
575
576
577
578
579
580
674
581675
582
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
583706
584707
585
586
587
708
709
710
711
588712
589
590
591
592
713
714
715
716
593717
594
595
596
597
598
599
600
718
719
720
721
722
723
724
725
726
727
601728
602
603
604
729
730
731
605732
606733
607734
......
613740
614741
615742
616
617
618
743
744
745
746
619747
620748
621
622
623
624
625
626
749
750
751
752
753
754
755
756
627757
628758
629759
630760
631
632
633
761
762
763
764
765
634766
635767
636768
637
769
638770
639
771
640772
641773
642
643
774
775
776
777
644778
645
646
647
648
779
780
781
782
649783
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
784
785
786
787
788
665789
666
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
667812
668813
814
815
816
669817
670818
671
672
673
819
820
821
674822
675
676
677
678
679
680
681
682
683
684
823
824
825
826
827
828
829
830
831
832
833
834
835
685836
686
837
687838
688839
840
841
842
689843
690844
691
692
693
694
695
696
697
698
845
846
847
848
849
850
851
852
699853
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
720883
721
722
723
724
725
726
727
728
729
730
731
884
885
886
887
888
732889
733
734
735
736
890
891
892
893
894
737895
738
739
740
741
896
897
898
899
742900
743
744
745
746
747
901
902
903
904
748905
749
906
907
908
750909
751
752
753
754
755
756
757
758
759
760
761
762
763
910
911
912
764913
765
766
767
768
914
769915
770
771
772
773
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
774958
775
776
777
778
779
959
960
961
962
963
964
965
966
967
968
780969
781
782
970
971
972
973
974
975
783976
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
7991010
800
1011
8011012
802
803
804
805
806
807
808
809
810
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
8111024
812
1025
8131026
814
1027
8151028
8161029
817
818
1030
1031
1032
1033
8191034
820
821
1035
1036
8221037
823
824
825
826
827
828
829
830
831
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
8321050
8331051
834
835
836
1052
1053
1054
1055
8371056
8381057
8391058
......
8431062
8441063
8451064
846
1065
1066
1067
1068
8471069
8481070
8491071
......
8571079
8581080
8591081
1082
8601083
8611084
8621085
......
8791102
8801103
8811104
882
1105
1106
1107
1108
1109
8831110
8841111
8851112
1113
8861114
8871115
8881116
......
9001128
9011129
9021130
903
904
1131
9051132
9061133
9071134
908
1135
1136
1137
1138
9091139
9101140
9111141
912
913
1142
9141143
9151144
9161145
9171146
9181147
9191148
920
1149
1150
1151
1152
9211153
9221154
9231155
9241156
1157
1158
1159
9251160
9261161
927
928
929
1162
9301163
931
932
1164
1165
9331166
1167
1168
1169
1170
1171
1172
1173
1174
1175
9341176
9351177
9361178
1179
1180
1181
9371182
9381183
939
1184
9401185
9411186
9421187
943
944
1188
1189
1190
1191
1192
1193
1194
1195
9451196
9461197
9471198
9481199
1200
1201
1202
9491203
9501204
9511205
952
1206
9531207
9541208
9551209
......
9581212
9591213
9601214
961
962
1215
1216
1217
1218
1219
1220
1221
1222
9631223
9641224
9651225
......
9691229
9701230
9711231
1232
1233
1234
9721235
9731236
9741237
975
1238
9761239
9771240
9781241
......
9811244
9821245
9831246
984
985
1247
1248
1249
1250
1251
1252
1253
1254
9861255
9871256
9881257
9891258
990
991
992
9931259
1260
1261
1262
1263
9941264
9951265
9961266
......
10081278
10091279
10101280
1281
1282
1283
10111284
10121285
1013
1014
1286
1287
10151288
1016
1017
1289
1290
10181291
1019
1020
1292
1293
10211294
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
10431332
1044
1333
10451334
10461335
1336
1337
1338
10471339
10481340
1049
1050
1341
10511342
1052
1053
1343
10541344
1055
1056
1345
1346
10571347
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
10791385
1080
1386
10811387
10821388
#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 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 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 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 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 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);
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);
// Don't bother with location
}
//==============================================================================
void HFSFree(CICell ih)
{
if(gCurrentIH == ih)
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);
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)
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;
long extentSize, extentFile, nodeSize;
void *extent;
if (ih == gCurrentIH) {
if (ih == gCurrentIH)
{
#ifdef __i386__
CacheInit(ih, gCacheBlockSize);
CacheInit(ih, gCacheBlockSize);
#endif
return 0;
}
return 0;
}
#ifdef __i386__
if (!gTempStr) gTempStr = (char *)malloc(4096);
if (!gLinkTemp) gLinkTemp = (char *)malloc(64);
if (!gBTreeHeaderBuffer) gBTreeHeaderBuffer = (char *)malloc(512);
if (!gHFSMdbVib) {
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;
}
if (!gHFSPlusHeader)
{
gHFSPlusHeader = (char *)malloc(kBlockSize);
gHFSPlus = (HFSPlusVolumeHeader *)gHFSPlusHeader;
}
if (!gTempStr || !gLinkTemp || !gBTreeHeaderBuffer || !gHFSMdbVib || !gHFSPlusHeader) return -1;
#endif /* __i386__ */
gAllocationOffset = 0;
Seek(ih, kMDBBaseOffset);
Read(ih, (long)gHFSMdbVib, kBlockSize);
if ( SWAP_BE16(gHFSMDB->drSigWord) == kHFSSigWord ) {
gAllocationOffset = SWAP_BE16(gHFSMDB->drAlBlSt) * 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;
// See if it is HFSPlus
if (SWAP_BE16(gHFSMDB->drEmbedSigWord) != kHFSPlusSigWord) {
// Normal HFS;
gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSMDB->drAlBlkSiz);
CacheInit(ih, gCacheBlockSize);
gCurrentIH = ih;
extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
extentFile = kHFSCatalogFileID;
ReadExtent(extent, extentSize, extentFile, 0, 256,
gBTreeHeaderBuffer + kBTreeCatalog * 256, 0);
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);
}
if (nodeSize > gBlockSize)
{
gCacheBlockSize = nodeSize;
CacheInit(ih, gCacheBlockSize);
}
return 0;
}
return 0;
}
// Calculate the offset to the embeded HFSPlus volume.
gAllocationOffset += (long long)SWAP_BE16(gHFSMDB->drEmbedExtent.startBlock) *
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;
}
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);
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);
}
if (nodeSize > gBlockSize)
{
gCacheBlockSize = nodeSize;
CacheInit(ih, gCacheBlockSize);
}
return 0;
return 0;
}
//==============================================================================
long HFSLoadFile(CICell ih, char * filePath)
{
return HFSReadFile(ih, filePath, (void *)gFSLoadAddress, 0, 0);
char devStr[12];
long dirID, result, flags =0;
if (HFSInitPartition(ih) == -1) return -1;
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) {
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;
}
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.
return length;
}
long HFSGetDirEntry(CICell ih, char * dirPath, long long * dirIndex, char ** name,
long * flags, long * time,
FinderInfo * finderInfo, long * infoValid)
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 = 0;
char entry[512];
if (HFSInitPartition(ih) == -1) return -1;
long dirID, dirFlags = 0;
if (*dirIndex == -1) return -1;
if (HFSInitPartition(ih) == -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 == -1)
{
return -1;
}
if (*dirIndex == 0) {
ResolvePathToCatalogEntry(dirPath, &dirFlags, entry, dirID, dirIndex);
if (*dirIndex == 0) *dirIndex = -1;
if ((dirFlags & kFileTypeMask) != kFileTypeUnknown) 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]);
}
GetCatalogEntry(dirIndex, name, flags, time, finderInfo, infoValid);
if (*dirIndex == 0) *dirIndex = -1;
if ((*flags & kFileTypeMask) == kFileTypeUnknown) return -1;
if (dirID == 0)
{
return -1;
}
return 0;
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)
//==============================================================================
void HFSGetDescription(CICell ih, char *str, long strMaxLen)
{
UInt16 nodeSize;
char *name;
long flags =0, time;
if (HFSInitPartition(ih) == -1) { return; }
if (HFSInitPartition(ih) == -1)
{
return;
}
/* Fill some crucial data structures by side effect. */
dirIndex = 0;
HFSGetDirEntry(ih, "/", &dirIndex, &name, &flags, &time, 0, 0);
/* 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);
/* 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;
dirIndex = (long long) firstLeafNode * nodeSize;
GetCatalogEntry(&dirIndex, &name, &flags, &time, 0, 0);
GetCatalogEntry(&dirIndex, &name, &flags, &time, 0, 0);
strncpy(str, name, strMaxLen);
str[strMaxLen] = '\0';
strncpy(str, name, strMaxLen);
str[strMaxLen] = '\0';
}
long
HFSGetFileBlock(CICell ih, char *filePath, unsigned long long *firstBlock)
//==============================================================================
long HFSGetFileBlock(CICell ih, char *filePath, unsigned long long *firstBlock)
{
char entry[512];
long dirID, result, flags =0;
void *extents;
HFSCatalogFile *hfsFile = (void *)entry;
HFSPlusCatalogFile *hfsPlusFile = (void *)entry;
char entry[512];
long dirID, result, flags =0;
void *extents;
HFSCatalogFile *hfsFile = (void *)entry;
HFSPlusCatalogFile *hfsPlusFile = (void *)entry;
if (HFSInitPartition(ih) == -1) return -1;
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) {
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;
}
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 (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);
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;
*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;
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;
void*extents;
longfileID;
uint64_tfileLength;
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 (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 (offset > fileLength)
{
printf("Offset is too large.\n");
return -1;
}
if ((*length == 0) || ((offset + *length) > fileLength)) {
*length = fileLength - offset;
}
if ((*length == 0) || ((offset + *length) > fileLength))
{
*length = fileLength - offset;
}
/* if (*length > kLoadSize) {
printf("File is too large.\n");
return -1;
}*/
/*
if (*length > kLoadSize)
{
printf("File is too large.\n");
return -1;
}
*/
*length = ReadExtent((char *)extents, fileLength, fileID,
offset, *length, (char *)base, 0);
*length = ReadExtent((char *)extents, fileLength, fileID, offset, *length, (char *)base, 0);
return 0;
return 0;
}
static long GetCatalogEntryInfo(void * entry, long * flags, long * time,
FinderInfo * finderInfo, long * infoValid)
//==============================================================================
static long GetCatalogEntryInfo(void * entry, long * flags, long * time, FinderInfo * finderInfo, long * infoValid)
{
long tmpTime = 0;
long valid = 0;
long tmpTime = 0;
long valid = 0;
// Get information about the file.
// Get information about the file.
switch ( SWAP_BE16(*(short *)entry) )
{
case kHFSFolderRecord :
*flags = kFileTypeDirectory;
tmpTime = SWAP_BE32(((HFSCatalogFolder *)entry)->modifyDate);
break;
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 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 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 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 :
break;
default:
break;
}
}
if (time != 0) {
// Convert base time from 1904 to 1970.
*time = tmpTime - 2082844800;
}
if (infoValid) *infoValid = valid;
if (time != 0)
{
// Convert base time from 1904 to 1970.
*time = tmpTime - 2082844800;
}
return 0;
if (infoValid)
{
*infoValid = valid;
}
return 0;
}
static long ResolvePathToCatalogEntry(char * filePath, long * flags,
void * entry, long dirID, long long * dirIndex)
//==============================================================================
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;
char*restPath;
longresult, cnt, subFolderID = 0;
long longtmpDirIndex;
HFSPlusCatalogFile*hfsPlusFile;
// Copy the file name to gTempStr
cnt = 0;
while ((filePath[cnt] != '/') && (filePath[cnt] != '\0')) cnt++;
strlcpy(gTempStr, filePath, cnt+1);
// Copy the file name to gTempStr
cnt = 0;
while ((filePath[cnt] != '/') && (filePath[cnt] != '\0'))
{
cnt++;
}
// Move restPath to the right place.
if (filePath[cnt] != '\0') cnt++;
restPath = filePath + cnt;
strlcpy(gTempStr, filePath, cnt+1);
// gTempStr is a name in the current Dir.
// restPath is the rest of the path if any.
// Move restPath to the right place.
if (filePath[cnt] != '\0')
{
cnt++;
}
result = ReadCatalogEntry(gTempStr, dirID, entry, dirIndex);
if (result == -1) {
return -1;
}
restPath = filePath + cnt;
GetCatalogEntryInfo(entry, flags, 0, 0, 0);
// gTempStr is a name in the current Dir.
// restPath is the rest of the path if any.
if ((*flags & kFileTypeMask) == kFileTypeDirectory) {
if (gIsHFSPlus)
subFolderID = SWAP_BE32(((HFSPlusCatalogFolder *)entry)->folderID);
else
subFolderID = SWAP_BE32(((HFSCatalogFolder *)entry)->folderID);
}
result = ReadCatalogEntry(gTempStr, dirID, entry, dirIndex);
if ((*flags & kFileTypeMask) == kFileTypeDirectory)
result = ResolvePathToCatalogEntry(restPath, flags, entry,
subFolderID, dirIndex);
if (result == -1)
{
return -1;
}
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);
}
}
GetCatalogEntryInfo(entry, flags, 0, 0, 0);
return result;
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)
//==============================================================================
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;
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);
}
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;
nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize);
nodeBuf = (char *)malloc(nodeSize);
node = (BTNodeDescriptor *)nodeBuf;
index = (long) (*dirIndex % nodeSize);
curNode = (long) (*dirIndex / nodeSize);
GetCatalogEntryInfo(entry, flags, time, finderInfo, infoValid);
// Get the file name.
if (gIsHFSPlus) {
utf_encodestr(((HFSPlusCatalogKey *)testKey)->nodeName.unicode,
// 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';
}
}
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);
if (index == SWAP_BE16(node->numRecords))
{
index = 0;
curNode = SWAP_BE32(node->fLink);
}
*dirIndex = (long long) curNode * nodeSize + index;
free(nodeBuf);
free(nodeBuf);
return 0;
return 0;
}
static long ReadCatalogEntry(char * fileName, long dirID,
void * entry, long long * dirIndex)
//==============================================================================
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;
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);
}
// Make the catalog key.
if (gIsHFSPlus)
{
hfsPlusKey->parentID = SWAP_BE32(dirID);
length = strlen(fileName);
return ReadBTreeEntry(kBTreeCatalog, &key, entry, dirIndex);
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;
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);
}
// 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);
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 =0;
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 =0;
// 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;
}
// 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;
}
}
// 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));
curNode = SWAP_BE32(gBTHeaders[btree]->rootNode);
nodeSize = SWAP_BE16(gBTHeaders[btree]->nodeSize);
nodeBuf = (char *)malloc(nodeSize);
node = (BTNodeDescriptor *)nodeBuf;
if ((gIsHFSPlus && btree == kBTreeCatalog) && (gBTHeaders[btree]->keyCompareType == kHFSBinaryCompare))
{
gCaseSensitive = 1;
}
}
while (1) {
// Read the current node.
ReadExtent(extent, extentSize, extentFile,
(long long) curNode * nodeSize, nodeSize, nodeBuf, 1);
curNode = SWAP_BE32(gBTHeaders[btree]->rootNode);
nodeSize = SWAP_BE16(gBTHeaders[btree]->nodeSize);
nodeBuf = (char *)malloc(nodeSize);
node = (BTNodeDescriptor *)nodeBuf;
// Find the matching key.
lowerBound = 0;
upperBound = SWAP_BE16(node->numRecords) - 1;
while (lowerBound <= upperBound) {
index = (lowerBound + upperBound) / 2;
while (1)
{
// Read the current node.
ReadExtent(extent, extentSize, extentFile, (long long) curNode * nodeSize, nodeSize, nodeBuf, 1);
GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData);
// Find the matching key.
lowerBound = 0;
upperBound = SWAP_BE16(node->numRecords) - 1;
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);
}
}
while (lowerBound <= upperBound)
{
index = (lowerBound + upperBound) / 2;
if (result < 0) upperBound = index - 1; // search < trial
else if (result > 0) lowerBound = index + 1; // search > trial
else break; // search = trial
}
GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData);
if (result < 0) {
index = upperBound;
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;
}
// 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; }
// 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);
}
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);
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;
}
// 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);
free(nodeBuf);
return 0;
return 0;
}
static void GetBTreeRecord(long index, char * nodeBuffer, long nodeSize,
char ** key, char ** data)
//==============================================================================
static void GetBTreeRecord(long index, char * nodeBuffer, long nodeSize, char ** key, char ** data)
{
long keySize;
long recordOffset;
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);
}
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)
//==============================================================================
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 extentDensity, sizeofExtent, currentExtentSize;
char *currentExtent, *extentBuffer = 0, *bufferPos = buffer;
if (offset >= extentSize) return 0;
if (offset >= extentSize)
{
return 0;
}
if (gIsHFSPlus)
{
}
lastOffset = offset + size;
while (offset < lastOffset)
{
blockNumber = offset / gBlockSize;
if (extentBuffer == 0)
{
extentBuffer = malloc(sizeofExtent * extentDensity);
if (extentBuffer == 0) return -1;
if (extentBuffer == 0)
{
return -1;
}
}
nextExtentBlock = nextExtent / extentDensity;
if (currentExtentBlock != nextExtentBlock)
{
ReadExtentsEntry(extentFile, countedBlocks, extentBuffer);
countedBlocks += currentExtentSize;
}
readOffset = ((blockNumber - countedBlocks) * gBlockSize) +
(offset % gBlockSize);
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;
if (readSize > (size - sizeRead))
{
readSize = size - sizeRead;
}
readOffset += (long long)GetExtentStart(currentExtent, 0) * gBlockSize;
CacheRead(gCurrentIH, bufferPos, gAllocationOffset + readOffset,
readSize, cache);
CacheRead(gCurrentIH, bufferPos, gAllocationOffset + readOffset, readSize, cache);
sizeRead += readSize;
offset += readSize;
bufferPos += readSize;
}
if (extentBuffer) free(extentBuffer);
if (extentBuffer)
{
free(extentBuffer);
}
return sizeRead;
}
//==============================================================================
static long GetExtentStart(void * extents, long index)
{
long start;
HFSExtentDescriptor *hfsExtents = extents;
HFSPlusExtentDescriptor *hfsPlusExtents = extents;
long start;
if (gIsHFSPlus) start = SWAP_BE32(hfsPlusExtents[index].startBlock);
else start = SWAP_BE16(hfsExtents[index].startBlock);
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;
long size;
HFSExtentDescriptor *hfsExtents = extents;
HFSPlusExtentDescriptor *hfsPlusExtents = extents;
if (gIsHFSPlus) size = SWAP_BE32(hfsPlusExtents[index].blockCount);
else size = SWAP_BE16(hfsExtents[index].blockCount);
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;
long result, searchParentID, trialParentID;
searchKey = key;
trialKey = testKey;
trialParentID = SWAP_BE32(trialKey->parentID);
// parent dirID is unsigned
if (searchParentID > trialParentID) result = 1;
else if (searchParentID < trialParentID) result = -1;
if (searchParentID > trialParentID)
{
result = 1;
}
else if (searchParentID < trialParentID)
{
result = -1;
}
else
{
// parent dirID's are equal, compare names
return result;
}
//==============================================================================
static long CompareHFSPlusCatalogKeys(void * key, void * testKey)
{
HFSPlusCatalogKey *searchKey, *trialKey;
long result, searchParentID, trialParentID;
long result, searchParentID, trialParentID;
searchKey = key;
trialKey = testKey;
trialParentID = SWAP_BE32(trialKey->parentID);
// parent dirID is unsigned
if (searchParentID > trialParentID) result = 1;
else if (searchParentID < trialParentID) result = -1;
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 = searchKey->nodeName.length - trialKey->nodeName.length;
}
else if (gCaseSensitive)
{
result = BinaryUnicodeCompare(&searchKey->nodeName.unicode[0],
SWAP_BE16(searchKey->nodeName.length),
&trialKey->nodeName.unicode[0],
return result;
}
//==============================================================================
static long CompareHFSExtentsKeys(void * key, void * testKey)
{
HFSExtentKey *searchKey, *trialKey;
long result;
HFSExtentKey *searchKey, *trialKey;
long result;
searchKey = key;
trialKey = testKey;
searchKey = key;
trialKey = testKey;
// assume searchKey < trialKey
result = -1;
// 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;
}
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;
return result;
}
//==============================================================================
static long CompareHFSPlusExtentsKeys(void * key, void * testKey)
{
HFSPlusExtentKey *searchKey, *trialKey;
long result;
HFSPlusExtentKey *searchKey, *trialKey;
searchKey = key;
trialKey = testKey;
long result = -1; // assume searchKey < trialKey
// assume searchKey < trialKey
result = -1;
searchKey = key;
trialKey = testKey;
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;
}
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;
return result;
}
branches/ErmaC/Trunk/i386/libsaio/device_tree.h
11
2
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
323
424
525
......
828
929
1030
11
12
13
14
1531
16
32
33
34
35
36
37
38
39
1740
1841
19
20
21
22
23
2442
25
43
44
45
46
47
48
49
50
2651
2752
28
29
3053
31
32
54
3355
34
35
56
3657
37
38
58
3959
40
41
60
4261
43
44
62
4563
46
47
64
4865
49
50
51
52
53
54
66
5567
56
57
68
69
5870
71
72
5973
/*
* Copyright (c) 2005 Apple Computer, Inc. All Rights Reserved.
* Copyright (c) 2005 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 __DEVICE_TREE_H
#include <stdbool.h>
#include <stdint.h>
typedef struct _Property {
const char * name;
uint32_t length;
void * value;
struct _Property * next;
//==============================================================================
typedef struct _Property
{
const char *name;
uint32_tlength;
void *value;
struct _Property *next;
} Property;
typedef struct _Node {
struct _Property * properties;
struct _Property * last_prop;
struct _Node * children;
struct _Node * next;
//==============================================================================
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);
extern Property * DT__AddProperty(Node *node, const char *name, uint32_t length, void *value);
Node *
DT__FindNode(const char *path, bool createIfMissing);
extern Node * DT__AddChild(Node *parent, const char *name);
extern void
DT__FreeProperty(Property *prop);
Node * DT__FindNode(const char *path, bool createIfMissing);
extern void
DT__FreeNode(Node *node);
extern void DT__FreeProperty(Property *prop);
extern char *
DT__GetName(Node *node);
extern void DT__FreeNode(Node *node);
void
DT__Initialize(void);
extern char * DT__GetName(Node *node);
/*
* Free up memory used by in-memory representation
* of device tree.
*/
extern void
DT__Finalize(void);
void DT__Initialize(void);
void
DT__FlattenDeviceTree(void **result, uint32_t *length);
// 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 */
branches/ErmaC/Trunk/i386/libsaio/allocate.c
3333
3434
3535
36
37
36
37
38
3839
39
40
40
41
4142
42
43
44
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
4563
46
47
48
49
50
51
52
53
54
64
5565
5666
57
58
67
68
69
70
5971
60
72
6173
62
74
6375
64
65
66
67
68
76
77
78
79
6980
70
81
7182
72
73
83
84
7485
75
86
7687
77
88
7889
#define RoundPage(x) ((((unsigned)(x)) + kPageSize - 1) & ~(kPageSize - 1))
long
AllocateMemoryRange(char * rangeName, long start, long length, long type)
//==============================================================================
long AllocateMemoryRange(char * rangeName, long start, long length, long type)
{
char *nameBuf;
uint32_t *buffer;
char *nameBuf;
uint32_t *buffer;
nameBuf = malloc(strlen(rangeName) + 1);
if (nameBuf == 0) return -1;
strcpy(nameBuf, rangeName);
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);
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;
return 0;
}
long
AllocateKernelMemory( long inSize )
//==============================================================================
long AllocateKernelMemory(long inSize)
{
long addr;
long addr;
if (gImageLastKernelAddr == 0)
if (gImageLastKernelAddr == 0)
{
gImageLastKernelAddr = RoundPage( bootArgs->kaddr +
bootArgs->ksize );
}
addr = gImageLastKernelAddr;
gImageLastKernelAddr += RoundPage(inSize);
gImageLastKernelAddr = RoundPage(bootArgs->kaddr + bootArgs->ksize);
}
addr = gImageLastKernelAddr;
gImageLastKernelAddr += RoundPage(inSize);
if ( gImageLastKernelAddr >= (KERNEL_ADDR + KERNEL_LEN) )
if ( gImageLastKernelAddr >= (KERNEL_ADDR + KERNEL_LEN) )
{
stop ("AllocateKernelMemory error");
}
stop ("AllocateKernelMemory error");
}
bootArgs->ksize = gImageLastKernelAddr - bootArgs->kaddr;
bootArgs->ksize = gImageLastKernelAddr - bootArgs->kaddr;
return addr;
return addr;
}
branches/ErmaC/Trunk/i386/libsaio/hfs.h
2323
2424
2525
26
27
28
26
2927
3028
3129
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 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);
branches/ErmaC/Trunk/i386/libsaio/hfs_compare.c
3232
3333
3434
35
36
35
3736
3837
3938
......
5857
5958
6059
61
62
60
6361
6462
6563
......
306304
307305
308306
309
310
307
311308
312309
313310
#if ! UNCOMPRESSED
static unsigned short *
UncompressStructure(struct compressed_block *bp, int count, int size)
static unsigned short * UncompressStructure(struct compressed_block *bp, int count, int size)
{
unsigned short *out = malloc(size);
unsigned short *op = out;
return out;
}
static void
InitCompareTables(void)
static void InitCompareTables(void)
{
if (gCompareTable == 0) {
gCompareTable = UncompressStructure(gCompareTableCompressed,
* 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,
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;
branches/ErmaC/Trunk/i386/libsaio/spd.c
6969
7070
7171
72
73
74
75
76
77
78
79
80
81
82
83
84
7285
7386
7487
......
107120
108121
109122
110
111
112
113
114
115
116
117
118
119
120
121
122123
123124
124125
......
134135
135136
136137
137
138
139
140
138
139
140
141
141142
142
143
144
145
146
147
148
149
150
151
152
153
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
154159
155160
156
157
158
159
160
161
162
163
164
161
162
163
164
165
166
167
168
169
170
171
165172
166173
167174
......
171178
172179
173180
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
201212
202213
203214
......
208219
209220
210221
211
212
213
214
215
216
217
218
222
223
224
225
226
227
228
229
219230
220231
221232
......
226237
227238
228239
229
240
241
230242
231243
232
244
245
233246
234247
235248
......
291304
292305
293306
294
307
295308
296309
297310
......
388401
389402
390403
391
404
405
392406
393407
394408
395409
396410
397411
398
399
400
412
401413
402
403
414
415
416
417
404418
405419
406420
407421
408422
409
423
410424
411425
412426
#define SMBHSTDAT 5
#define SBMBLKDAT 7
int spd_indexes[] = {
SPD_MEMORY_TYPE,
SPD_DDR3_MEMORY_BANK,
SPD_DDR3_MEMORY_CODE,
SPD_NUM_ROWS,
SPD_NUM_COLUMNS,
SPD_NUM_DIMM_BANKS,
SPD_NUM_BANKS_PER_SDRAM,
4,7,8,9,12,64, /* TODO: give names to these values */
95,96,97,98, 122,123,124,125 /* UIS */
};
#define SPD_INDEXES_SIZE (sizeof(spd_indexes) / sizeof(int))
/** Read one byte from the intel i2c, used for reading SPD on intel chipsets only. */
unsigned char smb_read_byte_intel(uint32_t base, uint8_t adr, uint8_t cmd)
/* SPD i2c read optimization: prefetch only what we need, read non prefetcheable bytes on the fly */
#define READ_SPD(spd, base, slot, x) spd[x] = smb_read_byte_intel(base, 0x50 + slot, x)
int spd_indexes[] = {
SPD_MEMORY_TYPE,
SPD_DDR3_MEMORY_BANK,
SPD_DDR3_MEMORY_CODE,
SPD_NUM_ROWS,
SPD_NUM_COLUMNS,
SPD_NUM_DIMM_BANKS,
SPD_NUM_BANKS_PER_SDRAM,
4,7,8,9,12,64, /* TODO: give names to these values */
95,96,97,98, 122,123,124,125 /* UIS */
};
#define SPD_INDEXES_SIZE (sizeof(spd_indexes) / sizeof(int))
/** Read from spd *used* values only*/
static void init_spd(char * spd, uint32_t base, int slot)
have different formats, always return a valid ptr.*/
const char * getVendorName(RamSlotInfo_t* slot, uint32_t base, int slot_num)
{
uint8_t bank = 0;
uint8_t code = 0;
int i = 0;
uint8_t * spd = (uint8_t *) slot->spd;
uint8_t bank = 0;
uint8_t code = 0;
int i = 0;
uint8_t * spd = (uint8_t *) slot->spd;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) { // DDR3
bank = (spd[SPD_DDR3_MEMORY_BANK] & 0x07f); // constructors like Patriot use b7=1
code = spd[SPD_DDR3_MEMORY_CODE];
for (i=0; i < VEN_MAP_SIZE; i++)
if (bank==vendorMap[i].bank && code==vendorMap[i].code)
return vendorMap[i].name;
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) {
if(spd[64]==0x7f) {
for (i=64; i<72 && spd[i]==0x7f;i++) {
bank++;
READ_SPD(spd, base, slot_num,i+1); // prefetch next spd byte to read for next loop
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3)
{ // DDR3
bank = (spd[SPD_DDR3_MEMORY_BANK] & 0x07f); // constructors like Patriot use b7=1
code = spd[SPD_DDR3_MEMORY_CODE];
for (i=0; i < VEN_MAP_SIZE; i++)
if (bank==vendorMap[i].bank && code==vendorMap[i].code)
return vendorMap[i].name;
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2 || spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR)
{
if(spd[64]==0x7f)
{
for (i=64; i<72 && spd[i]==0x7f;i++)
{
bank++;
READ_SPD(spd, base, slot_num,i+1); // prefetch next spd byte to read for next loop
}
READ_SPD(spd, base, slot_num,i);
code = spd[i];
} else {
code = spd[64];
bank = 0;
}
for (i=0; i < VEN_MAP_SIZE; i++)
if (bank==vendorMap[i].bank && code==vendorMap[i].code)
return vendorMap[i].name;
}
code = spd[i];
}
else
{
code = spd[64];
bank = 0;
}
for (i=0; i < VEN_MAP_SIZE; i++)
if (bank==vendorMap[i].bank && code==vendorMap[i].code)
return vendorMap[i].name;
}
/* OK there is no vendor id here lets try to match the partnum if it exists */
if (strstr(slot->PartNo,"GU332") == slot->PartNo) // Unifosa fingerprint
return "Unifosa";
/** Get Default Memory Module Speed (no overclocking handled) */
int getDDRspeedMhz(const char * spd)
{
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) {
switch(spd[12]) {
case 0x0f:
return 1066;
case 0x0c:
return 1333;
case 0x0a:
return 1600;
case 0x14:
default:
return 800;
}
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) {
switch(spd[9]) {
case 0x50:
return 400;
case 0x3d:
return 533;
case 0x30:
return 667;
case 0x25:
default:
return 800;
}
}
return 800; // default freq for unknown types
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3)
{
switch(spd[12])
{
case 0x0f:
return 1066;
case 0x0c:
return 1333;
case 0x0a:
return 1600;
case 0x14:
default:
return 800;
}
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2 || spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR)
{
switch(spd[9])
{
case 0x50:
return 400;
case 0x3d:
return 533;
case 0x30:
return 667;
case 0x25:
default:
return 800;
}
}
return 800; // default freq for unknown types
}
#define SMST(a) ((uint8_t)((spd[a] & 0xf0) >> 4))
{
static char asciiSerial[16];
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) // DDR3
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(122) /*& 0x7*/, SLST(122), SMST(123), SLST(123), SMST(124), SLST(124), SMST(125), SLST(125));
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) // DDR2 or DDR
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(95) /*& 0x7*/, SLST(95), SMST(96), SLST(96), SMST(97), SLST(97), SMST(98), SLST(98));
}
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) // DDR3
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(122) /*& 0x7*/, SLST(122), SMST(123), SLST(123), SMST(124), SLST(124), SMST(125), SLST(125));
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2 || spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR) // DDR2 or DDR
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(95) /*& 0x7*/, SLST(95), SMST(96), SLST(96), SMST(97), SLST(97), SMST(98), SLST(98));
}
return strdup(asciiSerial);
}
static char asciiPartNo[32];
int i, start=0, index = 0;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) {
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3)
{
start = 128;
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) {
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2 || spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR)
{
start = 73;
}
bzero(slot->spd, spd_size);
// Copy spd data into buffer
// Copy spd data into buffer
//for (x = 0; x < spd_size; x++) slot->spd[x] = smb_read_byte_intel(base, 0x50 + i, x);
init_spd(slot->spd, base, i);
pci_dt_t*current = pci_dt;
int i;
while (current) {
while (current)
{
#if 0
printf("%02x:%02x.%x [%04x] [%04x:%04x] :: %s\n",
current->dev.bits.bus, current->dev.bits.dev, current->dev.bits.func,
current->class_id, current->vendor_id, current->device_id,
get_pci_dev_path(current));
#endif
for ( i = 0; i < sizeof(smbus_controllers) / sizeof(smbus_controllers[0]); i++ )
{
if (current->vendor_id == smbus_controllers[i].vendor && current->device_id == smbus_controllers[i].device)
for ( i = 0; i < sizeof(smbus_controllers) / sizeof(smbus_controllers[0]); i++ )
{
smbus_controllers[i].read_smb(current); // read smb
return true;
if (current->vendor_id == smbus_controllers[i].vendor && current->device_id == smbus_controllers[i].device)
{
smbus_controllers[i].read_smb(current); // read smb
return true;
}
}
find_and_read_smbus_controller(current->children);
current = current->next;
}
return false; // not found
return false; // not found
}
void scan_spd(PlatformInfo_t *p)
branches/ErmaC/Trunk/i386/libsaio/spd.h
1212
1313
1414
15
15
16
1617
1718
1819
19
20
2021
2122
2223
void scan_spd(PlatformInfo_t *p);
struct smbus_controllers_t {
struct smbus_controllers_t
{
uint32_tvendor;
uint32_tdevice;
char*name;
void (*read_smb)(pci_dt_t *smbus_dev);
void (*read_smb)(pci_dt_t *smbus_dev);
};
branches/ErmaC/Trunk/i386/libsaio/bios.h
3131
3232
3333
34
35
36
37
38
39
40
34
35
36
37
38
39
40
41
42
43
4144
4245
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
5863
5964
60
61
62
63
64
65
66
67
68
69
70
71
72
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
7380
7481
75
76
77
82
83
84
7885
79
86
8087
8188
8289
8390
8491
85
86
87
88
89
92
93
94
95
96
97
9098
91
99
92100
93101
94102
95103
96104
97105
98
99
100
101
102
106
107
108
109
110
111
103112
104113
105114
#include "bootargs.h"
typedef union {
unsigned int rx;
unsigned short rr;
struct {
unsigned char l;
unsigned char h;
} r;
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;
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;
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 EBIOS_FIXED_DISK_ACCESS0x01
#define EBIOS_LOCKING_ACCESS0x02
#define EBIOS_ENHANCED_DRIVE_INFO0x04
#define BASE_HD_DRIVE 0x80
#define BASE_HD_DRIVE0x80
#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)
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 */
/* 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;
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 */
branches/ErmaC/Trunk/i386/libsaio/gma.c
191191
192192
193193
194
194
195195
196196
197197
......
308308
309309
310310
311
311
312312
313313
314314
pause();
return false;
}
devprop_add_value(device, "model", (uint8_t*)model, (strlen(model) + 1));
devprop_add_value(device, "device_type", (uint8_t*)"display", 8);
devprop_add_value(device, "AAPL,tbl-info",HD3000_tbl_info, 18);
devprop_add_value(device, "AAPL,os-info",HD3000_os_info, 20);
}
stringdata = malloc(sizeof(uint8_t) * string->length);
if (!stringdata)
{
branches/ErmaC/Trunk/i386/libsaio/memvendors.h
77
88
99
10
11
12
13
10
11
12
13
14
1415
1516
1617
#ifndef __MEMVEN_H
#define __MEMVEN_H
typedef struct _vidTag {
uint8_t bank;
uint8_t code;
const char* name;
typedef struct _vidTag
{
uint8_tbank;
uint8_tcode;
const char*name;
} VenIdName;
VenIdName vendorMap[] = {
branches/ErmaC/Trunk/i386/libsaio/device_inject.c
206206
207207
208208
209
209
210210
211211
212212
213213
214
214
215215
216216
217217
......
219219
220220
221221
222
222
223223
224224
225225
226226
227
227
228228
229229
230230
......
241241
242242
243243
244
244
245245
246246
247247
......
272272
273273
274274
275
275
276276
277277
278
278
279279
280280
281281
......
307307
308308
309309
310
310
311311
312312
313313
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);
{
{
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] = *vl++;
}
}
}
uint32_t offset = device->length - (24 + (6 * device->num_pci_devpaths));
{
free(device->data);
}
free(data);
device->data = newdata;
return 1;
}
dp_swap32(string->entries[i]->acpi_dev_path._UID));
buffer += 24;
for(x=0;x < string->entries[i]->num_pci_devpaths; x++)
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,
branches/ErmaC/Trunk/i386/libsaio/device_inject.h
1818
1919
2020
21
21
22
2223
2324
2425
......
2627
2728
2829
29
30
31
3032
3133
3234
......
3436
3537
3638
37
39
40
3841
3942
4043
4144
4245
43
46
47
4448
4549
4650
......
5559
5660
5761
58
62
63
5964
6065
6166
extern void setupDeviceProperties(Node *node);
struct ACPIDevPath {
struct ACPIDevPath
{
uint8_ttype;// = 2 ACPI device-path
uint8_tsubtype;// = 1 ACPI Device-path
uint16_tlength;// = 0x0c
uint32_t_UID;// = 0x00000000 PCI ROOT
};
struct PCIDevPath {
struct PCIDevPath
{
uint8_ttype;// = 1 Hardware device-path
uint8_tsubtype;// = 1 PCI
uint16_tlength;// = 6
uint8_tdevice;// pci dev number
};
struct DevicePathEnd {
struct DevicePathEnd
{
uint8_ttype;// = 0x7f
uint8_tsubtype;// = 0xff
uint16_tlength;// = 4;
};
struct DevPropDevice {
struct DevPropDevice
{
uint32_t length;
uint16_t numentries;
uint16_t WHAT2;// 0x0000 ?
// ------------------------
};
struct DevPropString {
struct DevPropString
{
uint32_t length;
uint32_t WHAT2;// 0x01000000 ?
uint16_t numentries;
branches/ErmaC/Trunk/i386/libsaio/fdisk.h
3535
3636
3737
38
39
40
38
39
40
4141
42
42
4343
4444
4545
......
4949
5050
5151
52
53
52
53
5454
5555
5656
#ifndef __LIBSAIO_FDISK_H
#define __LIBSAIO_FDISK_H
#define DISK_BLK00/* blkno of boot block */
#define DISK_BLK0SZ512/* size of boot block */
#define DISK_BOOTSZ446/* size of boot code in boot block */
#define DISK_BLK00 /* blkno of boot block */
#define DISK_BLK0SZ512 /* size of boot block */
#define DISK_BOOTSZ446 /* size of boot code in boot block */
#define DISK_SIGNATURE0xAA55/* signature of the boot record */
#define FDISK_NPART4/* number of entries in fdisk table */
#define FDISK_NPART4 /* number of entries in fdisk table */
#define FDISK_ACTIVE0x80/* indicator of active partition */
#define FDISK_NEXTNAME0xA7/* indicator of NeXT partition */
#define FDISK_DOS120x01/* 12-bit fat < 10MB dos partition */
#define FDISK_NTFS0x07/* NTFS partition */
#define FDISK_SMALLFAT320x0b/* FAT32 partition */
#define FDISK_FAT320x0c/* FAT32 partition */
#define FDISK_DOS16SLBA0x0e
#define FDISK_LINUX0x83
#define FDISK_DOS16SLBA0x0e /* 16-bit FAT, LBA-mapped */
#define FDISK_LINUX0x83 /* Linux native */
#define FDISK_OPENBSD0xa6 /* OpenBSD FFS partition */
#define FDISK_FREEBSD0xa5 /* FreeBSD UFS2 partition */
#define FDISK_BEFS0xeb /* Haiku BeFS partition */
branches/ErmaC/Trunk/i386/libsaio/sys.c
8181
8282
8383
84
85
86
87
88
84
85
86
87
88
89
8990
9091
9192
......
99100
100101
101102
102
103
104
103105
104106
105107
......
120122
121123
122124
123
125
126
124127
125128
126129
......
128131
129132
130133
131
134
132135
133136
134137
......
142145
143146
144147
145
148
149
146150
147151
148152
149153
150154
151155
152
153
156
157
154158
155
159
156160
157
158
161
162
163
164
159165
160
166
161167
162168
169
170
171
163172
164173
165
166
174
175
167176
168
169
177
178
179
180
170181
171
172
182
183
184
185
173186
174
187
175188
176189
190
191
192
177193
178194
179
180
181
182
195
196
197
198
183199
184
200
185201
186
187
202
203
204
205
206
207
208
209
210
188211
189
212
190213
191
192
214
215
216
217
218
219
193220
194
195
196
197
198
199
200
201
202
221
222
223
224
203225
204226
227
205228
206
207
229
208230
209
231
232
233
210234
211235
212
236
237
238
239
213240
214241
215242
216
243
244
245
217246
218
247
248
219249
220
221250
222
251
223252
224253
225254
255
256
257
226258
227259
228260
......
241273
242274
243275
276
244277
245278
246279
......
264297
265298
266299
267
268
269
270
271
300
301
272302
273
274
275
276
303
304
305
306
307
308
309
277310
278
279
280
281
311
312
313
314
282315
283
284
285
286
287
288
289
316
290317
291
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
292342
293343
294344
295
345
296346
297347
298348
299
300
349
301350
302
303
351
352
304353
305
354
306355
307356
308
357
358
359
309360
310
361
311362
312363
313364
......
315366
316367
317368
318
369
370
319371
320372
321373
322374
323375
324
325
376
326377
327
328
378
379
329380
330
331
381
382
383
384
332385
333
334
386
387
388
335389
336
390
337391
338392
339
340
341
342
343
344
345
346
347
348
349
350
351
393
394
395
396
397
398
399
400
401
402
403
404
405
406
352407
353
354
355
356
357
358
408
409
410
411
412
413
414
415
416
417
418
419
359420
360421
422
423
424
361425
362426
363
364
427
428
365429
366
430
367431
368
369
370
432
433
434
435
371436
372437
373438
374439
375440
376
441
442
377443
378444
379445
......
381447
382448
383449
384
385
450
451
452
453
386454
387455
388456
......
391459
392460
393461
394
462
395463
396464
397465
......
399467
400468
401469
402
470
403471
404
405
472
473
406474
407
408
475
476
477
409478
410479
411
480
481
412482
413483
414484
......
430500
431501
432502
433
503
504
434505
435506
436507
......
439510
440511
441512
442
513
514
443515
444516
445517
......
450522
451523
452524
525
453526
527
454528
455
456
529
530
531
532
533
457534
458535
536
459537
460538
461539
462540
541
463542
464543
465
544
545
546
466547
467548
468549
550
469551
470552
471553
......
475557
476558
477559
478
560
561
479562
480563
481564
......
491574
492575
493576
494
577
578
495579
496580
497581
498
582
583
499584
500585
501586
502
503
587
588
589
590
504591
505592
506593
507594
508595
509596
510
597
598
511599
512600
513601
514
602
603
515604
516
605
606
517607
518608
519609
......
526616
527617
528618
529
619
620
530621
531622
532623
533624
534
625
535626
536
537
627
628
629
630
538631
539
632
540633
541
634
542635
543636
544
637
638
545639
546640
547641
548642
549643
550
644
551645
552
553
646
647
648
649
554650
555
651
556652
557
653
558654
559655
560
656
657
561658
562659
563660
564661
565
662
566663
567
568
664
665
666
667
569668
570
669
571670
572671
573
672
673
574674
575675
576676
577677
578678
579
679
580680
581
582
681
682
683
684
583685
584
585
686
687
688
689
586690
587
588
691
692
693
694
589695
590
696
591697
592
698
593699
594
700
595701
596702
597
703
704
598705
599706
600707
......
650757
651758
652759
653
760
761
654762
655763
656764
657765
658766
659
767
660768
661
662
769
770
771
772
663773
664
774
665775
666776
667
668777
778
779
669780
670781
671
782
672783
673
674
675
784
676785
677
678
679
786
787
680788
681
789
790
791
682792
683
793
684794
795
796
685797
686
687
798
799
800
688801
689802
690
691803
804
805
692806
693807
694
695
696
808
809
810
697811
698812
699813
......
715829
716830
717831
718
719832
833
834
720835
721836
722
723
724
725
837
838
839
840
841
842
843
844
845
846
726847
727848
728849
729
730850
731
732
851
852
853
733854
734
735
736
737
738
855
856
857
858
739859
740860
741
742861
743
744
862
863
864
745865
746
747
748
749
750
751
866
867
868
869
870
752871
753872
754
755873
874
875
756876
757877
758
759
760
878
879
880
761881
762882
763
764883
884
885
765886
766887
767
888
768889
769890
770891
......
783904
784905
785906
786
787907
908
909
910
911
788912
789913
790914
......
807931
808932
809933
810
811934
935
936
812937
813938
814939
......
8841009
8851010
8861011
887
8881012
1013
1014
8891015
8901016
8911017
......
8991025
9001026
9011027
902
903
904
905
906
1028
1029
1030
1031
1032
9071033
9081034
9091035
9101036
911
912
1037
1038
9131039
914
915
1040
1041
9161042
917
1043
9181044
9191045
9201046
......
9251051
9261052
9271053
928
1054
9291055
9301056
9311057
932
1058
9331059
9341060
9351061
936
937
938
1062
1063
1064
1065
1066
1067
1068
9391069
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
9551084
956
1085
1086
1087
9571088
958
1089
9591090
960
961
962
963
964
965
966
967
968
969
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
9701106
971
972
1107
1108
9731109
974
975
976
977
978
979
1110
9801111
1112
1113
1114
1115
1116
1117
9811118
9821119
9831120
9841121
9851122
986
987
1123
1124
1125
1126
9881127
989
1128
9901129
991
992
1130
1131
1132
1133
9931134
994
995
996
1135
1136
1137
9971138
998
1139
9991140
1000
1001
1141
1142
1143
1144
1145
1146
10021147
1003
1004
1148
10051149
1006
1007
1008
1009
1010
1011
1150
10121151
1013
1014
1015
1016
1017
1152
1153
1154
1155
1156
1157
1158
1159
10181160
1019
1020
1161
1162
1163
1164
1165
1166
1167
10211168
1022
1169
1170
1171
10231172
1024
1173
1174
1175
1176
1177
1178
10251179
10261180
10271181
extern int multiboot_skip_partition;
extern int multiboot_skip_partition_set;
struct devsw {
const char * name;
// size increased from char to short to handle non-BIOS internal devices
unsigned short biosdev;
int type;
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.
};
// Pseudo BIOS devices
enum {
enum
{
kPseudoBIOSDevRAMDisk = 0x100,
kPseudoBIOSDevBooter = 0x101
};
//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.
long LoadVolumeFile(BVRef bvr, const char *filePath)
{
long fileSize;
long fileSize;
// Read file into load buffer. The data in the load buffer will be
// overwritten by the next LoadFile() call.
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;
const char * filePath;
BVRef bvr;
// Resolve the boot volume from the file spec.
// Resolve the boot volume from the file spec.
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL)
return -1;
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL)
{
return -1;
}
return LoadVolumeFile(bvr, filePath);
return LoadVolumeFile(bvr, filePath);
}
//==============================================================================
long ReadFileAtOffset(const char * fileSpec, void *buffer, uint64_t offset, uint64_t length)
{
const char *filePath;
BVRef bvr;
const char *filePath;
BVRef bvr;
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL)
return -1;
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL)
{
return -1;
}
if (bvr->fs_readfile == NULL)
return -1;
if (bvr->fs_readfile == NULL)
{
return -1;
}
return bvr->fs_readfile(bvr, (char *)filePath, buffer, offset, length);
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;
const char* filePath;
FSReadFilereadFile;
BVRefbvr;
unsigned long length, length2;
// Resolve the boot volume from the file spec.
// Resolve the boot volume from the file spec.
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL)
return -1;
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.
*binary = (void *)kLoadAddr;
gFSLoadAddress = (void *) LOAD_ADDR;
// Read file into load buffer. The data in the load buffer will be
// overwritten by the next LoadFile() call.
readFile = bvr->fs_readfile;
if (readFile != NULL)
{
// Read the first 4096 bytes (fat header)
length = readFile(bvr, (char *)filePath, *binary, 0, 0x1000);
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)
{
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);
length = readFile(bvr, (char *)filePath, (void *)kLoadAddr, (unsigned long)(*binary) - kLoadAddr, length);
*binary = (void *)kLoadAddr;
} else {
}
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;
if (length2 == -1)
return -1;
length += length2;
}
}
} else {
}
else
{
length = bvr->fs_loadfile(bvr, (char *)filePath);
if (length > 0) {
if (length > 0)
ThinFatFile(binary, &length);
}
}
return length;
}
//==============================================================================
#if UNUSED
long GetFSUUID(char *spec, char *uuidStr)
{
#endif
// filesystem-specific getUUID functions call this shared string generator
long CreateUUIDString(uint8_t uubytes[], int nbytes, char *uuidStr)
{
unsigned fmtbase, fmtidx, i;
// 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;
i = 0;
fmtbase = 0;
nib = byte >> 4;
*p = nib + '0'; // 0x4 -> '4'
if(*p > '9') *p = (nib - 9 + ('A'-1)); // 0xB -> 'B'
p++;
for(fmtidx = 0; fmtidx < sizeof(uuidfmt); fmtidx++)
{
for (i = 0; i < uuidfmt[fmtidx]; i++)
{
uint8_t byte = mdresult[fmtbase + i];
char nib = byte >> 4;
*p = nib + '0'; // 0x4 -> '4'
nib = byte & 0xf;
*p = nib + '0'; // 0x4 -> '4'
if(*p > '9') *p = (nib - 9 + ('A'-1)); // 0xB -> 'B'
p++;
if (*p > '9')
{
*p = (nib - 9 + ('A'-1)); // 0xB -> 'B'
}
}
fmtbase += i;
if(fmtidx < sizeof(uuidfmt)-1)
*(p++) = '-';
else
*p = '\0';
}
p++;
return 0;
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)
long GetDirEntry(const char * dirSpec, long long * dirIndex, const char ** name, long * flags, long * time)
{
const char * dirPath;
BVRef bvr;
const char * dirPath;
BVRef bvr;
// Resolve the boot volume from the dir spec.
// Resolve the boot volume from the dir spec.
if ((bvr = getBootVolumeRef(dirSpec, &dirPath)) == NULL)
return -1;
{
return -1;
}
// Return 0 on success, or -1 if there are no additional entries.
// Returns 0 on success or -1 when there are no additional entries.
return bvr->fs_getdirentry( bvr,
/* dirPath */ (char *)dirPath,
/* 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 GetFileInfo(const char * dirSpec, const char * name, long * flags, long * time)
{
long long index = 0;
const char * entryName;
long long index = 0;
const char * entryName;
if (gMakeDirSpec == 0)
gMakeDirSpec = (char *)malloc(1024);
if (gMakeDirSpec == 0)
{
gMakeDirSpec = (char *)malloc(1024);
}
if (!dirSpec) {
long idx, len;
if (!dirSpec)
{
long idx, len;
len = strlen(name);
len = strlen(name);
for (idx = len; idx && (name[idx] != '/' && name[idx] != '\\'); idx--) {}
if (idx == 0) {
if(name[idx] == '/' || name[idx] == '\\') ++name; // todo: ensure other functions handel \ properly
gMakeDirSpec[0] = '/';
gMakeDirSpec[1] = '\0';
gMakeDirSpec[idx] = '\0';
} else {
idx++;
strncpy(gMakeDirSpec, name, idx);
gMakeDirSpec[idx] = '\0'; // ISSUE: http://forge.voodooprojects.org/p/chameleon/issues/270/
name += idx;
}
dirSpec = gMakeDirSpec;
}
if (idx == 0)
{
if(name[idx] == '/' || name[idx] == '\\') ++name; // todo: ensure other functions handel \ properly
gMakeDirSpec[0] = '/';
gMakeDirSpec[1] = '\0';
gMakeDirSpec[idx] = '\0';
}
else
{
idx++;
strncpy(gMakeDirSpec, name, idx);
gMakeDirSpec[idx] = '\0'; // ISSUE: http://forge.voodooprojects.org/p/chameleon/issues/270/
name += idx;
}
while (GetDirEntry(dirSpec, &index, &entryName, flags, time) == 0)
{
if (strcmp(entryName, name) == 0)
return 0; // success
}
return -1; // file not found
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;
const char * filePath;
BVRef bvr;
// Resolve the boot volume from the file spec.
// Resolve the boot volume from the file spec.
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL) {
printf("Boot volume for '%s' is bogus\n", fileSpec);
return -1;
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL)
{
// printf("Boot volume for '%s' is bogus\n", fileSpec);
return -1;
}
return bvr->fs_getfileblock(bvr, (char *)filePath, firstBlock);
}
//==========================================================================
//==============================================================================
// GetFreeFD()
static int GetFreeFd(void)
intfd;
// Locate a free descriptor slot.
for (fd = 0; fd < NFILES; fd++) {
if (iob[fd].i_flgs == 0) {
for (fd = 0; fd < NFILES; fd++)
{
if (iob[fd].i_flgs == 0)
{
return fd;
}
}
return -1;
}
//==========================================================================
//==============================================================================
// iob_from_fdesc()
//
// Return a pointer to an allocated 'iob' based on the file descriptor
static struct iob * iob_from_fdesc(int fdesc)
{
register struct iob * io;
register struct iob * io;
if (fdesc < 0 || fdesc >= NFILES ||
((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0)
if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0)
{
return NULL;
else
return io;
}
return io;
}
//==========================================================================
//==============================================================================
// openmem()
int openmem(char * buf, int len)
return fdesc;
}
//==========================================================================
//==============================================================================
// open() - Open the file specified by 'path' for reading.
static int open_bvr(BVRef bvr, const char *filePath, int flags)
intfdesc;
inti;
if (bvr == NULL) {
if (bvr == NULL)
{
return -1;
}
// 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)) {
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) {
if (io->i_filesize < 0)
{
close(fdesc);
return -1;
}
return fdesc;
}
BVRefbvr;
// Resolve the boot volume from the file spec.
if ((bvr = getBootVolumeRef(path, &filepath)) != NULL) {
if ((bvr = getBootVolumeRef(path, &filepath)) != NULL)
{
return open_bvr(bvr, filepath, flags);
}
return -1;
intunit;
intpartition;
if ((i = open(path, flags)) >= 0) {
if ((i = open(path, flags)) >= 0)
{
return i;
}
if (bvd == NULL || (len = strlen(bvd)) < 2) {
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]) {
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)) {
while ((cp - path) < len && isdigit(*cp))
{
i = i * 10 + *cp++ - '0';
unit = i;
}
if (*cp++ == ',') {
if (*cp++ == ',')
{
i = 0;
while ((cp - path) < len && isdigit(*cp)) {
while ((cp - path) < len && isdigit(*cp))
{
i = i * 10 + *cp++ - '0';
partition = i;
}
return -1;
}
//==========================================================================
//==============================================================================
// close() - Close a file descriptor.
int close(int fdesc)
{
struct iob * io;
struct iob * io;
if ((io = iob_from_fdesc(fdesc)) == NULL)
return (-1);
if ((io = iob_from_fdesc(fdesc)) == NULL)
{
return (-1);
}
io->i_flgs = 0;
io->i_flgs = 0;
return 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;
struct iob * io;
if ((io = iob_from_fdesc(fdesc)) == NULL)
return (-1);
if ((io = iob_from_fdesc(fdesc)) == NULL)
{
return (-1);
}
io->i_offset = offset;
io->i_offset = offset;
return offset;
return offset;
}
//==========================================================================
//==============================================================================
// tell() - Returns the byte offset of the file descriptor.
int tell(int fdesc)
{
struct iob * io;
struct iob * io;
if ((io = iob_from_fdesc(fdesc)) == NULL)
return 0;
if ((io = iob_from_fdesc(fdesc)) == NULL)
{
return 0;
}
return io->i_offset;
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;
struct iob * io;
if ((io = iob_from_fdesc(fdesc)) == NULL)
return (-1);
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 ((io->i_offset + count) > (unsigned int)io->i_filesize)
{
count = io->i_filesize - io->i_offset;
}
if (count <= 0)
return 0; // end of file
if (count <= 0)
{
return 0; // end of file
}
bcopy(io->i_buf + io->i_offset, buf, count);
bcopy(io->i_buf + io->i_offset, buf, count);
io->i_offset += count;
io->i_offset += count;
return count;
return count;
}
//==========================================================================
//==============================================================================
// write() - Write up to 'count' bytes of data to the file descriptor
// from the buffer pointed to by buf.
return 4;
}
//==========================================================================
//==============================================================================
// file_size() - Returns the size of the file described by the file
// descriptor.
int file_size(int fdesc)
{
struct iob * io;
struct iob * io;
if ((io = iob_from_fdesc(fdesc)) == 0)
return 0;
if ((io = iob_from_fdesc(fdesc)) == 0)
{
return 0;
}
return io->i_filesize;
return io->i_filesize;
}
//==========================================================================
//==============================================================================
struct dirstuff * vol_opendir(BVRef bvr, const char * path)
{
struct dirstuff * dirp = 0;
struct dirstuff * dirp = 0;
dirp = (struct dirstuff *) malloc(sizeof(struct dirstuff));
if (dirp == NULL)
goto error;
dirp = (struct dirstuff *) malloc(sizeof(struct dirstuff));
dirp->dir_path = newString(path);
if (dirp->dir_path == NULL)
goto error;
if (dirp == NULL)
goto error;
dirp->dir_bvr = bvr;
dirp->dir_path = newString(path);
if (dirp->dir_path == NULL)
goto error;
return dirp;
dirp->dir_bvr = bvr;
return dirp;
error:
closedir(dirp);
return NULL;
closedir(dirp);
return NULL;
}
//==========================================================================
//==============================================================================
struct dirstuff * opendir(const char * path)
{
struct dirstuff * dirp = 0;
const char * dirPath;
BVRef bvr;
struct dirstuff * dirp = 0;
const char * dirPath;
BVRef bvr;
if ((bvr = getBootVolumeRef(path, &dirPath)) == NULL)
goto error;
return NULL;
}
//==========================================================================
//==============================================================================
int closedir(struct dirstuff * dirp)
{
if (dirp) {
if (dirp->dir_path) free(dirp->dir_path);
free(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)
//==============================================================================
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);
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)
//==============================================================================
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);
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";
if (gBootFileType == kNetworkDeviceType)
return "";
return "/Library/Preferences/SystemConfiguration";
}
//==========================================================================
//==============================================================================
int gBootFileType;
void scanBootVolumes( int biosdev, int * count )
void scanBootVolumes(int biosdev, int * count)
{
BVRef bvr = 0;
}
}
//==========================================================================
//==============================================================================
void scanDisks(int biosdev, int *count)
{
#define MAX_HDD_COUNT 32
}
}
//==========================================================================
//==============================================================================
BVRef selectBootVolume( BVRef chain )
{
bool filteredChain = false;
return bvr;
}
//==========================================================================
//==============================================================================
#define LP '('
#define RP ')'
int gBIOSDev;
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;
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);
// Record default boot device.
gBootVolume = selectBootVolume(chain);
// turbo - Save the ORIGINAL boot volume too for loading our mkext
if (!gBIOSBootVolume) gBIOSBootVolume = gBootVolume;
// turbo - Save the ORIGINAL boot volume too for loading our mkext
if (!gBIOSBootVolume) gBIOSBootVolume = gBootVolume;
setRootVolume(gBootVolume);
setRootVolume(gBootVolume);
}
/*!
is changed to the selected volume unless the volume selector is
that of a ramdisk.
*/
BVRef getBootVolumeRef( const char * path, const char ** outPath )
BVRef getBootVolumeRef(const char * path, const char ** outPath)
{
const char * cp;
BVRef bvr = gRootVolume;
int biosdev = gBIOSDev;
int biosdev = gBIOSDev;
// Search for left parenthesis in the path specification.
for (cp = path; *cp; cp++) {
if (*cp == LP || *cp == '/') break;
}
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;
if (*cp != LP) // no left paren found
{
cp = path;
// Path is using the implicit current device so if there is
// no current device, then we must fail.
if (gRootVolume == NULL)
{
return NULL;
}
}
else if ((cp - path) == 2) // found "xx("
{
const struct devsw * dp;
const char * xp = path;
cp++;
int i;
int unit = -1;
int part = -1;
// Check the 2 character device name pointed by 'xp'.
cp++;
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;
}
// 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).
// 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;
}
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;
if (unit == -1)
{
return NULL;
}
// Extract the optional partition number from the specification.
// Extract the optional partition number from the specification.
if (*cp == ',')
part = atoi(++cp);
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.
// 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.
// Skip past the right paren.
for ( ; *cp && *cp != RP; cp++) /* LOOP */;
if (*cp == RP) cp++;
for ( ; *cp && *cp != RP; cp++) /* LOOP */;
if (*cp == RP)
{
cp++;
}
biosdev = dp->biosdev + unit;
bvr = newBootVolumeRef(biosdev, part);
biosdev = dp->biosdev + unit;
if(bvr == NULL)
return NULL;
}
else
{
// Bad device specifier, skip past the right paren.
bvr = newBootVolumeRef(biosdev, part);
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.
}
if (bvr == NULL)
{
return NULL;
}
}
else
{
// Bad device specifier, skip past the right paren.
// Returns the file path following the device spec.
// e.g. 'hd(1,b)mach_kernel' is reduced to 'mach_kernel'.
for (cp++; *cp && *cp != RP; cp++) /* LOOP */;
{
if (*cp == RP)
{
cp++;
}
}
*outPath = cp;
// If gRootVolume was NULL, then bvr will be NULL as well which
// should be caught by the caller.
}
return bvr;
// Returns the file path following the device spec.
// e.g. 'hd(1,b)mach_kernel' is reduced to 'mach_kernel'.
*outPath = cp;
return bvr;
}
//==========================================================================
branches/ErmaC/Trunk/i386/libsaio/load.c
3232
3333
3434
35
36
37
38
39
40
41
42
43
3544
3645
3746
......
4150
4251
4352
44
4553
54
55
56
4657
4758
48
49
50
51
52
53
54
59
60
61
62
63
64
5565
5666
5767
......
6777
6878
6979
80
7081
7182
7283
......
8192
8293
8394
95
8496
8597
8698
......
89101
90102
91103
92
104
105
106
107
93108
94109
95110
96111
112
113
114
97115
98116
99
100
101
102
103
104
105
106
117
118
119
120
121
122
123
124
107125
108
126
127
109128
110
111
129
130
131
132
133
134
135
136
137
138
139
140
112141
113142
143
114144
115145
116146
117147
118148
149
119150
120151
152
121153
122
154
155
156
123157
158
159
124160
125161
126162
127163
128164
165
129166
130167
168
131169
170
132171
133172
134173
135174
136
175
176
137177
138
139
140
141
142
143
144
145
146
147
148
149
150
151178
152179
153180
......
157184
158185
159186
160
187
161188
189
162190
191
163192
164193
165194
166195
167196
168197
198
199
169200
170
201
171202
172203
173204
......
175206
176207
177208
178
209
179210
180211
181
212
213
214
215
182216
183
184
185
186
217
218
187219
188
189
190
220
221
222
191223
192
193
224
225
226
194227
195228
196229
197230
198
199
200
201
202
203
231
232
233
234
235
236
237
238
239
240
204241
205
242
206243
207244
208
209245
246
247
248
249
210250
211251
212
213
214
215
216
217
218
219
220
221
222
223
224
225
252
253
254
226255
227
256
257
258
259
260
261
262
263
264
228265
229266
230267
231268
232269
233270
234
235
236
237
238
271
272
273
274
275
239276
240
241
242
243
244
245
246
247
277
248278
279
280
281
282
283
284
249285
250
251
252
253
254
255
286
287
288
289
290
256291
257
258
259
260
261
262
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
263307
264
265
266
267
268
269
270
271
272
273
274308
275309
276
310
277311
278
279
280
312
313
314
281315
282
283
316
317
284318
285
319
286320
287321
322
323
324
288325
289326
290327
......
292329
293330
294331
295
296
297
298
332
333
299334
300335
301336
......
303338
304339
305340
306
307
308
309
341
310342
311343
312344
......
317349
318350
319351
352
353
354
320355
321356
322
323
324
325
357
358
359
326360
327
361
362
363
328364
329365
330
331
332
366
367
368
333369
334370
335
336
371
372
337373
338
339
340
341
374
375
376
377
342378
343
344
379
380
345381
346
347
348
349
382
383
384
385
350386
351
352
353
387
388
389
354390
#include <sl.h>
/*
* Backward compatibility fix for the SDK 10.7 version of loader.h
*/
#ifndef LC_MAIN
#define LC_MAIN (0x28|LC_REQ_DYLD) /* replacement for LC_UNIXTHREAD */
#endif
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);
bool gHaveKernelCache;/* XXX aserebln: uninitialized? and only set to true, never to false */
cpu_type_t archCpuType=CPU_TYPE_I386;
// Public Functions
//==============================================================================
// Public function.
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;
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)
{
{
return -1;
}
for (; nfat > 0; nfat--, fap++)
{
if (swapped)
fapoffset = fap->offset;
fapsize = fap->size;
}
if (fapcputype == archCpuType)
{
*binary = (void *) ((unsigned long)*binary + fapoffset);
}
}
if (length != 0) *length = size;
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;
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;
gBinaryAddress = (unsigned long)binary;
mH = (struct mach_header *)(gBinaryAddress);
mH = (struct mach_header *)(gBinaryAddress);
switch (archCpuType)
#if DEBUG
printf("magic: %x\n", (unsigned)mH->magic);
printf("cputype: %x\n", (unsigned)mH->cputype);
printf("cpusubtype: %x\n", (unsigned)mH->cpusubtype);
printf("filetype: %x\n", (unsigned)mH->filetype);
printf("ncmds: %x\n", (unsigned)mH->ncmds);
printf("sizeofcmds: %x\n", (unsigned)mH->sizeofcmds);
printf("flags: %x\n", (unsigned)mH->flags);
getchar();
#endif
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)
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;
cmdBase = cmdstart;
ncmds = mH->ncmds;
#if DEBUG
printf("magic: %x\n", (unsigned)mH->magic);
printf("cputype: %x\n", (unsigned)mH->cputype);
printf("cpusubtype: %x\n", (unsigned)mH->cpusubtype);
printf("filetype: %x\n", (unsigned)mH->filetype);
printf("ncmds: %x\n", (unsigned)mH->ncmds);
printf("sizeofcmds: %x\n", (unsigned)mH->sizeofcmds);
printf("flags: %x\n", (unsigned)mH->flags);
getchar();
#endif
ncmds = mH->ncmds;
for (cnt = 0; cnt < ncmds; cnt++)
{
cmd = ((long *)cmdBase)[0];
switch (cmd)
{
case LC_SEGMENT_64:
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_MAIN:/* Mountain Lion's replacement for LC_UNIXTHREAD */
case LC_UNIXTHREAD:
ret = DecodeUnixThread(cmdBase, &entry);
ret = DecodeUnixThread(cmdBase, &entry);
break;
case LC_SYMTAB:
default:
#if NOTDEF
printf("Ignoring cmd type %d.\n", (unsigned)cmd);
printf("Ignoring cmd type %d.\n", (unsigned)cmd);
#endif
break;
}
}
if (ret != 0) return -1;
if (ret != 0) return -1;
cmdBase += cmdsize;
}
cmdBase += cmdsize;
}
*rentry = (entry_t)( (unsigned long) entry & 0x3fffffff );
*rsize = vmend - vmaddr;
*raddr = (char *)vmaddr;
*rentry = (entry_t)( (unsigned long) entry & 0x3fffffff );
*rsize = vmend - vmaddr;
*raddr = (char *)vmaddr;
cmdBase = cmdstart;
for (cnt = 0; cnt < ncmds; cnt++)
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;
}
if (cmd == LC_SYMTAB)
{
if (DecodeSymbolTable(cmdBase) != 0)
{
return -1;
}
}
cmdBase += cmdsize;
}
return ret;
return ret;
}
// Private Functions
//==============================================================================
// Private function.
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;
char *segname;
long vmsize, filesize;
unsigned long vmaddr, fileaddr;
segname=segCmd->segname;
if (((long *)cmdBase)[0] == LC_SEGMENT_64)
{
struct segment_command_64 *segCmd;
segCmd = (struct segment_command_64 *)cmdBase;
vmaddr = (segCmd->vmaddr & 0x3fffffff);
vmsize = segCmd->vmsize;
fileaddr = (gBinaryAddress + segCmd->fileoff);
filesize = segCmd->filesize;
segname = segCmd->segname;
#ifdef DEBUG
printf("segname: %s, vmaddr: %x, vmsize: %x, fileoff: %x, filesize: %x, nsects: %d, flags: %x.\n",
segCmd->segname, (unsigned)vmaddr, (unsigned)vmsize, (unsigned)fileaddr, (unsigned)filesize,
(unsigned) segCmd->nsects, (unsigned)segCmd->flags);
getchar();
#endif
}
else
{
struct segment_command *segCmd;
#endif
}
else
{
struct segment_command *segCmd;
segCmd = (struct segment_command *)cmdBase;
vmaddr = (segCmd->vmaddr & 0x3fffffff);
vmsize = segCmd->vmsize;
fileaddr = (gBinaryAddress + segCmd->fileoff);
filesize = segCmd->filesize;
segname=segCmd->segname;
segCmd = (struct segment_command *)cmdBase;
vmaddr = (segCmd->vmaddr & 0x3fffffff);
vmsize = segCmd->vmsize;
fileaddr = (gBinaryAddress + segCmd->fileoff);
filesize = segCmd->filesize;
segname = segCmd->segname;
#ifdef DEBUG
printf("segname: %s, vmaddr: %x, vmsize: %x, fileoff: %x, filesize: %x, nsects: %d, flags: %x.\n",
segCmd->segname, (unsigned)vmaddr, (unsigned)vmsize, (unsigned)fileaddr, (unsigned)filesize,
(unsigned) segCmd->nsects, (unsigned)segCmd->flags);
getchar();
#endif
}
printf("segname: %s, vmaddr: %x, vmsize: %x, fileoff: %x, filesize: %x, nsects: %d, flags: %x.\n",
segCmd->segname, (unsigned)vmaddr, (unsigned)vmsize, (unsigned)fileaddr, (unsigned)filesize, (unsigned) segCmd->nsects, (unsigned)segCmd->flags);
getchar();
#endif
}
if (vmsize == 0 || filesize == 0)
{
*load_addr = ~0;
*load_size = 0;
return 0;
}
if (vmsize == 0 || filesize == 0)
{
*load_addr = ~0;
*load_size = 0;
return 0;
}
if (! ((vmaddr >= KERNEL_ADDR && (vmaddr + vmsize) <= (KERNEL_ADDR + KERNEL_LEN)) ||
(vmaddr >= HIB_ADDR && (vmaddr + vmsize) <= (HIB_ADDR + HIB_LEN))))
{
stop("Kernel overflows available space");
}
if (vmsize && ((strcmp(segname, "__PRELINK_INFO") == 0) || (strcmp(segname, "__PRELINK") == 0)))
gHaveKernelCache = true;
if (! ((vmaddr >= KERNEL_ADDR &&
(vmaddr + vmsize) <= (KERNEL_ADDR + KERNEL_LEN)) ||
(vmaddr >= HIB_ADDR &&
(vmaddr + vmsize) <= (HIB_ADDR + HIB_LEN)))) {
stop("Kernel overflows available space");
}
if (vmsize && ((strcmp(segname, "__PRELINK_INFO") == 0) || (strcmp(segname, "__PRELINK") == 0)))
gHaveKernelCache = true;
// Copy from file load area.
if (vmsize>0 && filesize>0)
bcopy((char *)fileaddr, (char *)vmaddr, vmsize>filesize?filesize:vmsize);
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);
// Zero space at the end of the segment.
if (vmsize > filesize)
bzero((char *)(vmaddr + filesize), vmsize - filesize);
*load_addr = vmaddr;
*load_size = vmsize;
*load_addr = vmaddr;
*load_size = vmsize;
return 0;
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);
i386ThreadState = (i386_thread_state_t *) (cmdBase + sizeof(struct thread_command) + 8);
*entry = i386ThreadState->eip;
return 0;
}
case CPU_TYPE_X86_64:
{
x86_thread_state64_t *x86_64ThreadState;
x86_64ThreadState = (x86_thread_state64_t *)
(cmdBase + sizeof(struct thread_command) + 8);
x86_64ThreadState = (x86_thread_state64_t *) (cmdBase + sizeof(struct thread_command) + 8);
*entry = x86_64ThreadState->rip;
return 0;
}
}
}
//==============================================================================
static long DecodeSymbolTable(long cmdBase)
{
struct symtab_command *symTab, *symTableSave;
long tmpAddr, symsSize, totalSize;
long gSymbolTableAddr;
long gSymbolTableSize;
long tmpAddr, symsSize, totalSize;
long gSymbolTableAddr;
long gSymbolTableSize;
symTab = (struct symtab_command *)cmdBase;
struct symtab_command *symTab, *symTableSave;
symTab = (struct symtab_command *)cmdBase;
#if DEBUG
printf("symoff: %x, nsyms: %x, stroff: %x, strsize: %x\n",
symTab->symoff, symTab->nsyms, symTab->stroff, symTab->strsize);
getchar();
printf("symoff: %x, nsyms: %x, stroff: %x, strsize: %x\n", symTab->symoff, symTab->nsyms, symTab->stroff, symTab->strsize);
getchar();
#endif
symsSize = symTab->stroff - symTab->symoff;
totalSize = symsSize + symTab->strsize;
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);
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 = (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;
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;
bcopy((char *)(gBinaryAddress + symTab->symoff), (char *)tmpAddr, totalSize);
return 0;
}
branches/ErmaC/Trunk/i386/libsaio/sl.h
3838
3939
4040
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
5859
5960
6061
#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
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);
branches/ErmaC/Trunk/i386/libsaio/cpu.c
378378
379379
380380
381
381
382
382383
383
384
385
384386
385387
386
387
388
389
388390
389391
390392
391393
392394
393395
394
396
397
395398
396399
397400
......
420423
421424
422425
423
426
427
424428
425429
426430
427
431
432
428433
429434
430435
431436
432437
433438
434
439
440
435441
436442
437443
......
439445
440446
441447
442
448
449
443450
444451
445452
......
476483
477484
478485
486
487
479488
480
481
482
483
484
489
490
491
485492
486
487
488
489
490
493
494
495
496
497
491498
492499
493500
fsbFrequency = 0;
cpuFrequency = 0;
if ((p->CPU.Vendor == CPUID_VENDOR_INTEL) && ((p->CPU.Family == 0x06) || (p->CPU.Family == 0x0f))) {
if ((p->CPU.Vendor == CPUID_VENDOR_INTEL) && ((p->CPU.Family == 0x06) || (p->CPU.Family == 0x0f)))
{
int intelCPU = p->CPU.Model;
if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03)) {
if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03))
{
/* Nehalem CPU model */
if (p->CPU.Family == 0x06 && (p->CPU.Model == CPU_MODEL_NEHALEM||
p->CPU.Model == CPU_MODEL_FIELDS||
p->CPU.Model == CPU_MODEL_DALES||
p->CPU.Model == CPU_MODEL_FIELDS||
p->CPU.Model == CPU_MODEL_DALES||
p->CPU.Model == CPU_MODEL_DALES_32NM||
p->CPU.Model == CPU_MODEL_WESTMERE||
p->CPU.Model == CPU_MODEL_NEHALEM_EX||
p->CPU.Model == CPU_MODEL_WESTMERE_EX ||
p->CPU.Model == CPU_MODEL_SANDYBRIDGE ||
p->CPU.Model == CPU_MODEL_JAKETOWN||
p->CPU.Model == CPU_MODEL_IVYBRIDGE)) {
p->CPU.Model == CPU_MODEL_IVYBRIDGE))
{
msr = rdmsr64(MSR_PLATFORM_INFO);
DBG("msr(%d): platform_info %08x\n", __LINE__, bitfield(msr, 31, 0));
bus_ratio_max = bitfield(msr, 14, 8);
}
}
if (bus_ratio_max) {
if (bus_ratio_max)
{
fsbFrequency = (tscFrequency / bus_ratio_max);
}
//valv: Turbo Ratio Limit
if ((intelCPU != 0x2e) && (intelCPU != 0x2f)) {
if ((intelCPU != 0x2e) && (intelCPU != 0x2f))
{
msr = rdmsr64(MSR_TURBO_RATIO_LIMIT);
cpuFrequency = bus_ratio_max * fsbFrequency;
max_ratio = bus_ratio_max * 10;
} else {
cpuFrequency = tscFrequency;
}
if ((getValueForKey(kbusratio, &newratio, &len, &bootInfo->chameleonConfig)) && (len <= 4)) {
if ((getValueForKey(kbusratio, &newratio, &len, &bootInfo->chameleonConfig)) && (len <= 4))
{
max_ratio = atoi(newratio);
max_ratio = (max_ratio * 10);
if (len >= 3) max_ratio = (max_ratio + 5);
verbose("Bus-Ratio: min=%d, max=%s\n", bus_ratio_min, newratio);
// extreme overclockers may love 320 ;)
if ((max_ratio >= min_ratio) && (max_ratio <= 320)) {
if ((max_ratio >= min_ratio) && (max_ratio <= 320))
{
cpuFrequency = (fsbFrequency * max_ratio) / 10;
if (len >= 3) maxdiv = 1;
else maxdiv = 0;
}
if (maxcoef)
{
if (maxdiv)
{
if (maxdiv)
{
fsbFrequency = ((tscFrequency * 2) / ((maxcoef * 2) + 1));
} else {
fsbFrequency = (tscFrequency / maxcoef);
fsbFrequency = ((tscFrequency * 2) / ((maxcoef * 2) + 1));
} else {
fsbFrequency = (tscFrequency / maxcoef);
}
if (currdiv)
{
cpuFrequency = (fsbFrequency * ((currcoef * 2) + 1) / 2);
} else {
cpuFrequency = (fsbFrequency * currcoef);
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" : "");
}
branches/ErmaC/Trunk/i386/libsaio/platform.h
102102
103103
104104
105
106
107
108
109
110
111
112
113
114
115
105
106
107
108
109
110
111
112
113
114
115
116
116117
117118
118
119
119
120
121
122
123
124
125
120126
121127
122128
......
140146
141147
142148
143
149
150
144151
145152
146153
......
153160
154161
155162
156
163
164
157165
158166
159167
/* Size of SMBIOS UUID in bytes */
#define UUID_LEN16
typedef struct _RamSlotInfo_t {
uint32_tModuleSize;// Size of Module in MB
uint32_tFrequency;// in Mhz
const char*Vendor;
const char*PartNo;
const char*SerialNo;
char*spd;// SPD Dump
boolInUse;
uint8_tType;
uint8_tBankConnections;// table type 6, see (3.3.7)
uint8_tBankConnCnt;
typedef struct _RamSlotInfo_t
{
uint32_tModuleSize;// Size of Module in MB
uint32_tFrequency;// in Mhz
const char*Vendor;
const char*PartNo;
const char*SerialNo;
char*spd;// SPD Dump
boolInUse;
uint8_tType;
uint8_tBankConnections;// table type 6, see (3.3.7)
uint8_tBankConnCnt;
} RamSlotInfo_t;
typedef struct _PlatformInfo_t {
struct CPU {
//==============================================================================
typedef struct _PlatformInfo_t
{
struct CPU
{
uint32_tFeatures;// CPU Features like MMX, SSE2, VT, MobileCPU
uint32_tVendor;// Vendor
uint32_tSignature;// Signature
uint32_tCPUID[CPUID_MAX][4];// CPUID 0..4, 80..81 Raw Values
} CPU;
struct RAM {
struct RAM
{
uint64_tFrequency;// Ram Frequency
uint32_tDivider;// Memory divider
uint8_tCAS;// CAS 1/2/2.5/3/4/5/6/7
RamSlotInfo_tDIMM[MAX_RAM_SLOTS];// Information about each slot
} RAM;
struct DMI {
struct DMI
{
intMaxMemorySlots;// number of memory slots populated by SMBIOS
intCntMemorySlots;// number of memory slots counted
intMemoryModules;// number of memory modules installed
branches/ErmaC/Trunk/i386/libsaio/disk.c
125125
126126
127127
128
128
129129
130130
131131
......
158158
159159
160160
161
161
162162
163163
164164
......
173173
174174
175175
176
176
177
177178
178179
179180
......
182183
183184
184185
186
187
188
185189
186190
187191
......
193197
194198
195199
200
196201
197202
198203
199204
200205
201
206
207
202208
203209
204210
......
208214
209215
210216
217
218
219
220
221
222
211223
212224
213225
......
224236
225237
226238
227
239
240
228241
229242
230243
231244
232245
233
234
235246
236247
237248
......
249260
250261
251262
252
253
263
254264
255265
256266
......
284294
285295
286296
287
288
297
289298
290299
291300
......
305314
306315
307316
317
308318
309319
310320
......
324334
325335
326336
327
328
337
329338
330339
331340
332
333
341
334342
335343
336344
......
344352
345353
346354
347
355
348356
349357
350358
351359
352360
353
354361
362
363
355364
356365
357366
358367
359368
360
361369
370
371
362372
363373
364374
......
380390
381391
382392
393
383394
384395
385396
......
394405
395406
396407
397
408
398409
399410
400411
......
417428
418429
419430
420
431
421432
422433
423434
......
506517
507518
508519
509
520
510521
511522
512523
......
579590
580591
581592
582
593
583594
584595
585596
......
592603
593604
594605
595
596
597
598
606
607
608
609
599610
600
601
602
603
604
605
606
607
608
609
610
611
612
611
612
613
614
615
616
617
618
619
620
621
622
623
613624
614
615
616
617
625
626
627
628
618629
619
630
620631
621
622
623
632
633
634
624635
625
626
627
636
637
638
628639
629
640
630641
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
649660
650661
651
662
652663
653664
654665
......
673684
674685
675686
676
687
677688
678689
679690
......
750761
751762
752763
753
764
754765
755766
756767
......
10391050
10401051
10411052
1042
1053
10431054
10441055
10451056
......
10771088
10781089
10791090
1080
1091
10811092
10821093
10831094
......
11481159
11491160
11501161
1151
1162
11521163
1153
1154
11551164
11561165
11571166
......
12241233
12251234
12261235
1227
1236
12281237
1229
1238
12301239
12311240
12321241
......
15281537
15291538
15301539
1531
1540
15321541
15331542
15341543
......
18411850
18421851
18431852
1844
1853
18451854
18461855
18471856
......
18631872
18641873
18651874
1866
1875
18671876
18681877
18691878
......
18831892
18841893
18851894
1886
1895
18871896
18881897
18891898
18901899
18911900
18921901
1893
1902
18941903
18951904
18961905
18971906
18981907
1899
1908
19001909
1901
1910
19021911
19031912
19041913
......
20252034
20262035
20272036
2028
2037
2038
2039
20292040
20302041
20312042
......
20432054
20442055
20452056
2046
2057
20472058
20482059
20492060
......
20972108
20982109
20992110
2100
2111
2112
21012113
21022114
21032115
......
21062118
21072119
21082120
2109
2121
2122
21102123
21112124
2112
2125
21132126
2114
2115
2116
2117
2118
2127
21192128
21202129
21212130
extern void spinActivityIndicator(int sectors);
//==========================================================================
//==============================================================================
static int getDriveInfo(int biosdev, struct driveInfo *dip)
{
if (!cached_di.valid || biosdev != cached_di.biosdev)
{
cc = get_drive_info(biosdev, &cached_di);
cc = get_drive_info(biosdev, &cached_di);
if (cc < 0)
{
return 0;
}
//==========================================================================
//==============================================================================
// Maps (E)BIOS return codes to message strings.
struct NamedValue
const char * name;
};
//==============================================================================
static const char * getNameForValue(const struct NamedValue * nameTable, unsigned char value)
{
const struct NamedValue * np;
return np->name;
}
}
return NULL;
}
#define ECC_CORRECTED_ERR 0x11
static const struct NamedValue bios_errors[] = {
static const struct NamedValue bios_errors[] =
{
{ 0x10, "Media error" },
{ 0x11, "Corrected ECC error" },
{ 0x20, "Controller or device error" },
{ 0x00, 0 }
};
static bool cache_valid = false;
//==============================================================================
static const char * bios_error(int errnum)
{
static char errorstr[] = "Error 0x00";
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.
//
// Returns 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;
}
if (di.no_emulation)
{
/* Always assume 2k block size; BIOS may lie about geometry */
bps = 2048;
bps = 2048; /* Always assume 2K block size since the BIOS may lie about the geometry */
}
else
{
{
if (rc == ECC_CORRECTED_ERR)
{
/* Ignore corrected ECC errors */
rc = 0;
rc = 0; /* Ignore corrected ECC errors */
break;
}
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));
{
if (rc == ECC_CORRECTED_ERR)
{
/* Ignore corrected ECC errors */
rc = 0;
rc = 0; /* Ignore corrected ECC errors */
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);
error(" Block %d, Cyl %d Head %d Sector %d\n", secno, cyl, head, sec);
sleep(1);
}
}
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 (error)
{
DEBUG_DISK(("error\n"));
return (-1);
}
return 0;
}
//==========================================================================
//==============================================================================
static int isExtendedFDiskPartition( const struct fdisk_part * part )
{
return 0;
}
//==========================================================================
//==============================================================================
static int getNextFDiskPartition( int biosdev, int * partno,
const struct fdisk_part ** outPart )
return (part != NULL);
}
//==========================================================================
//==============================================================================
static BVRef newFDiskBVRef( int biosdev, int partno, unsigned int blkoff,
const struct fdisk_part * part,
}
}
//==========================================================================
//==============================================================================
BVRef newAPMBVRef( int biosdev, int partno, unsigned int blkoff,
const DPME * part,
BVFree bvFreeFunc,
int probe, int type, unsigned int bvrFlags )
{
BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
if ( bvr )
{
bzero(bvr, sizeof(*bvr));
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);
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;
*/
/*
if ( part->bootid & FDISK_ACTIVE )
bvr->flags |= kBVFlagPrimary;
*/
// Probe the filesystem.
// Probe the filesystem.
if ( initFunc )
{
bvr->flags |= kBVFlagNativeBoot | kBVFlagBootable | kBVFlagSystemVolume;
if ( initFunc )
{
bvr->flags |= kBVFlagNativeBoot | kBVFlagBootable | kBVFlagSystemVolume;
if ( probe && initFunc( bvr ) != 0 )
{
// filesystem probe failed.
if ( probe && initFunc( bvr ) != 0 )
{
// filesystem probe failed.
DEBUG_DISK(("%s: failed probe on dev %x part %d\n", __FUNCTION__, biosdev, partno));
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;
(*bvr->bv_free)(bvr);
bvr = NULL;
}
}
/*
else if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
{
bvr->flags |= kBVFlagForeignBoot;
}
*/
else
{
(*bvr->bv_free)(bvr);
bvr = NULL;
}
}
if (bvr) bvr->flags |= bvrFlags;
return bvr;
}
//==========================================================================
//==============================================================================
// GUID's in LE form:
// http://en.wikipedia.org/wiki/GUID_Partition_Table
// 4C616265-6C00-11AA-AA11-00306543ECAC - Apple Label
// 5265636F-7665-11AA-AA11-00306543ECAC - Apple TV Recovery partition
// 53746F72-6167-11AA-AA11-00306543ECAC - Apple Core Storage (i.e. Lion FileVault) partition (Apple_Boot Recovery HD)
// EFI_GUID const GPT_RECOVERY_GUID = { 0x53746F72, 0x6167, 0x11AA, { 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC } };
EFI_GUID const GPT_CORESTORAGE_GUID = { 0x53746F72, 0x6167, 0x11AA, { 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC } };
BVRef newGPTBVRef( int biosdev, int partno, unsigned int blkoff,
const gpt_ent * part,
return bvr;
}
//==========================================================================
//==============================================================================
/* A note on partition numbers:
* IOKit makes the primary partitions numbers 1-4, and then
return map ? map->bvr : NULL;
}
//==========================================================================
//==============================================================================
static BVRef diskScanAPMBootVolumes( int biosdev, int * countPtr )
{
blksize = BPS;
factor = 1;
}
do
{
// Create a new mapping.
return map ? map->bvr : NULL;
}
//==========================================================================
//==============================================================================
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*
* Trying to figure out the filsystem type of a given partition.
*/
return efi_guid_is_null((EFI_GUID const*)partition->ent_type) ? false : true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//==============================================================================
static BVRef diskScanGPTBootVolumes( int biosdev, int * countPtr )
static BVRef diskScanGPTBootVolumes(int biosdev, int * countPtr)
{
struct DiskBVMap * map = NULL;
void *buffer = malloc(BPS);
return valid;
}
//==========================================================================
//==============================================================================
static void scanFSLevelBVRSettings(BVRef chain)
{
return ret;
}
//==========================================================================
//==============================================================================
static const struct NamedValue fdiskTypes[] =
{
{ 0x00,0 } /* must be last */
};
//==========================================================================
//==============================================================================
bool matchVolumeToString( BVRef bvr, const char* match, long matchLen)
{
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 true;
}
return false;
}
sprintf(bvr->label, p);
}
//==========================================================================
//==============================================================================
int readBootSector(int biosdev, unsigned int secno, void * buffer)
{
int error;
}
}
bootSector = gBootSector;
bootSector = gBootSector;
}
error = readBytes(biosdev, secno, 0, BPS, bootSector);
return 0;
}
//==========================================================================
//==============================================================================
// Handle seek request from filesystem modules.
void diskSeek(BVRef bvr, long long position)
bvr->fs_byteoff = position % BPS;
}
//==========================================================================
//==============================================================================
// Handle read request from filesystem modules.
int diskRead( BVRef bvr, long addr, long length )
int diskRead(BVRef bvr, long addr, long length)
{
return readBytes( bvr->biosdev,
bvr->fs_boff + bvr->part_boff,
bvr->fs_byteoff,
length,
(void *) addr );
return readBytes(bvr->biosdev, bvr->fs_boff + bvr->part_boff, bvr->fs_byteoff, length, (void *) addr);
}
int rawDiskRead( BVRef bvr, unsigned int secno, void *buffer, unsigned int len )
branches/ErmaC/Trunk/i386/libsaio/cache.c
3030
3131
3232
33
34
35
36
33
34
35
36
37
3738
3839
3940
......
4849
4950
5051
51
52
52
53
5354
54
55
55
56
5657
5758
5859
59
60
61
60
61
62
6263
6364
6465
......
7071
7172
7273
74
7375
76
7477
7578
76
77
79
80
7881
82
7983
8084
8185
8286
8387
8488
85
86
87
89
90
91
8892
8993
9094
9195
9296
93
94
95
97
98
99
100
101
102
103
104
105
106
107
96108
97109
98110
......
102114
103115
104116
105
106
117
107118
108
119
109120
110121
111122
112
123
124
113125
114
126
127
115128
116
129
130
131
117132
118133
119134
120135
121136
122137
123
138
139
124140
125141
126142
......
135151
136152
137153
154
138155
139
156
157
158
159
140160
141161
142162
143
163
164
144165
145166
146
167
168
169
147170
148171
149172
150
173
174
175
176
151177
152
178
179
153180
154181
155182
156183
157184
158185
159
186
187
160188
161189
162190
#include <sl.h>
// #include <fs.h>
struct CacheEntry {
CICell ih;
long time;
long long offset;
struct CacheEntry
{
CICell ih;
long time;
long long offset;
};
typedef struct CacheEntry CacheEntry;
static long gCacheTime;
#ifdef __i386__
static CacheEntry *gCacheEntries;
static char *gCacheBuffer;
static CacheEntry *gCacheEntries;
static char *gCacheBuffer;
#else
static CacheEntry gCacheEntries[kCacheMaxEntries];
static char gCacheBuffer[kCacheSize];
static CacheEntry gCacheEntries[kCacheMaxEntries];
static char gCacheBuffer[kCacheSize];
#endif
#if CACHE_STATS
unsigned long gCacheHits;
unsigned long gCacheMisses;
unsigned long gCacheEvicts;
unsigned long gCacheHits;
unsigned long gCacheMisses;
unsigned long gCacheEvicts;
#endif
void CacheReset()
{
#ifdef __i386__
if ((ih == gCacheIH) && (blockSize == gCacheBlockSize))
{
return;
}
#endif
if ((blockSize < kCacheMinBlockSize) ||
(blockSize > kCacheMaxBlockSize))
if ((blockSize < kCacheMinBlockSize) || (blockSize > kCacheMaxBlockSize))
{
return;
}
gCacheBlockSize = blockSize;
gCacheNumEntries = kCacheSize / gCacheBlockSize;
gCacheTime = 0;
#if CACHE_STATS
gCacheHits = 0;
gCacheMisses = 0;
gCacheEvicts = 0;
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 )
if (!gCacheBuffer)
{
gCacheBuffer = (char *) malloc(kCacheSize);
}
if (!gCacheEntries)
{
gCacheEntries = (CacheEntry *) malloc(kCacheMaxEntries * sizeof(CacheEntry));
}
if (!gCacheBuffer || !gCacheEntries)
{
gCacheIH = 0; // invalidate cache
return;
bzero(gCacheEntries, kCacheMaxEntries * sizeof(CacheEntry));
}
long CacheRead( CICell ih, char * buffer, long long offset,
long length, long cache )
long CacheRead(CICell ih, char * buffer, long long offset, long length, long cache)
{
long cnt, oldestEntry = 0, oldestTime, loadCache = 0;
long cnt, oldestEntry = 0, oldestTime, loadCache = 0;
CacheEntry *entry;
// See if the data can be cached.
if (cache && (gCacheIH == ih) && (length == gCacheBlockSize)) {
if (cache && (gCacheIH == ih) && (length == gCacheBlockSize))
{
// Look for the data in the cache.
for (cnt = 0; cnt < gCacheNumEntries; cnt++) {
for (cnt = 0; cnt < gCacheNumEntries; cnt++)
{
entry = &gCacheEntries[cnt];
if ((entry->ih == ih) && (entry->offset == offset)) {
if ((entry->ih == ih) && (entry->offset == offset))
{
entry->time = ++gCacheTime;
break;
}
}
// If the data was found copy it to the caller.
if (cnt != gCacheNumEntries) {
if (cnt != gCacheNumEntries)
{
bcopy(gCacheBuffer + cnt * gCacheBlockSize, buffer, gCacheBlockSize);
#if CACHE_STATS
gCacheHits++;
// Read the data from the disk.
Seek(ih, offset);
Read(ih, (long)buffer, length);
#if CACHE_STATS
if (cache) gCacheMisses++;
if (cache)
{
gCacheMisses++;
}
#endif
// Put the data from the disk in the cache if needed.
if (loadCache) {
if (loadCache)
{
// Find a free entry.
oldestTime = gCacheTime;
for (cnt = 0; cnt < gCacheNumEntries; cnt++) {
for (cnt = 0; cnt < gCacheNumEntries; cnt++)
{
entry = &gCacheEntries[cnt];
// Found a free entry.
if (entry->ih == 0) break;
if (entry->ih == 0)
{
break;
}
if (entry->time < oldestTime) {
if (entry->time < oldestTime)
{
oldestTime = entry->time;
oldestEntry = cnt;
}
}
// If no free entry was found, use the oldest.
if (cnt == gCacheNumEntries) {
if (cnt == gCacheNumEntries)
{
cnt = oldestEntry;
#if CACHE_STATS
gCacheEvicts++;
branches/ErmaC/Trunk/i386/libsaio/pci.c
106106
107107
108108
109
109
110110
111111
112112
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;
branches/ErmaC/Trunk/i386/libsaio/stringTable.c
2020
2121
2222
23
24
2325
24
25
26
27
2826
2927
3028
......
135133
136134
137135
138
139
140
141
142
136
143137
144
145
146
147
138
139
140
141
148142
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
166164
167165
168166
......
194192
195193
196194
197
195
196
198197
199198
200199
201
202
203
204
200
201
202
203
204
205205
206206
207207
208208
209209
210210
211
212
211
212
213
214
213215
214216
215217
......
224226
225227
226228
227
228
229
230
231
229
232230
233
234
235
231
232
233
236234
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
254258
255
256
257259
258260
259261
260
261
262
262
263
264
265
266
263267
264268
265269
......
267271
268272
269273
270
271
272
274
275
276
273277
274
275
276
277
278
279
280
278
279
280
281
282
283
284
285
286
287
281288
282289
283290
......
440447
441448
442449
443
450
444451
445452
446453
447454
448455
449
456
450457
451458
452459
453460
454461
455
462
456463
457464
458
465
459466
460467
461468
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*
* Copyright 1993 NeXT, Inc. All rights reserved.
*/
/*
* Copyright 1993 NeXT, Inc.
* All rights reserved.
*/
#include "bootstruct.h"
#include "libsaio.h"
return true;
}
char *
newStringFromList(
char **list,
int *size
)
char *newStringFromList(char **list, int *size)
{
char *begin = *list, *end;
char *newstr;
int newsize = *size;
int bufsize;
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;
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
bool getValueForConfigTableKey(config_file_t *config, const char *key, const char **val, int *size)
{
if (config->dictionary != 0 ) {
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);
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 {
}
else
{
// Legacy plist-style table
}
* in the string table matching 'key'. Also translates
* \n escapes in the string.
*/
char *newStringForStringTableKey(
char *table,
char *key,
config_file_t *config
)
char *newStringForStringTableKey(char *table, char *key, config_file_t *config)
{
const char *val;
char *newstr, *p;
int size;
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;
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--;
}
size--;
}
}
*p = '\0';
return newstr;
} else {
return 0;
}
}
else
{
return 0;
}
}
#endif
char *
newStringForKey(char *key, config_file_t *config)
{
const char *val;
char *newstr;
int size;
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;
}
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
{
if (*val < '0' || *val > '9')
return false;
sum = (sum * 10) + (*val++ - '0');
}
if (percentage)
sum = ( dimension_max * sum ) / 100;
// calculate offset from opposite origin
if (negative)
sum = ( ( dimension_max - object_size ) - sum );
} else {
// null value calculate center
sum = ( dimension_max - object_size ) / 2;
}
*value = (uint16_t) sum;
branches/ErmaC/Trunk/i386/libsaio/biosfn.c
4848
4949
5050
51
52
53
5154
5255
53
54
55
56
57
58
59
60
61
62
63
56
57
58
59
60
61
62
63
64
65
66
67
6468
6569
70
71
72
6673
6774
68
69
70
71
72
73
74
75
75
76
77
78
79
80
81
82
83
84
85
86
7687
7788
7889
7990
80
81
82
83
91
92
93
94
8495
8596
97
98
99
86100
87101
88
89
90
91
92
93
94
102
103
104
105
106
107
108
109
110
111
95112
96
97
98
99
100
101
113
114
115
116
117
118
119
102120
103121
104122
......
165183
166184
167185
168
169
186
187
170188
171
172
173
174
175
189
190
191
192
193
176194
177
178
179
180
181
182
183
184
185
186
195
196
197
198
199
200
201
202
203
204
187205
188
189
190
191
192
206
207
208
209
210
211
193212
194
195
196
197
198
199
200
201
202
213
214
215
216
217
218
219
220
221
203222
204
223
205224
206
207
208
209
210
211
212
225
226
227
228
229
230
213231
214
232
215233
216
217
218
219
220
221
222
223
234
235
236
237
238
239
240
224241
225
226
227
228
229
242
243
244
245
246
247
230248
231
232
249
250
233251
234
252
235253
236
237
238
239
240
241
242
254
255
256
257
258
259
260
261
243262
244263
245
246
264
265
247266
248267
249
250
268
269
251270
252271
253
254
255
256
257
258
259
260
272
273
274
275
276
277
278
279
280
281
282
283
284
261285
262286
263
287
264288
265289
290
291
292
293
266294
267295
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
286314
287
288
289
315
316
317
290318
291
319
292320
293
321
322
323
324
294325
295
296
297
298
299
300
301
302
303
304
305
306
326
327
328
329
330
331
332
333
334
335
336
337
307338
308
309
310
339
340
341
311342
312
343
313344
314
345
315346
316347
348
349
350
351
317352
318353
319
320
321
354
355
356
357
322358
323359
360
361
362
363
324364
325365
326
327
328
329
366
367
368
369
330370
331371
372
373
374
332375
333376
334
377
335378
336
337
379
380
338381
339
340
341
342
343
344
345
346
382
383
384
385
386
387
388
389
390
347391
348
349
392
393
350394
351
352
353
395
396
397
398
399
354400
355
356
357
401
402
403
404
405
358406
359
360
361
362
363
407
408
409
410
411
412
364413
365414
415
416
417
366418
367419
368
369
370
371
372
373
374
375
376
377
378
420
379421
380
381
382
383
384
385
386
387
388
389
390
391
422
423
424
425
426
427
428
429
430
431
432
392433
393
394
395
434
435
436
437
438
439
440
441
442
443
444
445
446
396447
397
398
399
448
449
450
451
452
400453
401
402
403
404
405
454
455
456
457
458
459
460
461
462
463
464
465
406466
407467
468
469
408470
409471
410
411
412
413
414
415
416
417
418
419
420
472
473
474
475
476
477
478
479
480
481
482
483
421484
422
423
424
425
426
427
428
429
430
431
432
433
434
485
486
487
488
489
490
491
492
493
494
495
496
497
498
435499
436
437
438
500
501
502
439503
440
441
442
504
505
506
443507
444
445
446
447
448
508
509
510
511
512
449513
450514
451515
452516
453
454
455
456
457
458
517
518
519
520
521
522
459523
460524
525
526
527
461528
462529
463
464
465
466
467
468
469
530
531
532
533
534
535
536
470537
471538
472
539
540
541
542
473543
474544
475
545
546
476547
477548
478549
......
488559
489560
490561
491
562
492563
493564
494
495
496
497
498
499
500
501
565
566
567
568
569
570
571
572
502573
574
503575
504576
505
506577
507
508578
509579
510580
511581
582
512583
513584
514
585
515586
516587
517
518
588
589
590
591
519592
520593
521594
......
568641
569642
570643
644
645
571646
572647
573648
574649
575
650
576651
577
652
653
578654
579655
580656
581657
658
582659
583660
584661
585
662
586663
587664
588665
589
666
590667
591668
592
669
593670
594671
595672
......
600677
601678
602679
603
680
681
604682
605683
606684
607685
608
686
687
609688
610689
611690
......
617696
618697
619698
620
699
700
621701
622702
623703
......
628708
629709
630710
631
711
712
632713
633714
634715
......
664745
665746
666747
667
748
749
668750
669751
670752
......
678760
679761
680762
681
763
764
682765
683766
684767
685768
686769
770
771
687772
688773
689
690
691
692
693
694
774
775
776
777
778
779
695780
696781
697782
698783
699
700
701
702
703
704
784
785
786
787
788
789
705790
706791
707792
708793
709
710
711
712
794
795
796
797
713798
714799
715800
716801
717
718
719
720
721
722
802
803
804
805
806
807
723808
724809
725810
726811
727
728
729
730
731
732
733
734
735
812
813
814
815
816
817
818
819
820
736821
737822
738823
739824
740
825
741826
742827
743828
744829
745
746
747
748
830
831
832
833
749834
750835
751836
752837
753838
754839
755
840
756841
757
758
759
760
761
762
763
842
843
844
845
846
847
848
764849
765850
766851
767852
768
769
770
771
772
773
774
775
776
777
778
779
780
781
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
782869
783870
784871
......
787874
788875
789876
790
791
877
792878
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
879
880
881
882
883
884
885
886
887
888
889
890
891
892
808893
809894
810
811
895
812896
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
836923
837924
838925
......
840927
841928
842929
843
844
930
931
845932
846
847
848
933
934
935
936
849937
850
851
852
853
938
939
940
941
854942
855943
856944
857945
858946
859
860
861
862
863
864
865
866
867
868
869
870
871
872
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
873963
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
901991
902992
903993
......
907997
908998
909999
910
911
912
913
914
915
916
917
918
919
920
921
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
9221013
9231014
9241015
......
9271018
9281019
9291020
930
931
932
933
934
935
936
937
938
939
940
941
942
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
9431035
9441036
9451037
......
9481040
9491041
9501042
1043
1044
1045
9511046
9521047
9531048
static biosBuf_t bb;
//==============================================================================
int bgetc(void)
{
/* Poll for the next character. Most real BIOS do not need this as the
INT 16h,AH=0h function will block until one is received.
Unfortunately, Apple's EFI CSM will never wake up. This idea is lifted
from the grub-a20.patch to GRUB's stage2/asm.S file.
*/
while(!readKeyboardStatus())
;
bb.intno = 0x16;
bb.eax.r.h = 0x00;
bios(&bb);
return bb.eax.rr;
/* Poll for the next character. Most real BIOS do not need this as the
INT 16h,AH=0h function will block until one is received.
Unfortunately, Apple's EFI CSM will never wake up. This idea is lifted
from the grub-a20.patch to GRUB's stage2/asm.S file.
*/
while(!readKeyboardStatus());
bb.intno = 0x16;
bb.eax.r.h = 0x00;
bios(&bb);
return bb.eax.rr;
}
//==============================================================================
int readKeyboardStatus(void)
{
bb.intno = 0x16;
bb.eax.r.h = 0x01;
bios(&bb);
if (bb.flags.zf) {
return 0;
} else {
return bb.eax.rr;
}
bb.intno = 0x16;
bb.eax.r.h = 0x01;
bios(&bb);
if (bb.flags.zf)
{
return 0;
}
else
{
return bb.eax.rr;
}
}
int readKeyboardShiftFlags(void)
{
bb.intno = 0x16;
bb.eax.r.h = 0x02;
bios(&bb);
return bb.eax.r.l;
bb.intno = 0x16;
bb.eax.r.h = 0x02;
bios(&bb);
return bb.eax.r.l;
}
//==============================================================================
unsigned int time18(void)
{
union {
struct {
unsigned int low:16;
unsigned int high:16;
} s;
unsigned int i;
} time;
union
{
struct
{
unsigned int low:16;
unsigned int high:16;
} s;
unsigned int i;
} time;
bb.intno = 0x1a;
bb.eax.r.h = 0x00;
bios(&bb);
time.s.low = bb.edx.rr;
time.s.high = bb.ecx.rr;
return time.i;
bb.intno = 0x1a;
bb.eax.r.h = 0x00;
bios(&bb);
time.s.low = bb.edx.rr;
time.s.high = bb.ecx.rr;
return time.i;
}
#if 0
unsigned long * conMemSizePtr,
unsigned long * extMemSizePtr )
{
#define kMemoryMapSignature 'SMAP'
#define kDescriptorSizeMin 20
#define kMemoryMapSignature 'SMAP'
#define kDescriptorSizeMin 20
MemoryRange *range = (MemoryRange *)BIOS_ADDR;
unsigned longcount = 0;
// unsigned longrerangedCount;
unsigned long longconMemSize = 0;
unsigned long longextMemSize = 0;
MemoryRange *range = (MemoryRange *)BIOS_ADDR;
unsigned longcount = 0;
// unsigned longrerangedCount;
unsigned long longconMemSize = 0;
unsigned long longextMemSize = 0;
// Prepare for the INT15 E820h call. Each call returns a single
// memory range. A continuation value is returned that must be
// provided on a subsequent call to fetch the next range.
//
// Certain BIOSes (Award 6.00PG) expect the upper word in EAX
// to be cleared on entry, otherwise only a single range will
// be reported.
//
// Some BIOSes will simply ignore the value of ECX on entry.
// Probably best to keep its value at 20 to avoid surprises.
// Prepare for the INT15 E820h call. Each call returns a single
// memory range. A continuation value is returned that must be
// provided on a subsequent call to fetch the next range.
//
// Certain BIOSes (Award 6.00PG) expect the upper word in EAX
// to be cleared on entry, otherwise only a single range will
// be reported.
//
// Some BIOSes will simply ignore the value of ECX on entry.
// Probably best to keep its value at 20 to avoid surprises.
//printf("Get memory map 0x%x, %d\n", rangeArray); getchar();
if (maxRangeCount > (BIOS_LEN / sizeof(MemoryRange))) {
maxRangeCount = (BIOS_LEN / sizeof(MemoryRange));
}
bb.ebx.rx = 0; // Initial continuation value must be zero.
//printf("Get memory map 0x%x, %d\n", rangeArray); getchar();
if (maxRangeCount > (BIOS_LEN / sizeof(MemoryRange)))
{
maxRangeCount = (BIOS_LEN / sizeof(MemoryRange));
}
bb.ebx.rx = 0; // Initial continuation value must be zero.
while ( count < maxRangeCount )
{
bb.intno = 0x15;
bb.eax.rx = 0xe820;
bb.ecx.rx = kDescriptorSizeMin;
bb.edx.rx = kMemoryMapSignature;
bb.edi.rr = NORMALIZED_OFFSET( (unsigned long) range );
bb.es = NORMALIZED_SEGMENT( (unsigned long) range );
bios(&bb);
while (count < maxRangeCount)
{
bb.intno = 0x15;
bb.eax.rx = 0xe820;
bb.ecx.rx = kDescriptorSizeMin;
bb.edx.rx = kMemoryMapSignature;
bb.edi.rr = NORMALIZED_OFFSET( (unsigned long) range );
bb.es = NORMALIZED_SEGMENT( (unsigned long) range );
bios(&bb);
// Check for errors.
// Check for errors.
if ( bb.flags.cf
|| bb.eax.rx != kMemoryMapSignature
|| bb.ecx.rx != kDescriptorSizeMin ) {
//printf("Got an error %x %x %x\n", bb.flags.cf,
// bb.eax.rx, bb.ecx.rx);
break;
}
if ( bb.flags.cf || bb.eax.rx != kMemoryMapSignature || bb.ecx.rx != kDescriptorSizeMin )
{
//printf("Got an error %x %x %x\n", bb.flags.cf,
// bb.eax.rx, bb.ecx.rx);
break;
}
// Tally up the conventional/extended memory sizes.
// Tally up the conventional/extended memory sizes.
if ( range->type == kMemoryRangeUsable ||
range->type == kMemoryRangeACPI ||
range->type == kMemoryRangeNVS )
{
// Tally the conventional memory ranges.
if ( range->base + range->length <= 0xa0000 ) {
conMemSize += range->length;
}
if (range->type == kMemoryRangeUsable || range->type == kMemoryRangeACPI || range->type == kMemoryRangeNVS )
{
// Tally the conventional memory ranges.
if (range->base + range->length <= 0xa0000)
{
conMemSize += range->length;
}
// Record the top of extended memory.
if ( range->base >= EXTENDED_ADDR ) {
extMemSize += range->length;
}
}
// Record the top of extended memory.
if (range->base >= EXTENDED_ADDR)
{
extMemSize += range->length;
}
}
range++;
count++;
range++;
count++;
// Is this the last address range?
// Is this the last address range?
if ( bb.ebx.rx == 0 ) {
//printf("last range\n");
break;
}
}
*conMemSizePtr = conMemSize / 1024; // size in KB
*extMemSizePtr = extMemSize / 1024; // size in KB
if ( bb.ebx.rx == 0 )
{
//printf("last range\n");
break;
}
}
*conMemSizePtr = conMemSize / 1024; // size in KB
*extMemSizePtr = extMemSize / 1024; // size in KB
#if 0
rerangedCount = rerangeMemoryMap(count);
range += rerangedCount - count;
rerangedCount = rerangeMemoryMap(count);
range += rerangedCount - count;
#endif
// Copy out data
bcopy((char *)BIOS_ADDR, rangeArray, ((char *)range - (char *)BIOS_ADDR));
// Copy out data
bcopy((char *)BIOS_ADDR, rangeArray, ((char *)range - (char *)BIOS_ADDR));
#if DEBUG
{
int i;
printf("%d total ranges\n", count); getchar();
for (i=0, range = rangeArray; i<count; i++, range++) {
printf("range: type %d, base 0x%x, length 0x%x\n",
range->type, (unsigned int)range->base, (unsigned int)range->length); getchar();
}
}
{
int i;
printf("%d total ranges\n", count);
getchar();
for (i = 0, range = rangeArray; i<count; i++, range++)
{
printf("range: type %d, base 0x%x, length 0x%x\n",
range->type, (unsigned int)range->base, (unsigned int)range->length);
getchar();
}
}
#endif
return count;
return count;
}
//==============================================================================
unsigned long getExtendedMemorySize()
{
// Get extended memory size for large configurations. Not used unless
// the INT15, E820H call (Get System Address Map) failed.
//
// Input:
//
// AX Function Code E801h
//
// Outputs:
//
// CF Carry Flag Carry cleared indicates no error.
// AX Extended 1 Number of contiguous KB between 1 and 16 MB,
// maximum 0x3C00 = 15 MB.
// BX Extended 2 Number of contiguous 64 KB blocks between
// 16 MB and 4 GB.
// CX Configured 1 Number of contiguous KB between 1 and 16 MB,
// maximum 0x3C00 = 15 MB.
// DX Configured 2 Number of contiguous 64 KB blocks between
// 16 MB and 4 GB.
// Get extended memory size for large configurations. Not used unless
// the INT15, E820H call (Get System Address Map) failed.
//
// Input:
//
// AX Function Code E801h
//
// Outputs:
//
// CF Carry Flag Carry cleared indicates no error.
// AX Extended 1 Number of contiguous KB between 1 and 16 MB,
// maximum 0x3C00 = 15 MB.
// BX Extended 2 Number of contiguous 64 KB blocks between
// 16 MB and 4 GB.
// CX Configured 1 Number of contiguous KB between 1 and 16 MB,
// maximum 0x3C00 = 15 MB.
// DX Configured 2 Number of contiguous 64 KB blocks between
// 16 MB and 4 GB.
bb.intno = 0x15;
bb.eax.rx = 0xe801;
bios(&bb);
bb.intno = 0x15;
bb.eax.rx = 0xe801;
bios(&bb);
// Return the size of memory above 1MB (extended memory) in kilobytes.
// Return the size of memory above 1MB (extended memory) in kilobytes.
if ( bb.flags.cf == 0 ) return (bb.ebx.rr * 64 + bb.eax.rr);
if (bb.flags.cf == 0)
{
return (bb.ebx.rr * 64 + bb.eax.rr);
}
// Get Extended memory size. Called on last resort since the return
// value is limited to 16-bits (a little less than 64MB max). May
// not be supported by modern BIOSes.
//
// Input:
//
// AX Function Code E801h
//
// Outputs:
//
// CF Carry Flag Carry cleared indicates no error.
// AX Memory Count Number of contiguous KB above 1MB.
// Get Extended memory size. Called on last resort since the return
// value is limited to 16-bits (a little less than 64MB max). May
// not be supported by modern BIOSes.
//
// Input:
//
// AX Function Code E801h
//
// Outputs:
//
// CF Carry Flag Carry cleared indicates no error.
// AX Memory Count Number of contiguous KB above 1MB.
bb.intno = 0x15;
bb.eax.rx = 0x88;
bios(&bb);
bb.intno = 0x15;
bb.eax.rx = 0x88;
bios(&bb);
// Return the size of memory above 1MB (extended memory) in kilobytes.
// Return the size of memory above 1MB (extended memory) in kilobytes.
return bb.flags.cf ? 0 : bb.eax.rr;
return bb.flags.cf ? 0 : bb.eax.rr;
}
//==============================================================================
unsigned long getConventionalMemorySize()
{
bb.intno = 0x12;
bios(&bb);
return bb.eax.rr; // kilobytes
bb.intno = 0x12;
bios(&bb);
return bb.eax.rr; // kilobytes
}
//==============================================================================
void video_mode(int mode)
{
bb.intno = 0x10;
bb.eax.r.h = 0x00;
bb.eax.r.l = mode;
bios(&bb);
bb.intno = 0x10;
bb.eax.r.h = 0x00;
bb.eax.r.l = mode;
bios(&bb);
}
//==============================================================================
int biosread(int dev, int cyl, int head, int sec, int num)
{
int i;
int i;
bb.intno = 0x13;
sec += 1; /* sector numbers start at 1 */
bb.intno = 0x13;
sec += 1; // sector numbers start at 1.
for (i=0;;) {
bb.ecx.r.h = cyl;
bb.ecx.r.l = ((cyl & 0x300) >> 2) | (sec & 0x3F);
bb.edx.r.h = head;
bb.edx.r.l = dev;
bb.eax.r.l = num;
bb.ebx.rr = OFFSET(ptov(BIOS_ADDR));
bb.es = SEGMENT(ptov(BIOS_ADDR));
for (i=0;;)
{
bb.ecx.r.h = cyl;
bb.ecx.r.l = ((cyl & 0x300) >> 2) | (sec & 0x3F);
bb.edx.r.h = head;
bb.edx.r.l = dev;
bb.eax.r.l = num;
bb.ebx.rr = OFFSET(ptov(BIOS_ADDR));
bb.es = SEGMENT(ptov(BIOS_ADDR));
bb.eax.r.h = 0x02;
bios(&bb);
bb.eax.r.h = 0x02;
bios(&bb);
/* In case of a successful call, make sure we set AH (return code) to zero. */
if (bb.flags.cf == 0)
bb.eax.r.h = 0;
// In case of a successful call, make sure we set AH (return code) to zero.
if (bb.flags.cf == 0)
{
bb.eax.r.h = 0;
}
/* Now we can really check for the return code (AH) value. */
if ((bb.eax.r.h == 0x00) || (i++ >= 5))
break;
// Now we can really check for the return code (AH) value.
if ((bb.eax.r.h == 0x00) || (i++ >= 5))
{
break;
}
/* reset disk subsystem and try again */
bb.eax.r.h = 0x00;
bios(&bb);
}
return bb.eax.r.h;
// Reset disk subsystem and try again.
bb.eax.r.h = 0x00;
bios(&bb);
}
return bb.eax.r.h;
}
//==============================================================================
int ebiosread(int dev, unsigned long long sec, int count)
{
int i;
static struct {
unsigned char size;
unsigned char reserved;
unsigned char numblocks;
unsigned char reserved2;
unsigned short bufferOffset;
unsigned short bufferSegment;
unsigned long long startblock;
} addrpacket __attribute__((aligned(16))) = {0};
addrpacket.size = sizeof(addrpacket);
int i;
for (i=0;;) {
bb.intno = 0x13;
bb.eax.r.h = 0x42;
bb.edx.r.l = dev;
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&addrpacket);
bb.ds = NORMALIZED_SEGMENT((unsigned)&addrpacket);
addrpacket.reserved = addrpacket.reserved2 = 0;
addrpacket.numblocks = count;
addrpacket.bufferOffset = OFFSET(ptov(BIOS_ADDR));
addrpacket.bufferSegment = SEGMENT(ptov(BIOS_ADDR));
addrpacket.startblock = sec;
bios(&bb);
static struct
{
unsigned char size;
unsigned char reserved;
unsigned char numblocks;
unsigned char reserved2;
unsigned short bufferOffset;
unsigned short bufferSegment;
unsigned long long startblock;
} addrpacket __attribute__((aligned(16))) = {0};
addrpacket.size = sizeof(addrpacket);
/* In case of a successful call, make sure we set AH (return code) to zero. */
if (bb.flags.cf == 0)
bb.eax.r.h = 0;
for (i = 0; ;)
{
bb.intno = 0x13;
bb.eax.r.h = 0x42;
bb.edx.r.l = dev;
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&addrpacket);
bb.ds = NORMALIZED_SEGMENT((unsigned)&addrpacket);
addrpacket.reserved = addrpacket.reserved2 = 0;
addrpacket.numblocks = count;
addrpacket.bufferOffset = OFFSET(ptov(BIOS_ADDR));
addrpacket.bufferSegment = SEGMENT(ptov(BIOS_ADDR));
addrpacket.startblock = sec;
bios(&bb);
/* Now we can really check for the return code (AH) value. */
if ((bb.eax.r.h == 0x00) || (i++ >= 5))
break;
// In case of a successful call, make sure we set AH (return code) to zero.
if (bb.flags.cf == 0)
{
bb.eax.r.h = 0;
}
/* reset disk subsystem and try again */
bb.eax.r.h = 0x00;
bios(&bb);
}
return bb.eax.r.h;
// Now we can really check for the return code (AH) value.
if ((bb.eax.r.h == 0x00) || (i++ >= 5))
{
break;
}
// Reset disk subsystem and try again.
bb.eax.r.h = 0x00;
bios(&bb);
}
return bb.eax.r.h;
}
//==============================================================================
int ebioswrite(int dev, long sec, int count)
{
int i;
static struct {
unsigned char size;
unsigned char reserved;
unsigned char numblocks;
unsigned char reserved2;
unsigned short bufferOffset;
unsigned short bufferSegment;
unsigned long long startblock;
} addrpacket __attribute__((aligned(16))) = {0};
addrpacket.size = sizeof(addrpacket);
int i;
static struct
{
unsigned char size;
unsigned char reserved;
unsigned char numblocks;
unsigned char reserved2;
unsigned short bufferOffset;
unsigned short bufferSegment;
unsigned long long startblock;
} addrpacket __attribute__((aligned(16))) = {0};
addrpacket.size = sizeof(addrpacket);
for (i=0;;) {
bb.intno = 0x13;
bb.eax.r.l = 0; /* Don't verify */
bb.eax.r.h = 0x43;
bb.edx.r.l = dev;
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&addrpacket);
bb.ds = NORMALIZED_SEGMENT((unsigned)&addrpacket);
addrpacket.reserved = addrpacket.reserved2 = 0;
addrpacket.numblocks = count;
addrpacket.bufferOffset = OFFSET(ptov(BIOS_ADDR));
addrpacket.bufferSegment = SEGMENT(ptov(BIOS_ADDR));
addrpacket.startblock = sec;
bios(&bb);
for (i=0;;)
{
bb.intno = 0x13;
bb.eax.r.l = 0; /* Don't verify */
bb.eax.r.h = 0x43;
bb.edx.r.l = dev;
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&addrpacket);
bb.ds = NORMALIZED_SEGMENT((unsigned)&addrpacket);
addrpacket.reserved = addrpacket.reserved2 = 0;
addrpacket.numblocks = count;
addrpacket.bufferOffset = OFFSET(ptov(BIOS_ADDR));
addrpacket.bufferSegment = SEGMENT(ptov(BIOS_ADDR));
addrpacket.startblock = sec;
bios(&bb);
/* In case of a successful call, make sure we set AH (return code) to zero. */
if (bb.flags.cf == 0)
bb.eax.r.h = 0;
/* In case of a successful call, make sure we set AH (return code) to zero. */
if (bb.flags.cf == 0)
bb.eax.r.h = 0;
/* Now we can really check for the return code (AH) value. */
if ((bb.eax.r.h == 0x00) || (i++ >= 5))
break;
/* Now we can really check for the return code (AH) value. */
if ((bb.eax.r.h == 0x00) || (i++ >= 5))
break;
/* reset disk subsystem and try again */
bb.eax.r.h = 0x00;
bios(&bb);
}
return bb.eax.r.h;
/* reset disk subsystem and try again */
bb.eax.r.h = 0x00;
bios(&bb);
}
return bb.eax.r.h;
}
void bios_putchar(int ch)
{
bb.intno = 0x10;
bb.ebx.r.h = 0x00; /* background black */
bb.ebx.r.l = 0x0F; /* foreground white */
bb.eax.r.h = 0x0e;
bb.eax.r.l = ch;
bios(&bb);
bb.intno = 0x10;
bb.ebx.r.h = 0x00; /* background black */
bb.ebx.r.l = 0x0F; /* foreground white */
bb.eax.r.h = 0x0e;
bb.eax.r.l = ch;
bios(&bb);
}
//==============================================================================
void putca(int ch, int attr, int repeat)
{
bb.intno = 0x10;
bb.ebx.r.h = 0x00; /* page number */
bb.ebx.r.l = attr; /* attribute */
bb.eax.r.h = 0x9;
bb.eax.r.l = ch;
bb.ecx.rx = repeat; /* repeat count */
bios(&bb);
bb.intno = 0x10;
bb.ebx.r.h = 0x00; /* page number */
bb.ebx.r.l = attr; /* attribute */
bb.eax.r.h = 0x9;
bb.eax.r.l = ch;
bb.ecx.rx = repeat; /* repeat count */
bios(&bb);
}
/* Check to see if the passed-in drive is in El Torito no-emulation mode. */
//==============================================================================
// Check to see if the passed-in drive is in El Torito no-emulation mode.
int is_no_emulation(int drive)
{
struct packet {
struct packet
{
unsigned char packet_size;
unsigned char media_type;
unsigned char drive_num;
unsigned char reseved;
} __attribute__((packed));
static struct packet pkt;
bzero(&pkt, sizeof(pkt));
pkt.packet_size = 0x13;
bb.intno= 0x13;
bb.eax.r.h= 0x4b;
bb.eax.r.l= 0x01; // subfunc: get info
bb.edx.r.l= drive;
bb.esi.rr= NORMALIZED_OFFSET((unsigned)&pkt);
bb.ds= NORMALIZED_SEGMENT((unsigned)&pkt);
bb.intno = 0x13;
bb.eax.r.h = 0x4b;
bb.eax.r.l = 0x01; // subfunc: get info
bb.edx.r.l = drive;
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&pkt);
bb.ds = NORMALIZED_SEGMENT((unsigned)&pkt);
bios(&bb);
#if DEBUG
printf("el_torito info drive %x\n", drive);
printf("--> cf %x, eax %x\n", bb.flags.cf, bb.eax.rr);
printf("pkt_size: %x\n", pkt.packet_size);
printf("media_type: %x\n", pkt.media_type);
printf("drive_num: %x\n", pkt.drive_num);
printf("device_spec: %x\n", pkt.device_spec);
pause();
#endif
/* Some BIOSes erroneously return cf = 1 */
/* Just check to see if the drive number is the same. */
if (pkt.drive_num == drive) {
if ((pkt.media_type & 0x0F) == 0) {
if (pkt.drive_num == drive)
{
if ((pkt.media_type & 0x0F) == 0)
{
/* We are in no-emulation mode. */
return 1;
}
#endif
//==============================================================================
int get_drive_info(int drive, struct driveInfo *dp)
{
boot_drive_info_t *di = &dp->di;
int ret = 0;
#if UNUSED
if (maxhd == 0) {
if (maxhd == 0)
{
bb.intno = 0x13;
bb.eax.r.h = 0x08;
bb.edx.r.l = 0x80;
bios(&bb);
if (bb.flags.cf == 0)
maxhd = 0x7f + bb.edx.r.l;
};
if (drive > maxhd)
return 0;
#endif
bzero(dp, sizeof(struct driveInfo));
dp->biosdev = drive;
/* Check for El Torito no-emulation mode. */
dp->no_emulation = is_no_emulation(drive);
bb.ebx.rr = 0x55aa;
bios(&bb);
if ((bb.ebx.rr == 0xaa55) && (bb.flags.cf == 0)) {
if ((bb.ebx.rr == 0xaa55) && (bb.flags.cf == 0))
{
/* Get flags for supported operations. */
dp->uses_ebios = bb.ecx.r.l;
}
if (dp->uses_ebios & (EBIOS_ENHANCED_DRIVE_INFO | EBIOS_LOCKING_ACCESS | EBIOS_FIXED_DISK_ACCESS)) {
if (dp->uses_ebios & (EBIOS_ENHANCED_DRIVE_INFO | EBIOS_LOCKING_ACCESS | EBIOS_FIXED_DISK_ACCESS))
{
/* Get EBIOS drive info. */
static struct drive_params params;
bb.ds = NORMALIZED_SEGMENT((unsigned)&params);
bios(&bb);
if (bb.flags.cf != 0 /* || params.phys_sectors < 2097152 */) {
if (bb.flags.cf != 0 /* || params.phys_sectors < 2097152 */)
{
dp->uses_ebios = 0;
di->params.buf_size = 1;
}
if (drive >= BASE_HD_DRIVE &&
(dp->uses_ebios & EBIOS_ENHANCED_DRIVE_INFO) &&
di->params.buf_size >= 30 &&
!(di->params.dpte_offset == 0xFFFF && di->params.dpte_segment == 0xFFFF)) {
!(di->params.dpte_offset == 0xFFFF && di->params.dpte_segment == 0xFFFF))
{
void *ptr = (void *)(di->params.dpte_offset + ((unsigned int)di->params.dpte_segment << 4));
bcopy(ptr, &di->dpte, sizeof(di->dpte));
}
//}
//}
if (dp->no_emulation) {
if (dp->no_emulation)
{
/* Some BIOSes give us erroneous EBIOS support information.
* Assume that if you're on a CD, then you can use
* EBIOS disk calls.
pause();
#endif
if (ret == 0) {
if (ret == 0)
{
dp->valid = 1;
}
return ret;
}
//==============================================================================
int ebiosEjectMedia(int biosdev)
{
bb.intno = 0x13;
bb.eax.r.h = 0x46;
bb.eax.r.l = 0;
bb.edx.rx = biosdev;
bios(&bb);
return bb.eax.r.h;
bb.intno = 0x13;
bb.eax.r.h = 0x46;
bb.eax.r.l = 0;
bb.edx.rx = biosdev;
bios(&bb);
return bb.eax.r.h;
}
void setCursorPosition(int x, int y, int page)
{
bb.intno = 0x10;
bb.eax.r.h = 0x02;
bb.ebx.r.h = page; /* page 0 for graphics */
bb.edx.r.l = x;
bb.edx.r.h = y;
bios(&bb);
bb.intno = 0x10;
bb.eax.r.h = 0x02;
bb.ebx.r.h = page; /* page 0 for graphics */
bb.edx.r.l = x;
bb.edx.r.h = y;
bios(&bb);
}
void setCursorType(int type)
{
bb.intno = 0x10;
bb.eax.r.h = 0x01;
bb.ecx.rr = type;
bios(&bb);
bb.intno = 0x10;
bb.eax.r.h = 0x01;
bb.ecx.rr = type;
bios(&bb);
}
void getCursorPositionAndType(int * x, int * y, int * type)
{
bb.intno = 0x10;
bb.eax.r.h = 0x03;
bios(&bb);
*x = bb.edx.r.l;
*y = bb.edx.r.h;
*type = bb.ecx.rr;
bb.intno = 0x10;
bb.eax.r.h = 0x03;
bios(&bb);
*x = bb.edx.r.l;
*y = bb.edx.r.h;
*type = bb.ecx.rr;
}
void scollPage(int x1, int y1, int x2, int y2, int attr, int rows, int dir)
{
bb.intno = 0x10;
bb.eax.r.h = (dir > 0) ? 0x06 : 0x07;
bb.eax.r.l = rows;
bb.ebx.r.h = attr;
bb.ecx.r.h = y1;
bb.ecx.r.l = x1;
bb.edx.r.h = y2;
bb.edx.r.l = x2;
bios(&bb);
bb.intno = 0x10;
bb.eax.r.h = (dir > 0) ? 0x06 : 0x07;
bb.eax.r.l = rows;
bb.ebx.r.h = attr;
bb.ecx.r.h = y1;
bb.ecx.r.l = x1;
bb.edx.r.h = y2;
bb.edx.r.l = x2;
bios(&bb);
}
void clearScreenRows( int y1, int y2 )
{
scollPage( 0, y1, 80 - 1, y2, 0x07, y2 - y1 + 1, 1 );
scollPage( 0, y1, 80 - 1, y2, 0x07, y2 - y1 + 1, 1 );
}
void setActiveDisplayPage( int page )
{
bb.intno = 0x10;
bb.eax.r.h = 5;
bb.eax.r.l = page;
bios(&bb);
bb.intno = 0x10;
bb.eax.r.h = 5;
bb.eax.r.l = page;
bios(&bb);
}
#if DEBUG
int terminateDiskEmulation()
{
static char cd_spec[0x13];
static char cd_spec[0x13];
bb.intno = 0x13;
bb.eax.r.h = 0x4b;
bb.eax.r.l = 0; // subfunc: terminate emulation
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&cd_spec);
bb.ds = NORMALIZED_SEGMENT((unsigned)&cd_spec);
bios(&bb);
return bb.eax.r.h;
bb.intno = 0x13;
bb.eax.r.h = 0x4b;
bb.eax.r.l = 0; // subfunc: terminate emulation
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&cd_spec);
bb.ds = NORMALIZED_SEGMENT((unsigned)&cd_spec);
bios(&bb);
return bb.eax.r.h;
}
int readDriveParameters(int drive, struct driveParameters *dp)
{
bb.intno = 0x13;
bb.edx.r.l = drive;
bb.eax.r.h = 0x08;
bios(&bb);
if (bb.eax.r.h == 0) {
dp->heads = bb.edx.r.h;
dp->sectors = bb.ecx.r.l & 0x3F;
dp->cylinders = bb.ecx.r.h | ((bb.ecx.r.l & 0xC0) << 2);
dp->totalDrives = bb.edx.r.l;
} else {
bzero(dp, sizeof(*dp));
}
return bb.eax.r.h;
bb.intno = 0x13;
bb.edx.r.l = drive;
bb.eax.r.h = 0x08;
bios(&bb);
if (bb.eax.r.h == 0)
{
dp->heads = bb.edx.r.h;
dp->sectors = bb.ecx.r.l & 0x3F;
dp->cylinders = bb.ecx.r.h | ((bb.ecx.r.l & 0xC0) << 2);
dp->totalDrives = bb.edx.r.l;
}
else
{
bzero(dp, sizeof(*dp));
}
return bb.eax.r.h;
}
#endif
#define APM_INTNO 0x15
#define APM_INTCODE 0x53
int
APMPresent(void)
int APMPresent(void)
{
bb.intno = APM_INTNO;
bb.eax.r.h = APM_INTCODE;
bb.eax.r.l = 0x00;
bb.ebx.rr = 0x0000;
bios(&bb);
if ((bb.flags.cf == 0) &&
(bb.ebx.r.h == 'P') &&
(bb.ebx.r.l == 'M')) {
/* Success */
bootArgs->apmConfig.major_vers = bb.eax.r.h;
bootArgs->apmConfig.minor_vers = bb.eax.r.l;
bootArgs->apmConfig.flags.data = bb.ecx.rr;
return 1;
}
return 0;
bb.intno = APM_INTNO;
bb.eax.r.h = APM_INTCODE;
bb.eax.r.l = 0x00;
bb.ebx.rr = 0x0000;
bios(&bb);
if ((bb.flags.cf == 0) && (bb.ebx.r.h == 'P') && (bb.ebx.r.l == 'M'))
{
/* Success */
bootArgs->apmConfig.major_vers = bb.eax.r.h;
bootArgs->apmConfig.minor_vers = bb.eax.r.l;
bootArgs->apmConfig.flags.data = bb.ecx.rr;
return 1;
}
return 0;
}
int
APMConnect32(void)
int APMConnect32(void)
{
bb.intno = APM_INTNO;
bb.eax.r.h = APM_INTCODE;
bb.eax.r.l = 0x03;
bb.ebx.rr = 0x0000;
bios(&bb);
if (bb.flags.cf == 0) {
/* Success */
bootArgs->apmConfig.cs32_base = (bb.eax.rr) << 4;
bootArgs->apmConfig.entry_offset = bb.ebx.rx;
bootArgs->apmConfig.cs16_base = (bb.ecx.rr) << 4;
bootArgs->apmConfig.ds_base = (bb.edx.rr) << 4;
if (bootArgs->apmConfig.major_vers >= 1 &&
bootArgs->apmConfig.minor_vers >= 1) {
bootArgs->apmConfig.cs_length = bb.esi.rr;
bootArgs->apmConfig.ds_length = bb.edi.rr;
} else {
bootArgs->apmConfig.cs_length =
bootArgs->apmConfig.ds_length = 64 * 1024;
}
bootArgs->apmConfig.connected = 1;
return 1;
}
return 0;
bb.intno = APM_INTNO;
bb.eax.r.h = APM_INTCODE;
bb.eax.r.l = 0x03;
bb.ebx.rr = 0x0000;
bios(&bb);
if (bb.flags.cf == 0)
{
/* Success */
bootArgs->apmConfig.cs32_base = (bb.eax.rr) << 4;
bootArgs->apmConfig.entry_offset = bb.ebx.rx;
bootArgs->apmConfig.cs16_base = (bb.ecx.rr) << 4;
bootArgs->apmConfig.ds_base = (bb.edx.rr) << 4;
if (bootArgs->apmConfig.major_vers >= 1 && bootArgs->apmConfig.minor_vers >= 1)
{
bootArgs->apmConfig.cs_length = bb.esi.rr;
bootArgs->apmConfig.ds_length = bb.edi.rr;
}
else
{
bootArgs->apmConfig.cs_length =
bootArgs->apmConfig.ds_length = 64 * 1024;
}
bootArgs->apmConfig.connected = 1;
return 1;
}
return 0;
}
#endif /* APM_SUPPORT */
#ifdef EISA_SUPPORT
bool eisa_present(void)
{
static bool checked = false;
static bool isEISA;
static bool checked = false;
static bool isEISA;
if (!checked) {
if (strncmp((char *)0xfffd9, "EISA", 4) == 0)
isEISA = true;
if (!checked)
{
if (strncmp((char *)0xfffd9, "EISA", 4) == 0)
isEISA = true;
checked = true;
}
return (isEISA);
checked = true;
}
return (isEISA);
}
int
ReadEISASlotInfo(EISA_slot_info_t *ep, int slot)
{
union {
struct {
unsigned char char2h :2;
unsigned char char1 :5;
unsigned char char3 :5;
unsigned char char2l :3;
unsigned char d2 :4;
unsigned char d1 :4;
unsigned char d4 :4;
unsigned char d3 :4;
} s;
unsigned char data[4];
} u;
static char hex[0x10] = "0123456789ABCDEF";
union
{
struct
{
unsigned char char2h :2;
unsigned char char1 :5;
unsigned char char3 :5;
unsigned char char2l :3;
unsigned char d2 :4;
unsigned char d1 :4;
unsigned char d4 :4;
unsigned char d3 :4;
} s;
unsigned char data[4];
} u;
static char hex[0x10] = "0123456789ABCDEF";
bb.intno = 0x15;
bb.eax.r.h = 0xd8;
bb.eax.r.l = 0x00;
bb.ecx.r.l = slot;
bios(&bb);
if (bb.flags.cf)
return bb.eax.r.h;
ep->u_ID.d = bb.eax.r.l;
ep->configMajor = bb.ebx.r.h;
ep->configMinor = bb.ebx.r.l;
ep->checksum = bb.ecx.rr;
ep->numFunctions = bb.edx.r.h;
ep->u_resources.d = bb.edx.r.l;
u.data[0] = bb.edi.r.l;
u.data[1] = bb.edi.r.h;
u.data[2] = bb.esi.r.l;
u.data[3] = bb.esi.r.h;
ep->id[0] = u.s.char1 + ('A' - 1);
ep->id[1] = (u.s.char2l | (u.s.char2h << 3)) + ('A' - 1);
ep->id[2] = u.s.char3 + ('A' - 1);
ep->id[3] = hex[u.s.d1];
ep->id[4] = hex[u.s.d2];
ep->id[5] = hex[u.s.d3];
ep->id[6] = hex[u.s.d4];
ep->id[7] = 0;
return 0;
bb.intno = 0x15;
bb.eax.r.h = 0xd8;
bb.eax.r.l = 0x00;
bb.ecx.r.l = slot;
bios(&bb);
if (bb.flags.cf)
return bb.eax.r.h;
ep->u_ID.d = bb.eax.r.l;
ep->configMajor = bb.ebx.r.h;
ep->configMinor = bb.ebx.r.l;
ep->checksum = bb.ecx.rr;
ep->numFunctions = bb.edx.r.h;
ep->u_resources.d = bb.edx.r.l;
u.data[0] = bb.edi.r.l;
u.data[1] = bb.edi.r.h;
u.data[2] = bb.esi.r.l;
u.data[3] = bb.esi.r.h;
ep->id[0] = u.s.char1 + ('A' - 1);
ep->id[1] = (u.s.char2l | (u.s.char2h << 3)) + ('A' - 1);
ep->id[2] = u.s.char3 + ('A' - 1);
ep->id[3] = hex[u.s.d1];
ep->id[4] = hex[u.s.d2];
ep->id[5] = hex[u.s.d3];
ep->id[6] = hex[u.s.d4];
ep->id[7] = 0;
return 0;
}
/*
int
ReadEISAFuncInfo(EISA_func_info_t *ep, int slot, int function)
{
bb.intno = 0x15;
bb.eax.r.h = 0xd8;
bb.eax.r.l = 0x01;
bb.ecx.r.l = slot;
bb.ecx.r.h = function;
bb.esi.rr = (unsigned int)ep->data;
bios(&bb);
if (bb.eax.r.h == 0) {
ep->slot = slot;
ep->function = function;
}
return bb.eax.r.h;
bb.intno = 0x15;
bb.eax.r.h = 0xd8;
bb.eax.r.l = 0x01;
bb.ecx.r.l = slot;
bb.ecx.r.h = function;
bb.esi.rr = (unsigned int)ep->data;
bios(&bb);
if (bb.eax.r.h == 0)
{
ep->slot = slot;
ep->function = function;
}
return bb.eax.r.h;
}
#endif /* EISA_SUPPORT */
int
ReadPCIBusInfo(PCI_bus_info_t *pp)
{
bb.intno = 0x1a;
bb.eax.r.h = 0xb1;
bb.eax.r.l = 0x01;
bios(&bb);
if ((bb.eax.r.h == 0) && (bb.edx.rx == PCI_SIGNATURE)) {
pp->BIOSPresent = 1;
pp->u_bus.d = bb.eax.r.l;
pp->majorVersion = bb.ebx.r.h;
pp->minorVersion = bb.ebx.r.l;
pp->maxBusNum = bb.ecx.r.l;
return 0;
}
return -1;
bb.intno = 0x1a;
bb.eax.r.h = 0xb1;
bb.eax.r.l = 0x01;
bios(&bb);
if ((bb.eax.r.h == 0) && (bb.edx.rx == PCI_SIGNATURE))
{
pp->BIOSPresent = 1;
pp->u_bus.d = bb.eax.r.l;
pp->majorVersion = bb.ebx.r.h;
pp->minorVersion = bb.ebx.r.l;
pp->maxBusNum = bb.ecx.r.l;
return 0;
}
return -1;
}
void sleep(int n)
while (time18() < endtime);
}
//==============================================================================
void delay(int ms)
{
bb.intno = 0x15;
branches/ErmaC/Trunk/i386/libsaio/saio_types.h
7272
7373
7474
75
75
7676
7777
7878
......
110110
111111
112112
113
114
113
114
115115
116116
117117
......
136136
137137
138138
139
139140
140141
141142
142143
143144
144
145
146
145147
146148
147149
......
159161
160162
161163
162
163
164
165
164
165
166
167
166168
167169
168170
......
177179
178180
179181
180
182
181183
182184
183185
......
204206
205207
206208
207
208
209
210
209211
210212
211213
typedef struct
{
charplist[16384];// buffer for plist
TagPtrdictionary;// buffer for xml dictionary
TagPtrdictionary; // buffer for xml dictionary
boolcanOverride;// flag to mark a dictionary can be overriden
} config_file_t;
unsigned short control_port_base;
unsigned char head_flags;
unsigned char vendor_info;
unsigned char irq : 4;
unsigned char irq_unused : 4;
unsigned char irq : 4;
unsigned char irq_unused : 4;
unsigned char block_count;
unsigned char dma_channel : 4;
unsigned char dma_type : 4;
int valid;
};
typedef struct FinderInfo
{
unsigned char data[16];
} FinderInfo;
structBootVolume;
structBootVolume;
typedef struct BootVolume * BVRef;
typedef struct BootVolume * CICell;
struct iob
{
unsigned int i_flgs; /* see F_* below */
unsigned int i_offset; /* seek byte offset in file */
int i_filesize; /* size of file */
char * i_buf; /* file load address */
char * i_buf; /* file load address */
unsigned int i_flgs; /* see F_* below */
unsigned int i_offset; /* seek byte offset in file */
int i_filesize; /* size of file */
};
#define BPS 512/* sector size of the device */
struct dirstuff {
char * dir_path;/* directory path */
long long dir_index;/* directory entry index */
BVRef dir_bvr;/* volume reference */
BVRef dir_bvr; /* volume reference */
};
#define BVSTRLEN 32
char type_name[BVSTRLEN]; /* (type of partition, eg. Apple_HFS) */
BVFree bv_free; /* BVFree function */
uint32_t modTime;
char label[BVSTRLEN]; /* partition volume label */
char altlabel[BVSTRLEN]; /* partition volume label */
char label[BVSTRLEN]; /* partition volume label */
char altlabel[BVSTRLEN]; /* partition volume label */
bool filtered; /* newFilteredBVChain() will set to TRUE */
bool visible; /* will shown in the device list */
char OSVersion[8];
branches/ErmaC/Trunk/i386/libsaio/md5c.c
11
2
2
33
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
432
533
634
......
3563
3664
3765
66
67
3868
3969
4070
4171
4272
4373
44
74
75
76
77
4578
4679
4780
4881
4982
50
83
84
85
5186
5287
53
54
55
56
88
89
90
91
5792
5893
5994
6095
6196
97
6298
6399
64100
65101
66102
103
67104
68105
69106
70107
71108
109
72110
73111
74112
......
79117
80118
81119
82
83
120
84121
85122
86
87123
88124
89
125
90126
91127
92128
......
115151
116152
117153
118
119
154
155
120156
157
158
121159
122160
123161
124162
125163
126
164
165
166
127167
128168
129169
/*
* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
* Copyright (c) 2000-2006 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@
*/
/*
* MD5.C - RSA Data Security, Inc., MD5 message-digest algorithm
*
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
* rights reserved.
*
#define Encode memcpy
#define Decode memcpy
//------------------------------------------------------------------------------
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions. */
//------------------------------------------------------------------------------
// F, G, H and I are basic MD5 functions.
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits. */
//------------------------------------------------------------------------------
// ROTATE_LEFT rotates x left n bits.
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/*
* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
* Rotation is separate from addition to prevent recomputation.
*/
//------------------------------------------------------------------------------
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
// Rotation is separate from addition to prevent recomputation.
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
/* MD5 initialization. Begins an MD5 operation, writing a new context. */
void
MD5Init (context)
void MD5Init (context)
MD5_CTX *context;
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants. */
// Load magic initialization constants.
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((u_int32_t)inputLen << 3))
< ((u_int32_t)inputLen << 3))
if ((context->count[0] += ((u_int32_t)inputLen << 3)) < ((u_int32_t)inputLen << 3))
{
context->count[1]++;
}
context->count[1] += ((u_int32_t)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible. */
if (inputLen >= partLen) {
if (inputLen >= partLen)
{
memcpy((void *)&context->buffer[index], (const void *)input,
partLen);
MD5Transform (context->state, context->buffer);
branches/ErmaC/Trunk/i386/libsaio/fake_efi.c
7373
7474
7575
76
76
7777
7878
7979
*/
/* Identify ourselves as the EFI firmware vendor */
static EFI_CHAR16 const FIRMWARE_VENDOR[] = {'.',':','E','r','m','a','C',':','.','_','1','.','0', 0};
static EFI_CHAR16 const FIRMWARE_VENDOR[] = { 'A', 'p', 'p', 'l', 'e', '\0' };
static EFI_UINT32 const FIRMWARE_REVISION = 132; /* FIXME: Find a constant for this. */
/* Default platform system_id (fix by IntVar) */
branches/ErmaC/Trunk/i386/boot2/drivers.c
112112
113113
114114
115
115
116116
117117
118118
......
120120
121121
122122
123
123
124124
125125
126126
......
656656
657657
658658
659
659
660
660661
661662
662663
......
665666
666667
667668
669
668670
669671
670672
673
671674
672675
673676
677
674678
675679
676680
681
677682
678683
679684
......
703708
704709
705710
706
707
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
708727
709
710
711
712
713
714
715
716
717
718
728
719729
720730
721731
......
743753
744754
745755
746
756
747757
748758
749759
750
751
752
760
761
762
753763
754764
755765
756766
757767
758
768
759769
760770
761771
......
798808
799809
800810
801
811
802812
803813
804814
static char * gFileName;
/*static*/ unsigned long
Adler32( unsigned char * buffer, long length )
Adler32(unsigned char * buffer, long length)
{
long cnt;
unsigned long result, lowHalf, highHalf;
lowHalf = 1;
highHalf = 0;
for ( cnt = 0; cnt < length; cnt++ )
for (cnt = 0; cnt < length; cnt++)
{
if ((cnt % 5000) == 0)
{
ModulePtr module, module2;
long done;
do {
do
{
done = 1;
module = gModuleHead;
if (module->willLoad == 1)
{
prop = XMLGetProperty(module->dict, kPropOSBundleLibraries);
if (prop != 0)
{
prop = prop->tag;
while (prop != 0)
{
module2 = gModuleHead;
while (module2 != 0)
{
prop2 = XMLGetProperty(module2->dict, kPropCFBundleIdentifier);
if ((prop2 != 0) && (!strcmp(prop->string, prop2->string)))
{
if (module2->willLoad == 0) module2->willLoad = 1;
static ModulePtr
FindModule( char * name )
{
ModulePtr module;
TagPtr prop;
ModulePtr module;
TagPtr prop;
module = gModuleHead;
while (module != 0)
{
prop = GetProperty(module->dict, kPropCFBundleIdentifier);
if ((prop != 0) && !strcmp(name, prop->string))
{
break;
}
module = module->nextModule;
}
module = gModuleHead;
while (module != 0)
{
prop = GetProperty(module->dict, kPropCFBundleIdentifier);
if ((prop != 0) && !strcmp(name, prop->string)) break;
module = module->nextModule;
}
return module;
return module;
}
#endif /* NOTDEF */
XMLFreeTag(moduleDict);
}
if (length == -1) return -1;
required = XMLGetProperty(moduleDict, kPropOSBundleRequired);
if ( (required == 0) ||
(required->type != kTagTypeString) ||
!strcmp(required->string, "Safe Boot"))
if ( (required == 0) || (required->type != kTagTypeString) || !strcmp(required->string, "Safe Boot"))
{
XMLFreeTag(moduleDict);
return -2;
}
tmpModule = malloc(sizeof(Module));
tmpModule = malloc(sizeof(Module));
if (tmpModule == 0)
{
XMLFreeTag(moduleDict);
printf("compressed_size: 0x%x\n", kernel_header->compressed_size);
getchar();
#endif
if (kernel_header->signature == OSSwapBigToHostConstInt32('comp'))
{
if (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss'))
branches/ErmaC/Trunk/i386/boot2/prompt.c
2828
2929
3030
31
31
3232
3333
3434
#include <vers.h>
char bootBanner[] = "\nDarwin/x86 boot v" I386BOOT_VERSION " - Enoch by ErmaC r" I386BOOT_CHAMELEONREVISION "\n"
char bootBanner[] = "\nDarwin/x86 boot v" I386BOOT_VERSION " - Enoch r" I386BOOT_CHAMELEONREVISION "\n"
"Build date: " I386BOOT_BUILDDATE "\n"
"%dMB memory\n";
branches/ErmaC/Trunk/i386/boot2/boot.c
133133
134134
135135
136
136
137137
138138
139139
140140
141
141
142142
143143
144
144
145145
146146
147
147
148148
149149
150
150
151151
152
152
153153
154154
155155
156
156
157157
158
158
159159
160
161
160
161
162
162163
163164
164165
165166
166
167
167168
168169
169170
170171
171172
172173
173
174
174
175
176
175177
176178
177179
178180
179181
180182
181
183
182184
183185
184186
185187
186
188
187189
188190
189191
......
193195
194196
195197
196
198
197199
198
200
199201
200
202
201203
202
204
205
203206
204207
205208
......
223226
224227
225228
226
229
230
227231
228232
229233
230
234
231235
232
233
236
237
234238
235239
236
240
237241
238242
239243
240244
241245
242246
243
247
248
244249
245250
246251
......
286291
287292
288293
289
294
295
290296
291297
292298
......
303309
304310
305311
306
312
313
307314
308315
309316
......
311318
312319
313320
314
321
322
315323
316324
317325
......
321329
322330
323331
324
332
333
325334
326335
327336
......
339348
340349
341350
342
351
352
343353
344354
345355
......
380390
381391
382392
383
393
384394
385395
386396
387
397
388398
389399
390
400
391401
392402
393
403
394404
395
405
396406
397407
398408
......
403413
404414
405415
406
416
407417
408418
409
419
410420
411421
412422
413423
414
424
415425
416426
417
418
427
428
429
419430
420431
421
432
422433
423434
424435
425436
426
437
427438
428439
429
440
430441
431442
432
443
433444
434445
435
446
447
436448
437449
438
450
439451
440452
441453
......
443455
444456
445457
446
458
447459
448460
449
461
462
450463
451464
452
465
453466
454
467
468
455469
456470
457471
458472
459
473
460474
461475
462
476
463477
464
478
465479
466480
467481
......
481495
482496
483497
484
498
485499
486
500
487501
488502
489503
......
493507
494508
495509
496
510
497511
498512
499513
......
501515
502516
503517
504
518
505519
506520
507521
508
522
509523
510524
511525
......
526540
527541
528542
529
543
530544
531
545
532546
533547
534548
......
540554
541555
542556
543
557
544558
545559
546560
547
561
562
548563
549564
550565
551566
552567
553
568
569
554570
555571
556572
557573
558
559
560
574
575
576
577
578
561579
562580
563581
......
565583
566584
567585
568
586
587
569588
570589
571590
572591
573592
574593
575
594
595
576596
577597
578
579
598
599
600
580601
581602
582603
583
584
604
605
606
585607
586608
587609
588610
589
611
590612
591613
592614
593615
594616
595
617
596618
597619
598620
599
621
600622
601623
602
603
604
624
625
626
627
605628
606629
607
630
608631
609632
610633
......
626649
627650
628651
629
652
653
630654
631655
632656
......
637661
638662
639663
640
664
665
641666
642667
643668
644669
645670
646
671
672
647673
648674
649675
......
676702
677703
678704
679
705
706
680707
681708
682709
......
690717
691718
692719
693
720
721
694722
695723
696724
697
725
698726
699727
700728
......
703731
704732
705733
706
734
707735
708
736
709737
710738
711739
712740
713
714
741
742
743
715744
716745
717
718
746
747
748
719749
720750
721751
......
731761
732762
733763
734
764
765
735766
736767
737768
738769
739
770
771
740772
741773
742774
......
793825
794826
795827
796
828
829
797830
798831
799832
800833
801
834
835
802836
803837
804838
bootArgs->kaddr = bootArgs->ksize = 0;
execute_hook("ExecKernel", (void*)binary, NULL, NULL, NULL);
ret = DecodeKernel(binary,
&kernelEntry,
(char **) &bootArgs->kaddr,
(int *)&bootArgs->ksize );
if ( ret != 0 )
return ret;
// Reserve space for boot args
reserveKernBootStruct();
// Notify modules that the kernel has been decoded
execute_hook("DecodedKernel", (void*)binary, NULL, NULL, NULL);
setupFakeEfi();
// Load boot drivers from the specifed root path.
//if (!gHaveKernelCache)
LoadDrivers("/");
execute_hook("DriversLoaded", (void*)binary, NULL, NULL, NULL);
clearActivityIndicator();
if (gErrors) {
if (gErrors)
{
printf("Errors encountered while starting up the computer.\n");
printf("Pausing %d seconds...\n", kBootErrorTimeout);
sleep(kBootErrorTimeout);
}
md0Ramdisk();
verbose("Starting Darwin %s\n",( archCpuType == CPU_TYPE_I386 ) ? "x86" : "x86_64");
verbose("Boot Args: %s\n", bootArgs->CommandLine);
// Cleanup the PXE base code.
if ( (gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit ) {
if ( (gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit )
{
if ( (ret = nbpUnloadBaseCode()) != nbpStatusSuccess )
{
printf("nbpUnloadBaseCode error %d\n", (int) ret);
sleep(2);
}
}
bool dummyVal;
if (getBoolForKey(kWaitForKeypressKey, &dummyVal, &bootInfo->chameleonConfig) && dummyVal) {
showTextBuffer(msgbuf, strlen(msgbuf));
}
usb_loop();
// If we were in text mode, switch to graphics mode.
setVideoMode( GRAPHICS_MODE, 0 );
else
drawBootGraphics();
setupBooterLog();
finalizeBootStruct();
// Jump to kernel's entry point. There's no going back now.
if ((checkOSVersion("10.7")) || (checkOSVersion("10.8"))) {
if ((checkOSVersion("10.7")) || (checkOSVersion("10.8")))
{
// Notify modules that the kernel is about to be started
execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgs, NULL, NULL);
//==========================================================================
// LoadKernelCache - Try to load Kernel Cache.
// return the length of the loaded cache file or -1 on error
long LoadKernelCache(const char* cacheFile, void **binary) {
long LoadKernelCache(const char* cacheFile, void **binary)
{
charkernelCacheFile[512];
charkernelCachePath[512];
longflags, time, cachetime, kerneltime, exttime, ret=-1;
unsigned long adler32;
unsigned long adler32;
if((gBootMode & kBootModeSafe) != 0)
{
if((gBootMode & kBootModeSafe) != 0)
{
verbose("Kernel Cache ignored.\n");
return -1;
}
}
// Use specify kernel cache file if not empty
if (cacheFile[0] != 0)
strlcpy(kernelCacheFile, cacheFile, sizeof(kernelCacheFile));
else {
// Lion and Mountain Lion prelink kernel cache file
if ((checkOSVersion("10.7")) || (checkOSVersion("10.8"))) {
if ((checkOSVersion("10.7")) || (checkOSVersion("10.8")))
{
sprintf(kernelCacheFile, "%skernelcache", kDefaultCachePathSnow);
}
// Snow Leopard prelink kernel cache file
ret = -1;
// If boot from a boot helper partition check the kernel cache file on it
if (gBootVolume->flags & kBVFlagBooter) {
if (gBootVolume->flags & kBVFlagBooter)
{
sprintf(kernelCachePath, "com.apple.boot.P%s", kernelCacheFile);
ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime);
if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat))
}
}
// If not found, use the original kernel cache path.
if (ret == -1) {
if (ret == -1)
{
strcpy(kernelCachePath, kernelCacheFile);
ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime);
if ((flags & kFileTypeMask) != kFileTypeFlat)
}
// Exit if kernel cache file wasn't found
if (ret == -1) {
if (ret == -1)
{
verbose("No Kernel Cache File '%s' found\n", kernelCacheFile);
return -1;
}
ret = GetFileInfo(NULL, bootInfo->bootFile, &flags, &kerneltime);
// Check if the kernel file is more recent than the cache file
if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat)
&& (kerneltime > cachetime)) {
&& (kerneltime > cachetime))
{
verbose("Kernel file (%s) is more recent than KernelCache (%s), ignoring KernelCache\n",
bootInfo->bootFile, kernelCacheFile);
return -1;
// Since the kernel cache file exists and is the most recent try to load it
verbose("Loading kernel cache %s\n", kernelCachePath);
if ((checkOSVersion("10.7")) || (checkOSVersion("10.8"))) {
if ((checkOSVersion("10.7")) || (checkOSVersion("10.8")))
{
ret = LoadThinFatFile(kernelCachePath, binary);
} else {
ret = LoadFile(kernelCachePath);
intstatus;
unsigned intallowBVFlags = kBVFlagSystemVolume | kBVFlagForeignBoot;
unsigned intdenyBVFlags = kBVFlagEFISystem;
// Set reminder to unload the PXE base code. Neglect to unload
// the base code will result in a hang or kernel panic.
gUnloadPXEOnExit = true;
// Record the device that the booter was loaded from.
gBIOSDev = biosdev & kBIOSDevMask;
// Initialize boot info structure.
initKernBootStruct();
initBooterLog();
// Setup VGA text mode.
// Not sure if it is safe to call setVideoMode() before the
// config table has been loaded. Call video_mode() instead.
#if DEBUG
printf("after video_mode\n");
#endif
// Scan and record the system's hardware information.
scan_platform();
// First get info for boot volume.
scanBootVolumes(gBIOSDev, 0);
bvChain = getBVChainForBIOSDev(gBIOSDev);
setBootGlobals(bvChain);
// Load boot.plist config file
status = loadChameleonConfig(&bootInfo->chameleonConfig);
if (getBoolForKey(kQuietBootKey, &quiet, &bootInfo->chameleonConfig) && quiet) {
if (getBoolForKey(kQuietBootKey, &quiet, &bootInfo->chameleonConfig) && quiet)
{
gBootMode |= kBootModeQuiet;
}
// Override firstRun to get to the boot menu instantly by setting "Instant Menu"=y in system config
if (getBoolForKey(kInstantMenuKey, &instantMenu, &bootInfo->chameleonConfig) && instantMenu) {
firstRun = false;
}
// Loading preboot ramdisk if exists.
loadPrebootRAMDisk();
// Disable rescan option by default
gEnableCDROMRescan = false;
// Enable it with Rescan=y in system config
if (getBoolForKey(kRescanKey, &gEnableCDROMRescan, &bootInfo->chameleonConfig)
&& gEnableCDROMRescan) {
&& gEnableCDROMRescan)
{
gEnableCDROMRescan = true;
}
// Ask the user for Rescan option by setting "Rescan Prompt"=y in system config.
rescanPrompt = false;
if (getBoolForKey(kRescanPromptKey, &rescanPrompt , &bootInfo->chameleonConfig)
{
gEnableCDROMRescan = promptForRescanOption();
}
// Enable touching a single BIOS device only if "Scan Single Drive"=y is set in system config.
if (getBoolForKey(kScanSingleDriveKey, &gScanSingleDrive, &bootInfo->chameleonConfig)
&& gScanSingleDrive) {
&& gScanSingleDrive)
{
gScanSingleDrive = true;
}
// Create a list of partitions on device(s).
if (gScanSingleDrive) {
if (gScanSingleDrive)
{
scanBootVolumes(gBIOSDev, &bvCount);
} else {
scanDisks(gBIOSDev, &bvCount);
}
// Create a separated bvr chain using the specified filters.
bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount);
gBootVolume = selectBootVolume(bvChain);
// Intialize module system
init_module_system();
// initGUI() returned with an error, disabling GUI.
useGUI = false;
}
setBootGlobals(bvChain);
// Parse args, load and start kernel.
while (1)
{
intlen, ret = -1;
longflags, sleeptime, time;
void*binary = (void *)kLoadAddr;
char bootFile[sizeof(bootInfo->bootFile)];
charbootFilePath[512];
charkernelCacheFile[512];
// Initialize globals.
sysConfigValid = false;
gErrors = false;
status = getBootOptions(firstRun);
firstRun = false;
if (status == -1) continue;
status = processBootOptions();
// Status == 1 means to chainboot
if ( status ==1 ) break;
}
continue;
}
// Other status (e.g. 0) means that we should proceed with boot.
// Turn off any GUI elements
if ( bootArgs->Video.v_display == GRAPHICS_MODE )
{
drawBackground();
updateVRAM();
}
// Find out which version mac os we're booting.
getOSVersion();
if (platformCPUFeature(CPU_FEATURE_EM64T)) {
if (platformCPUFeature(CPU_FEATURE_EM64T))
{
archCpuType = CPU_TYPE_X86_64;
} else {
archCpuType = CPU_TYPE_I386;
}
if (getValueForKey(karch, &val, &len, &bootInfo->chameleonConfig)) {
if (getValueForKey(karch, &val, &len, &bootInfo->chameleonConfig))
{
if (strncmp(val, "i386", 4) == 0) {
archCpuType = CPU_TYPE_I386;
}
}
if (getValueForKey(kKernelArchKey, &val, &len, &bootInfo->chameleonConfig)) {
if (strncmp(val, "i386", 4) == 0) {
if (getValueForKey(kKernelArchKey, &val, &len, &bootInfo->chameleonConfig))
{
if (strncmp(val, "i386", 4) == 0)
{
archCpuType = CPU_TYPE_I386;
}
}
// Notify modules that we are attempting to boot
execute_hook("PreBoot", NULL, NULL, NULL, NULL);
if (!getBoolForKey (kWake, &tryresume, &bootInfo->chameleonConfig)) {
if (!getBoolForKey (kWake, &tryresume, &bootInfo->chameleonConfig))
{
tryresume = true;
tryresumedefault = true;
} else {
tryresumedefault = false;
}
if (!getBoolForKey (kForceWake, &forceresume, &bootInfo->chameleonConfig)) {
if (!getBoolForKey (kForceWake, &forceresume, &bootInfo->chameleonConfig))
{
forceresume = false;
}
if (forceresume) {
if (forceresume)
{
tryresume = true;
tryresumedefault = false;
}
while (tryresume) {
while (tryresume)
{
const char *tmp;
BVRef bvr;
if (!getValueForKey(kWakeImage, &val, &len, &bootInfo->chameleonConfig))
val = "/private/var/vm/sleepimage";
// Do this first to be sure that root volume is mounted
ret = GetFileInfo(0, val, &flags, &sleeptime);
if ((bvr = getBootVolumeRef(val, &tmp)) == NULL)
break;
// Can't check if it was hibernation Wake=y is required
if (bvr->modTime == 0 && tryresumedefault)
break;
if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat))
break;
if (!forceresume && ((sleeptime+3)<bvr->modTime)) {
#if DEBUG
if (!forceresume && ((sleeptime+3)<bvr->modTime))
{
#if DEBUG
printf ("Hibernate image is too old by %d seconds. Use ForceWake=y to override\n",
bvr->modTime-sleeptime);
#endif
#endif
break;
}
if (useKernelCache) do {
// Determine the name of the Kernel Cache
if (getValueForKey(kKernelCacheKey, &val, &len, &bootInfo->bootConfig)) {
if (getValueForKey(kKernelCacheKey, &val, &len, &bootInfo->bootConfig))
{
if (val[0] == '\\')
{
len--;
kernelCacheFile[0] = 0; // Use default kernel cache file
}
if (gOverrideKernel && kernelCacheFile[0] == 0) {
if (gOverrideKernel && kernelCacheFile[0] == 0)
{
verbose("Using a non default kernel (%s) without specifying 'Kernel Cache' path, KernelCache will not be used\n",
bootInfo->bootFile);
useKernelCache = false;
break;
}
if (gMKextName[0] != 0) {
if (gMKextName[0] != 0)
{
verbose("Using a specific MKext Cache (%s), KernelCache will not be used\n",
gMKextName);
useKernelCache = false;
// Try to load kernel image from alternate locations on boot helper partitions.
ret = -1;
if ((gBootVolume->flags & kBVFlagBooter) && !bootFileWithDevice) {
if ((gBootVolume->flags & kBVFlagBooter) && !bootFileWithDevice)
{
sprintf(bootFilePath, "com.apple.boot.P%s", bootFile);
ret = GetFileInfo(NULL, bootFilePath, &flags, &time);
if (ret == -1)
}
}
}
if (ret == -1) {
if (ret == -1)
{
// No alternate location found, using the original kernel image path.
strlcpy(bootFilePath, bootFile,sizeof(bootFilePath));
}
verbose("Loading kernel %s\n", bootFilePath);
ret = LoadThinFatFile(bootFilePath, &binary);
if (ret <= 0 && archCpuType == CPU_TYPE_X86_64)
ret = LoadThinFatFile(bootFilePath, &binary);
}
} while (0);
clearActivityIndicator();
#if DEBUG
printf("Pausing...");
sleep(8);
#endif
if (ret <= 0) {
if (ret <= 0)
{
printf("Can't find %s\n", bootFile);
sleep(1);
if (gBootFileType == kNetworkDeviceType) {
if (gBootFileType == kNetworkDeviceType)
{
// Return control back to PXE. Don't unload PXE base code.
gUnloadPXEOnExit = false;
break;
// chainboot
if (status == 1) {
// if we are already in graphics-mode,
if (getVideoMode() == GRAPHICS_MODE) {
if (getVideoMode() == GRAPHICS_MODE)
{
setVideoMode(VGA_TEXT_MODE, 0); // switch back to text mode.
}
}
if ((gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit) {
if ((gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit)
{
nbpUnloadBaseCode();
}
}
while (len > 0) {
k = len < NMAX ? len : NMAX;
len -= k;
while (k >= 16) {
while (k >= 16)
{
DO16(buf);
buf += 16;
k -= 16;
}
if (k != 0) do {
if (k != 0) do
{
s1 += *buf++;
s2 += s1;
} while (--k);
branches/ErmaC/Trunk/i386/boot2/boot2.s
6464
6565
6666
67
67
6868
6969
7070
#
# Returns:
#
LABEL(boot2)
LABEL(boot2) # Entry point at 0:BOOTER_ADDR (will be called by boot1)
pushl %ecx # Save general purpose registers
pushl %ebx
pushl %ebp
branches/ErmaC/Trunk/i386/boot2/boot.h
2222
2323
2424
25
26
25
2726
2827
2928
......
182181
183182
184183
185
186
184
187185
188186
189187
......
206204
207205
208206
209
210
211
212
213
207
208
209
210
211
212
214213
215214
216215
......
282281
283282
284283
285
286
287
284
285
286
287
288288
289289
290290
......
292292
293293
294294
295
296
297
298
299
300
301
302
303
304
295
296
297
298
299
300
301
302
303
304
305
305306
306307
307308
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Copyright 1994 NeXT Computer, Inc.
* All rights reserved.
* Copyright 1994 NeXT Computer, Inc. All rights reserved.
*/
#ifndef __BOOT2_BOOT_H
#define kCDBootTimeout 8
/*
* A global set by boot() to record the device that the booter
* was loaded from.
* A global set by boot() to record the device that the booter was loaded from.
*/
#define ROOT_DEVICE_SIZE 512
extern int gBIOSDev;
/*
* Boot Modes
*/
enum {
kBootModeNormal = 0,
kBootModeSafe = 1,
kBootModeSecure = 2,
kBootModeQuiet = 4
enum
{
kBootModeNormal = 0,
kBootModeSafe = 1,
kBootModeSecure = 2,
kBootModeQuiet = 4
};
extern void initialize_runtime();
void showTextFile();
char *getMemoryInfoString();
typedef struct {
char name[80];
void * param;
typedef struct
{
char name[80];
void * param;
} MenuItem;
/*
*/
extern int decompress_lzss(u_int8_t *dst, u_int8_t *src, u_int32_t srclen);
struct compressed_kernel_header {
u_int32_t signature;
u_int32_t compress_type;
u_int32_t adler32;
u_int32_t uncompressed_size;
u_int32_t compressed_size;
u_int32_t reserved[11];
char platform_name[64];
char root_path[256];
u_int8_t data[0];
struct compressed_kernel_header
{
u_int32_t signature;
u_int32_t compress_type;
u_int32_t adler32;
u_int32_t uncompressed_size;
u_int32_t compressed_size;
u_int32_t reserved[11];
char platform_name[64];
char root_path[256];
u_int8_t data[0];
};
typedef struct compressed_kernel_header compressed_kernel_header;
branches/ErmaC/Trunk/i386/boot2/lzss.c
4242
4343
4444
45
46
47
48
49
45
46
47
48
49
50
5051
51
52
52
53
54
55
56
5357
54
55
56
57
58
59
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
60104
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
105
91106
#include <sl.h>
#define N 4096 /* size of ring buffer - must be power of 2 */
#define F 18 /* upper limit for match_length */
#define THRESHOLD 2 /* encode string into position and length
if match_length is greater than this */
//#define NIL N /* index for root of binary search trees */
#define N4096/* Size of ring buffer - must be power of 2. */
#define N_MIN_14095
#define F18/* Upper limit for match_length. */
#define RN - F
#define THRESHOLD2/* Encode string into position and length if match_length is greater than this. */
#define NILN/* Index for root of binary search trees. */
int
decompress_lzss(u_int8_t *dst, u_int8_t *src, u_int32_t srclen)
//==============================================================================
// Refactoring and bug fix Copyright (c) 2010 by DHP.
int decompress_lzss(u_int8_t * dst, u_int8_t * src, u_int32_t srclen)
{
/* ring buffer of size N, with extra F-1 bytes to aid string comparison */
u_int8_t text_buf[N + F - 1];
u_int8_t *dststart = dst;
u_int8_t *srcend = src + srclen;
int i, j, k, r, c;
unsigned int flags;
/* Four KB ring buffer with 17 extra bytes added to aid string comparisons. */
u_int8_t text_buf[N_MIN_1 + F];
u_int8_t * dststart = dst;
const u_int8_t * srcend = (src + srclen);
int r = R;
int i, j, k, c;
unsigned int flags = 0;
for (i = 0; i < R; i++)
{
text_buf[i] = ' ';
}
while (src < srcend)
{
if (((flags >>= 1) & 0x100) == 0)
{
c = *src++;
flags = c | 0xFF00; // Clever use of the high byte.
}
if ((src < srcend) && (flags & 1))
{
c = *src++;
*dst++ = c;
text_buf[r++] = c;
r &= N_MIN_1;
}
else if ((src + 2) <= srcend)
{
i = *src++;
j = *src++;
i |= ((j & 0xF0) << 4);
j = (j & 0x0F) + THRESHOLD;
for (k = 0; k <= j; k++)
{
c = text_buf[(i + k) & N_MIN_1];
*dst++ = c;
text_buf[r++] = c;
r &= N_MIN_1;
}
}
}
dst = dststart;
for (i = 0; i < N - F; i++)
text_buf[i] = ' ';
r = N - F;
flags = 0;
for ( ; ; ) {
if (((flags >>= 1) & 0x100) == 0) {
if (src < srcend) c = *src++; else break;
flags = c | 0xFF00; /* uses higher byte cleverly */
} /* to count eight */
if (flags & 1) {
if (src < srcend) c = *src++; else break;
*dst++ = c;
text_buf[r++] = c;
r &= (N - 1);
} else {
if (src < srcend) i = *src++; else break;
if (src < srcend) j = *src++; else break;
i |= ((j & 0xF0) << 4);
j = (j & 0x0F) + THRESHOLD;
for (k = 0; k <= j; k++) {
c = text_buf[(i + k) & (N - 1)];
*dst++ = c;
text_buf[r++] = c;
r &= (N - 1);
}
}
}
return dst - dststart;
return dst - dststart;
}
branches/ErmaC/Trunk/i386/boot2/options.c
10691069
10701070
10711071
1072
1073
1072
1073
10741074
1075
1076
1077
1078
1079
1080
10751081
1082
1083
1084
1085
1086
10761087
1088
10771089
1078
1079
1080
1081
1090
1091
1092
1093
1094
10821095
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1096
10971097
10981098
10991099
bool copyArgument(const char *argName, const char *val, int cnt, char **argP, int *cntRemainingP)
{
int argLen = argName ? strlen(argName) : 0;
int len = argLen + cnt + 1; // +1 to account for space
int argLen = argName ? strlen(argName) : 0;
int len = argLen + cnt + 1; // + 1 to account for space.
if (len > *cntRemainingP)
{
error("Warning: boot arguments too long, truncating\n");
return false;
}
if (argName)
{
strncpy(*argP, argName, argLen);
*argP += argLen;
*argP[0] = '=';
(*argP)++;
len++; // +1 to account for '='
}
if (len > *cntRemainingP) {
error("Warning: boot arguments too long, truncating\n");
return false;
}
strncpy(*argP, val, cnt);
*argP += cnt;
*argP[0] = ' ';
(*argP)++;
*cntRemainingP -= len;
if (argName) {
strncpy( *argP, argName, argLen );
*argP += argLen;
*argP[0] = '=';
(*argP)++;
}
strncpy( *argP, val, cnt );
*argP += cnt;
*argP[0] = ' ';
(*argP)++;
*cntRemainingP -= len;
return true;
return true;
}
//
branches/ErmaC/Trunk/i386/libsa/libsa.h
128128
129129
130130
131
132
131
133132
134133
135134
......
140139
141140
142141
143
142
144143
145144
146145
......
149148
150149
151150
152
153
151
154152
155153
/*
* prf.c
*/
extern void prf(const char * fmt, va_list ap, int (*putfn_p)(),
void * putfn_arg);
extern void prf(const char * fmt, va_list ap, int (*putfn_p)(), void * putfn_arg);
/*
* printf.c
/*
* zalloc.c
*/
#define malloc(size)safe_malloc(size, __FILE__, __LINE__)
#define malloc(size) safe_malloc(size, __FILE__, __LINE__)
extern void malloc_init(char * start, int size, int nodes, void (*malloc_error)(char *, size_t, const char *, int));
extern void * safe_malloc(size_t size,const char *file, int line);
extern void free(void * start);
/*
* getsegbyname.c
*/
extern struct segment_command *
getsegbynamefromheader(struct mach_header * mhp, char * segname);
extern struct segment_command * getsegbynamefromheader(struct mach_header * mhp, char * segname);
#endif /* !__BOOT_LIBSA_H */
branches/ErmaC/Trunk/i386/libsa/printf.c
3434
3535
3636
37
38
37
3938
4039
41
42
43
40
41
42
43
4444
45
46
45
46
4747
4848
4949
char * last_str;
};
static int
sputc(int c, struct putc_info * pi) //Azi: same as above
static int sputc(int c, struct putc_info * pi) //Azi: same as above
{
if (pi->last_str)
if (pi->str == pi->last_str) {
*(pi->str) = '\0';
return 0;
if (pi->str == pi->last_str)
{
*(pi->str) = '\0';
return 0;
}
*(pi->str)++ = c;
return c;
*(pi->str)++ = c;
return c;
}
/*VARARGS1*/
branches/ErmaC/Trunk/i386/libsa/zalloc.c
4949
5050
5151
52
52
5353
5454
5555
......
7777
7878
7979
80
80
81
82
83
84
85
8186
82
87
8388
8489
85
90
8691
8792
8893
......
9196
9297
9398
94
95
99
100
96101
97102
98103
......
104109
105110
106111
107
108
112
113
114
109115
110116
111
112
117
118
113119
114120
115121
116122
117123
118124
119
125
120126
121127
122128
123129
124130
125131
126
127
128
129
130
131
132
133
134
135
136
132
133
134
135
136
137
138
139
140
137141
138
142
139143
140144
141145
......
143147
144148
145149
146
150
147151
148
149
150
151
152
153
152
153
154
155
156
157
154158
155159
156160
157161
158
162
159163
160
164
165
161166
162
167
163168
164
169
165170
166
171
167172
168173
169174
170175
171176
172177
173
178
174179
175
180
176181
177182
178183
179
180
181
184
185
186
182187
183
188
184189
185190
186191
187192
188
193
194
189195
190196
191197
192
198
193199
194200
195201
196202
197
203
198204
199205
200206
201207
202
208
203209
204210
205211
206212
207
208
209
210
213
214
215
216
217
218
211219
212220
213221
......
222230
223231
224232
225
226
233
227234
228235
229236
......
232239
233240
234241
235
236
237
242
243
244
245
238246
239247
240248
......
242250
243251
244252
245
246
247
253
254
255
256
248257
249258
250259
260
251261
252262
253263
254
255
264
256265
266
257267
258268
259269
260270
271
261272
262273
263
264
265
274
275
276
277
278
266279
267280
268
269
281
270282
271283
272284
......
277289
278290
279291
280
292
281293
282294
283295
284
285
296
286297
287298
288299
......
290301
291302
292303
293
304
294305
295
306
296307
297308
298309
299
300
310
301311
302312
303313
304314
305315
306
307
316
308317
309
310
318
319
311320
312321
313322
static short availableNodes, allocedNodes, totalNodes;
static char * zalloc_base;
static char * zalloc_end;
static void (*zerror)(char *, size_t, const char *, int);
static void (*zerror)(char *, size_t, const char *, int);
static void zallocate(char * start,int size);
static void zinsert(zmem * zp, int ndx);
zalloced = (zmem *) zalloc_base;
zavailable = (zmem *) zalloc_base + sizeof(zmem) * totalNodes;
zavailable[0].start = (char *)zavailable + sizeof(zmem) * totalNodes;
if (size == 0) size = ZALLOC_LEN;
if (size == 0)
{
size = ZALLOC_LEN;
}
zavailable[0].size = size - (zavailable[0].start - zalloc_base);
zalloc_end = zalloc_base + size;
zalloc_end = zalloc_base + size;
availableNodes = 1;
allocedNodes = 0;
zerror = malloc_err_fn ? malloc_err_fn : malloc_error;
zerror = malloc_err_fn ? malloc_err_fn : malloc_error;
}
#define BEST_FIT 1
{
int i;
#if BEST_FIT
int bestFit;
size_t smallestSize;
int bestFit;
size_t smallestSize;
#endif
char * ret = 0;
size = ((size + 0xf) & ~0xf);
if (size == 0) {
if (zerror) (*zerror)((char *)0xdeadbeef, 0, file, line);
if (size == 0)
{
if (zerror) (*zerror)((char *)0xdeadbeef, 0, file, line);
}
#if BEST_FIT
smallestSize = 0;
bestFit = -1;
smallestSize = 0;
bestFit = -1;
#endif
for (i = 0; i < availableNodes; i++)
{
// find node with equal size, or if not found,
// then smallest node that fits.
if ( zavailable[i].size == size )
if (zavailable[i].size == size)
{
zallocate(ret = zavailable[i].start, size);
zdelete(zavailable, i); availableNodes--;
goto done;
}
#if BEST_FIT
else
{
if ((zavailable[i].size > size) &&
((smallestSize == 0) ||
(zavailable[i].size < smallestSize)))
{
bestFit = i;
smallestSize = zavailable[i].size;
}
}
else
{
if ((zavailable[i].size > size) && ((smallestSize == 0) || (zavailable[i].size < smallestSize)))
{
bestFit = i;
smallestSize = zavailable[i].size;
}
}
#else
else if ( zavailable[i].size > size )
else if (zavailable[i].size > size)
{
zallocate(ret = zavailable[i].start, size);
zavailable[i].start += size;
goto done;
}
#endif
}
}
#if BEST_FIT
if (bestFit != -1)
{
zallocate(ret = zavailable[bestFit].start, size);
zavailable[bestFit].start += size;
zavailable[bestFit].size -= size;
}
if (bestFit != -1)
{
zallocate(ret = zavailable[bestFit].start, size);
zavailable[bestFit].start += size;
zavailable[bestFit].size -= size;
}
#endif
done:
if ((ret == 0) || (ret + size >= zalloc_end))
{
{
if (zerror) (*zerror)(ret, size, file, line);
}
}
if (ret != 0)
{
{
bzero(ret, size);
}
}
#if ZDEBUG
zalloced_size += size;
zalloced_size += size;
#endif
return (void *) ret;
}
void free(void * pointer)
{
unsigned long rp;
unsigned long rp;
int i, found = 0;
size_t tsize = 0;
size_t tsize = 0;
char * start = pointer;
#if i386
// Get return address of our caller,
// in case we have to report an error below.
asm volatile ("movl %%esp, %%eax\n\t"
// Get return address of our caller,
// in case we have to report an error below.
asm volatile ("movl %%esp, %%eax\n\t"
"subl $4, %%eax\n\t"
"movl 0(%%eax), %%eax" : "=a" (rp) );
"movl 0(%%eax), %%eax" : "=a" (rp));
#else
rp = 0;
#endif
if ( !start ) return;
if (!start)
return;
for (i = 0; i < allocedNodes; i++)
{
if ( zalloced[i].start == start )
if (zalloced[i].start == start)
{
tsize = zalloced[i].size;
#if ZDEBUG
zout -= tsize;
printf(" zz out %d\n",zout);
printf(" zz out %d\n", zout);
#endif
zdelete(zalloced, i); allocedNodes--;
found = 1;
#if ZDEBUG
memset(pointer, 0x5A, tsize);
memset(pointer, 0x5A, tsize);
#endif
break;
}
}
if ( !found ) {
if (zerror) (*zerror)(pointer, rp, "free", 0);
else return;
}
if (!found)
{
if (zerror) (*zerror)(pointer, rp, "free", 0);
else
return;
}
#if ZDEBUG
zalloced_size -= tsize;
#endif
return;
}
if ((i > 0) &&
(zavailable[i-1].start + zavailable[i-1].size == start))
if ((i > 0) && (zavailable[i-1].start + zavailable[i-1].size == start))
{
zavailable[i-1].size += tsize;
zcoalesce();
if ((start + tsize) < zavailable[i].start)
{
if (++availableNodes > totalNodes) {
if (zerror) (*zerror)((char *)0xf000f000, 0, "free", 0);
}
if (++availableNodes > totalNodes)
{
if (zerror) (*zerror)((char *)0xf000f000, 0, "free", 0);
}
zinsert(zavailable, i);
zavailable[i].start = start;
zavailable[i].size = tsize;
}
}
if (++availableNodes > totalNodes) {
if (zerror) (*zerror)((char *)0xf000f000, 1, "free", 0);
}
if (++availableNodes > totalNodes)
{
if (zerror) (*zerror)((char *)0xf000f000, 1, "free", 0);
}
zavailable[i].start = start;
zavailable[i].size = tsize;
zcoalesce();
return;
}
static void
zallocate(char * start,int size)
static void zallocate(char * start,int size)
{
#if ZDEBUG
zout += size;
printf(" alloc %d, total 0x%x\n",size,zout);
#endif
zalloced[allocedNodes].start = start;
zalloced[allocedNodes].size = size;
if (++allocedNodes > totalNodes) {
if (zerror) (*zerror)((char *)0xf000f000, 2, "zallocate", 0);
};
if (++allocedNodes > totalNodes)
{
if (zerror) (*zerror)((char *)0xf000f000, 2, "zallocate", 0);
};
}
static void
zinsert(zmem * zp, int ndx)
static void zinsert(zmem * zp, int ndx)
{
int i;
zmem *z1, *z2;
for (; i >= ndx; i--, z1--, z2--)
{
*z2 = *z1;
*z2 = *z1;
}
}
static void
zdelete(zmem * zp, int ndx)
static void zdelete(zmem * zp, int ndx)
{
int i;
zmem *z1, *z2;
z1 = zp + ndx;
z2 = z1 + 1;
for (i = ndx; i < totalNodes-1; i++, z1++, z2++)
for (i = ndx; i < totalNodes - 1; i++, z1++, z2++)
{
*z1 = *z2;
*z1 = *z2;
}
}
static void
zcoalesce(void)
static void zcoalesce(void)
{
int i;
for (i = 0; i < availableNodes-1; i++)
{
if ( zavailable[i].start + zavailable[i].size ==
zavailable[i+1].start )
if ( zavailable[i].start + zavailable[i].size == zavailable[i + 1].start )
{
zavailable[i].size += zavailable[i+1].size;
zdelete(zavailable, i+1); availableNodes--;
zavailable[i].size += zavailable[i + 1].size;
zdelete(zavailable, i + 1); availableNodes--;
return;
}
}
branches/ErmaC/Trunk/i386/libsa/string.c
139139
140140
141141
142
143
142
144143
145144
146145
......
149148
150149
151150
152
153
151
154152
155153
156154
......
168166
169167
170168
171
172
169
173170
174171
175172
......
177174
178175
179176
180
181
177
182178
183179
184180
......
186182
187183
188184
189
190
185
191186
192187
193188
......
210205
211206
212207
213
214
208
215209
216210
217211
......
223217
224218
225219
226
227
220
228221
229222
230223
/*#endif*/
/* NOTE: Moved from ntfs.c */
int
memcmp(const void *p1, const void *p2, size_t len)
int memcmp(const void *p1, const void *p2, size_t len)
{
while (len--) {
if (*(const char*)(p1++) != *(const char*)(p2++))
return 0;
}
int
strcmp(const char * s1, const char * s2)
int strcmp(const char * s1, const char * s2)
{
while (*s1 && (*s1 == *s2)) {
s1++;
return(n<0 ? 0 : *s1 - *--s2);
}
char *
strcpy(char * s1, const char * s2)
char * strcpy(char * s1, const char * s2)
{
register char *ret = s1;
while ((*s1++ = *s2++))
return ret;
}
char *
strncpy(char * s1, const char * s2, size_t n)
char * strncpy(char * s1, const char * s2, size_t n)
{
register char *ret = s1;
while (n && (*s1++ = *s2++))
return ret;
}
char *
strstr(const char *in, const char *str)
char * strstr(const char *in, const char *str)
{
char c;
size_t len;
return (char *) (in - 1);
}
int
ptol(const char *str)
int ptol(const char *str)
{
register int c = *str;
return c;
}
int
atoi(const char *str)
int atoi(const char *str)
{
register int sum = 0;
while (*str == ' ' || *str == '\t')
branches/ErmaC/Trunk/i386/libsa/prf.c
5656
5757
5858
59
60
61
62
63
64
59
60
61
62
63
6564
6665
6766
......
7271
7372
7473
75
74
75
7676
7777
7878
......
9090
9191
9292
93
94
95
96
97
98
93
9994
10095
10196
10297
10398
104
99
105100
106
101
102
107103
104
108105
109
106
107
108
110109
111110
112111
......
121120
122121
123122
124
123
124
125125
126126
127127
......
150150
151151
152152
153
153
154
154155
155156
156157
157158
158159
159160
160
161
161
162
163
164
162165
163166
164167
165168
166169
167
168
170
171
172
173
169174
170175
171176
172177
173178
174179
175
180
181
176182
177183
178184
* Printn prints a number n in base b.
* We don't use recursion to avoid deep kernel stacks.
*/
static void
printn(n, b, flag, minwidth, putfn_p, putfn_arg)
u_long n;
int b, flag, minwidth;
void (*putfn_p)();
void *putfn_arg;
static void printn(n, b, flag, minwidth, putfn_p, putfn_arg)
u_long n;
int b, flag, minwidth;
void (*putfn_p)();
void *putfn_arg;
{
char prbuf[11];
register char *cp;
n = (unsigned)(-(int)n);
}
cp = prbuf;
do {
do
{
*cp++ = "0123456789abcdef0123456789ABCDEF"[(flag & UCASE) + n%b];
n /= b;
width++;
while (cp > prbuf);
}
int prf(
char *fmt,
unsigned int *adx,
void (*putfn_p)(),
void *putfn_arg
)
int prf(char *fmt, unsigned int *adx, void (*putfn_p)(), void *putfn_arg )
{
int b, c, len =0;
char *s;
int flag = 0, width = 0;
int minwidth;
loop:
while ((c = *fmt++) != '%') {
while ((c = *fmt++) != '%')
{
if(c == '\0')
{
return len;
if (putfn_p) {
}
if (putfn_p)
{
(*putfn_p)(c, putfn_arg);
}
len++;
flag |= SPACE;
goto again;
case '0':
if (minwidth == 0) {
if (minwidth == 0)
{
/* this is a flag */
flag |= ZERO;
goto again;
case 'o': case 'O':
b = 8;
number:
if (putfn_p) {
if (putfn_p)
{
printn((u_long)*adx, b, flag, minwidth, putfn_p, putfn_arg);
}
len++;
break;
case 's':
s = (char *)*adx;
while ((c = *s++)) {
if (putfn_p) {
while ((c = *s++))
{
if (putfn_p)
{
(*putfn_p)(c, putfn_arg);
}
len++;
width++;
}
while (width++ < minwidth) {
if (putfn_p) {
while (width++ < minwidth)
{
if (putfn_p)
{
(*putfn_p)(' ', putfn_arg);
}
len++;
}
break;
case 'c':
if (putfn_p) {
if (putfn_p)
{
(*putfn_p)((char)*adx, putfn_arg);
}
len++;
branches/ErmaC/Trunk/i386/libsa/efi_tables.c
129129
130130
131131
132
132
133133
134134
135
135
136
136137
137
138
138139
139140
140141
141142
143
142144
143145
144146
......
154156
155157
156158
157
159
160
158161
159162
160163
161164
162165
166
bool efi_guid_is_null(EFI_GUID const *pGuid)
{
if(pGuid->Data1 == 0 && pGuid->Data2 == 0 && pGuid->Data3 == 0)
if (pGuid->Data1 == 0 && pGuid->Data2 == 0 && pGuid->Data3 == 0)
{
int i;
for(i=0; i<8; ++i)
for (i = 0; i < 8; ++i)
{
if(pGuid->Data4[i] != 0)
if (pGuid->Data4[i] != 0)
return false;
}
return true;
}
return false;
}
COMPARE_MEMBER_AND_RETURN_IF_NE(pG1, pG2, Data2);
COMPARE_MEMBER_AND_RETURN_IF_NE(pG1, pG2, Data3);
int i;
for(i=0; i<8; ++i)
for(i = 0; i < 8; ++i)
{
COMPARE_MEMBER_AND_RETURN_IF_NE(pG1, pG2, Data4[i]);
}
return 0;
}
branches/ErmaC/Trunk/i386/libsa/memory.h
118118
119119
120120
121
122
123
121
122
123
124
124125
125126
126127
......
131132
132133
133134
134
135
135136
136137
137138
......
139140
140141
141142
142
143
143144
144145
#define OFFSET(addr) ((addr) & 0xFFFF)
#define SEGMENT(addr) (((addr) & 0xF0000) >> 4)
/* Extract segment/offset in normalized form so that the resulting far pointer
will point to something that is very unlikely to straddle a segment.
This is sometimes known as a "huge" pointer.
/*
* Extract segment/offset in normalized form so that the resulting far pointer
* will point to something that is very unlikely to straddle a segment.
* This is sometimes known as a "huge" pointer.
*/
#define NORMALIZED_OFFSET(addr) ((addr) & 0x000F)
#define NORMALIZED_SEGMENT(addr) (((addr) & 0xFFFF0) >> 4)
#define MIN_SYS_MEM_KB (32 * 1024)
/*
* The number of descriptor entries in the GDT.
* The number of descriptor entries in the GDT (Global Descriptor Table).
*/
#define NGDTENT 7
* The total size of the GDT in bytes.
* Each descriptor entry require 8 bytes.
*/
#define GDTLIMIT ( NGDTENT * 8 )
#define GDTLIMIT (NGDTENT * 8)
#endif /* !__BOOT_MEMORY_H */
branches/ErmaC/Trunk/CHANGES
1
2
3
4
5
16
27
38
- This revision is devoted to Samantha, AKA DHP or Revogirl in the OSx86 scene.
A young talent we lost prematurely.
Part of her work will now live on in the Chameleon source code.
Changes: code cleaned, improvements taken from Revoboot.
http://www.insanelymac.com/forum/index.php?showtopic=259090
- Apply patch by Andrey B http://forge.voodooprojects.org/p/chameleon/issues/270/
- cparm : Added a Sata module, known as YellowIconFixer in my branch, useful to fix yellow icon issue (can also fix an issue with the apple's dvd player application in moutain lion)
, for now not added in the pkg script !!!

Archive Download the corresponding diff file

Revision: 2037