From fc1285c39ce33e7ddf3e0c04d485dc0a8d079e96 Mon Sep 17 00:00:00 2001 From: turbocat Date: Sat, 3 Jul 2021 19:49:51 +0000 Subject: [PATCH] Recreation of the Kolibri-F branch. Part 1 git-svn-id: svn://kolibrios.org@8987 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/Kolibri-F/COPYING.TXT | 347 - kernel/branches/Kolibri-F/Makefile | 47 - kernel/branches/Kolibri-F/Tupfile.lua | 7 - kernel/branches/Kolibri-F/acpi/acpi.inc | 303 - kernel/branches/Kolibri-F/asmxygen.py | 2011 ------ kernel/branches/Kolibri-F/blkdev/bd_drv.inc | 301 - kernel/branches/Kolibri-F/blkdev/cd_drv.inc | 1218 ---- kernel/branches/Kolibri-F/blkdev/disk.inc | 1625 ----- .../branches/Kolibri-F/blkdev/disk_cache.inc | 1387 ---- kernel/branches/Kolibri-F/blkdev/fdc.inc | 68 - kernel/branches/Kolibri-F/blkdev/flp_drv.inc | 960 --- kernel/branches/Kolibri-F/blkdev/hd_drv.inc | 568 -- .../branches/Kolibri-F/blkdev/ide_cache.inc | 202 - kernel/branches/Kolibri-F/blkdev/rd.inc | 192 - kernel/branches/Kolibri-F/blkdev/rdsave.inc | 33 - kernel/branches/Kolibri-F/boot/ETFONT.FNT | Bin 4096 -> 0 bytes kernel/branches/Kolibri-F/boot/bootcode.inc | 1400 ---- kernel/branches/Kolibri-F/boot/booten.inc | 107 - kernel/branches/Kolibri-F/boot/bootet.inc | 106 - kernel/branches/Kolibri-F/boot/bootge.inc | 107 - kernel/branches/Kolibri-F/boot/bootru.inc | 106 - kernel/branches/Kolibri-F/boot/bootsp.inc | 108 - kernel/branches/Kolibri-F/boot/bootstr.inc | 56 - kernel/branches/Kolibri-F/boot/bootvesa.inc | 801 --- kernel/branches/Kolibri-F/boot/et.inc | 16 - kernel/branches/Kolibri-F/boot/parsers.inc | 172 - kernel/branches/Kolibri-F/boot/preboot.inc | 46 - kernel/branches/Kolibri-F/boot/rdload.inc | 128 - kernel/branches/Kolibri-F/boot/ru.inc | 102 - kernel/branches/Kolibri-F/boot/shutdown.inc | 408 -- kernel/branches/Kolibri-F/bootbios.asm | 124 - .../branches/Kolibri-F/bootloader/Tupfile.lua | 3 - .../Kolibri-F/bootloader/boot_fat12.asm | 304 - .../after_win/Tupfile.lua | 2 - .../after_win/build.bat | 2 - .../extended_primary_loader/after_win/fat.inc | 509 -- .../after_win/kordldr.win.asm | 924 --- .../after_win/kordldr.win.txt | 391 -- .../after_win/ntfs.inc | 587 -- .../extended_primary_loader/cdfs/Tupfile.lua | 2 - .../extended_primary_loader/cdfs/bootsect.asm | 1024 --- .../extended_primary_loader/cdfs/bootsect.txt | 418 -- .../extended_primary_loader/cdfs/build.bat | 2 - .../extended_primary_loader/config.ini | 15 - .../extended_primary_loader/fat1x/Tupfile.lua | 3 - .../fat1x/bootsect.asm | 392 -- .../fat1x/bootsect.txt | 360 - .../extended_primary_loader/fat1x/build.bat | 3 - .../fat1x/kordldr.f1x.asm | 689 -- .../extended_primary_loader/fat32/Tupfile.lua | 3 - .../fat32/bootsect.asm | 358 - .../fat32/bootsect.txt | 333 - .../extended_primary_loader/fat32/build.bat | 3 - .../fat32/kordldr.f32.asm | 673 -- .../Kolibri-F/bootloader/floppy1440.inc | 26 - .../Kolibri-F/bootloader/floppy1680.inc | 26 - .../Kolibri-F/bootloader/floppy1743.inc | 26 - .../Kolibri-F/bootloader/floppy2880.inc | 26 - .../Kolibri-F/bootloader/grub4kos.asm | 296 - kernel/branches/Kolibri-F/bootloader/readme | 50 - .../Kolibri-F/bootloader/uefi4kos/Tupfile.lua | 3 - .../Kolibri-F/bootloader/uefi4kos/kolibri.ini | 21 - .../Kolibri-F/bootloader/uefi4kos/uefi.inc | 272 - .../Kolibri-F/bootloader/uefi4kos/uefi32.inc | 58 - .../bootloader/uefi4kos/uefi32kos.asm | 990 --- .../Kolibri-F/bootloader/uefi4kos/uefi64.inc | 196 - .../bootloader/uefi4kos/uefi64kos.asm | 1249 ---- kernel/branches/Kolibri-F/build.bat | 39 - kernel/branches/Kolibri-F/build.sh | 12 - kernel/branches/Kolibri-F/bus/pci/PCIe.inc | 119 - kernel/branches/Kolibri-F/bus/pci/pci16.inc | 51 - kernel/branches/Kolibri-F/bus/pci/pci32.inc | 679 -- kernel/branches/Kolibri-F/bus/usb/common.inc | 462 -- .../branches/Kolibri-F/bus/usb/hccommon.inc | 348 - kernel/branches/Kolibri-F/bus/usb/hub.inc | 1285 ---- kernel/branches/Kolibri-F/bus/usb/init.inc | 268 - kernel/branches/Kolibri-F/bus/usb/memory.inc | 43 - kernel/branches/Kolibri-F/bus/usb/pipe.inc | 860 --- .../branches/Kolibri-F/bus/usb/protocol.inc | 1019 --- kernel/branches/Kolibri-F/const.inc | 984 --- kernel/branches/Kolibri-F/core/Tupfile.lua | 3 - kernel/branches/Kolibri-F/core/apic.inc | 567 -- kernel/branches/Kolibri-F/core/clipboard.inc | 167 - .../branches/Kolibri-F/core/conf_lib-sp.inc | 21 - kernel/branches/Kolibri-F/core/conf_lib.inc | 254 - kernel/branches/Kolibri-F/core/debug.inc | 455 -- kernel/branches/Kolibri-F/core/dll.inc | 1524 ----- kernel/branches/Kolibri-F/core/export.inc | 40 - kernel/branches/Kolibri-F/core/exports.inc | 141 - kernel/branches/Kolibri-F/core/ext_lib.inc | 476 -- kernel/branches/Kolibri-F/core/fpu.inc | 419 -- kernel/branches/Kolibri-F/core/heap.inc | 1589 ----- kernel/branches/Kolibri-F/core/hpet.inc | 74 - kernel/branches/Kolibri-F/core/irq.inc | 294 - kernel/branches/Kolibri-F/core/malloc.inc | 1035 --- kernel/branches/Kolibri-F/core/memory.inc | 1364 ---- kernel/branches/Kolibri-F/core/mtrr.inc | 931 --- kernel/branches/Kolibri-F/core/mtrrtest.asm | 213 - kernel/branches/Kolibri-F/core/peload.inc | 295 - kernel/branches/Kolibri-F/core/sched.inc | 434 -- kernel/branches/Kolibri-F/core/slab.inc | 125 - kernel/branches/Kolibri-F/core/string.inc | 189 - kernel/branches/Kolibri-F/core/sync.inc | 355 - kernel/branches/Kolibri-F/core/sys32-sp.inc | 14 - kernel/branches/Kolibri-F/core/sys32.inc | 840 --- kernel/branches/Kolibri-F/core/syscall.inc | 186 - kernel/branches/Kolibri-F/core/taskman.inc | 1057 --- .../branches/Kolibri-F/core/test_malloc.asm | 250 - kernel/branches/Kolibri-F/core/timers.inc | 229 - kernel/branches/Kolibri-F/core/v86.inc | 907 --- kernel/branches/Kolibri-F/crc.inc | 42 - kernel/branches/Kolibri-F/data16.inc | 87 - kernel/branches/Kolibri-F/data32.inc | 559 -- kernel/branches/Kolibri-F/data32et.inc | 48 - kernel/branches/Kolibri-F/data32sp.inc | 54 - kernel/branches/Kolibri-F/detect/biosdisk.inc | 122 - kernel/branches/Kolibri-F/detect/biosmem.inc | 46 - kernel/branches/Kolibri-F/detect/dev_fd.inc | 38 - kernel/branches/Kolibri-F/detect/dev_hdcd.inc | 475 -- kernel/branches/Kolibri-F/detect/disks.inc | 15 - kernel/branches/Kolibri-F/detect/getcache.inc | 209 - kernel/branches/Kolibri-F/detect/init_ata.inc | 492 -- kernel/branches/Kolibri-F/detect/sear_par.inc | 280 - kernel/branches/Kolibri-F/detect/vortex86.inc | 158 - kernel/branches/Kolibri-F/docs/apm.txt | 518 -- .../Kolibri-F/docs/doxygen/doxygen.cfg | 2612 -------- .../branches/Kolibri-F/docs/drivers_api.txt | 105 - .../Kolibri-F/docs/events_subsystem.ru.txt | 232 - .../Kolibri-F/docs/events_subsystem.txt | 248 - kernel/branches/Kolibri-F/docs/loader_doc.txt | 95 - kernel/branches/Kolibri-F/docs/stack.txt | 214 - kernel/branches/Kolibri-F/docs/sysfuncr.txt | 5003 -------------- kernel/branches/Kolibri-F/docs/sysfuncs.txt | 5256 --------------- kernel/branches/Kolibri-F/docs/usbapi.txt | 211 - kernel/branches/Kolibri-F/encoding.inc | 145 - kernel/branches/Kolibri-F/fdo.inc | 456 -- kernel/branches/Kolibri-F/fs/ext.inc | 2708 -------- kernel/branches/Kolibri-F/fs/fat.inc | 3152 --------- kernel/branches/Kolibri-F/fs/fs_common.inc | 142 - kernel/branches/Kolibri-F/fs/fs_lfn.inc | 795 --- kernel/branches/Kolibri-F/fs/iso9660.inc | 740 --- kernel/branches/Kolibri-F/fs/ntfs.inc | 4146 ------------ kernel/branches/Kolibri-F/fs/parse_fn.inc | 340 - kernel/branches/Kolibri-F/fs/xfs.asm | 2124 ------ kernel/branches/Kolibri-F/fs/xfs.inc | 622 -- kernel/branches/Kolibri-F/gui/button.inc | 346 - kernel/branches/Kolibri-F/gui/char.mt | Bin 2304 -> 0 bytes kernel/branches/Kolibri-F/gui/charUni.mt | Bin 22704 -> 0 bytes kernel/branches/Kolibri-F/gui/char_et.mt | Bin 2304 -> 0 bytes kernel/branches/Kolibri-F/gui/char_sp.mt | Bin 2304 -> 0 bytes kernel/branches/Kolibri-F/gui/event.inc | 622 -- kernel/branches/Kolibri-F/gui/font.inc | 878 --- kernel/branches/Kolibri-F/gui/mouse.inc | 687 -- .../branches/Kolibri-F/gui/mousepointer.inc | 250 - kernel/branches/Kolibri-F/gui/skincode.inc | 453 -- kernel/branches/Kolibri-F/gui/skindata.inc | 64 - kernel/branches/Kolibri-F/gui/window.inc | 2496 ------- kernel/branches/Kolibri-F/hid/keyboard.inc | 578 -- kernel/branches/Kolibri-F/hid/mousedrv.inc | 567 -- kernel/branches/Kolibri-F/hid/set_dtc.inc | 203 - kernel/branches/Kolibri-F/imports.inc | 27 - kernel/branches/Kolibri-F/init.inc | 531 -- kernel/branches/Kolibri-F/kernel.asm | 5787 ----------------- kernel/branches/Kolibri-F/kernel32.inc | 79 - kernel/branches/Kolibri-F/kernelsp.inc | 14 - kernel/branches/Kolibri-F/kglobals.inc | 69 - kernel/branches/Kolibri-F/macros.inc | 143 - kernel/branches/Kolibri-F/memmap.inc | 272 - kernel/branches/Kolibri-F/network/ARP.inc | 676 -- kernel/branches/Kolibri-F/network/IPv4.inc | 1161 ---- kernel/branches/Kolibri-F/network/IPv6.inc | 290 - kernel/branches/Kolibri-F/network/PPPoE.inc | 346 - .../branches/Kolibri-F/network/ethernet.inc | 312 - kernel/branches/Kolibri-F/network/icmp.inc | 456 -- .../branches/Kolibri-F/network/loopback.inc | 176 - kernel/branches/Kolibri-F/network/queue.inc | 120 - kernel/branches/Kolibri-F/network/socket.inc | 2525 ------- kernel/branches/Kolibri-F/network/stack.inc | 896 --- kernel/branches/Kolibri-F/network/tcp.inc | 293 - .../branches/Kolibri-F/network/tcp_input.inc | 1927 ------ .../branches/Kolibri-F/network/tcp_output.inc | 754 --- .../branches/Kolibri-F/network/tcp_subr.inc | 619 -- .../branches/Kolibri-F/network/tcp_timer.inc | 192 - .../branches/Kolibri-F/network/tcp_usreq.inc | 237 - kernel/branches/Kolibri-F/network/udp.inc | 434 -- kernel/branches/Kolibri-F/posix/futex.inc | 245 - kernel/branches/Kolibri-F/posix/pipe.inc | 339 - kernel/branches/Kolibri-F/posix/posix.inc | 129 - kernel/branches/Kolibri-F/proc32.inc | 316 - .../branches/Kolibri-F/readme-ext-loader.txt | 55 - .../sec_loader/trunk/boot/PrimaryLoader.txt | 91 - .../sec_loader/trunk/boot/after_win/build.bat | 2 - .../sec_loader/trunk/boot/after_win/fat.inc | 509 -- .../trunk/boot/after_win/kordldr.win.asm | 924 --- .../trunk/boot/after_win/kordldr.win.txt | 391 -- .../sec_loader/trunk/boot/after_win/ntfs.inc | 587 -- .../Kolibri-F/sec_loader/trunk/boot/build.bat | 20 - .../sec_loader/trunk/boot/cdfs/bootsect.asm | 1024 --- .../sec_loader/trunk/boot/cdfs/bootsect.txt | 418 -- .../sec_loader/trunk/boot/cdfs/build.bat | 2 - .../sec_loader/trunk/boot/fat1x/bootsect.asm | 392 -- .../sec_loader/trunk/boot/fat1x/bootsect.txt | 360 - .../sec_loader/trunk/boot/fat1x/build.bat | 3 - .../trunk/boot/fat1x/kordldr.f1x.asm | 668 -- .../sec_loader/trunk/boot/fat32/bootsect.asm | 358 - .../sec_loader/trunk/boot/fat32/bootsect.txt | 333 - .../sec_loader/trunk/boot/fat32/build.bat | 3 - .../trunk/boot/fat32/kordldr.f32.asm | 672 -- .../sec_loader/trunk/boot/floppy.asc | 49 - .../sec_loader/trunk/boot/mkfloppy.inc | 91 - .../Kolibri-F/sec_loader/trunk/boot_st.inc | 68 - .../Kolibri-F/sec_loader/trunk/build_ru.bat | 4 - .../Kolibri-F/sec_loader/trunk/debug_msg.inc | 77 - .../Kolibri-F/sec_loader/trunk/listing.inc | 635 -- .../Kolibri-F/sec_loader/trunk/loader.asm | 317 - .../Kolibri-F/sec_loader/trunk/loader.lst | 2147 ------ .../Kolibri-F/sec_loader/trunk/parse.inc | 118 - .../Kolibri-F/sec_loader/trunk/parse_any.inc | 686 -- .../Kolibri-F/sec_loader/trunk/parse_dat.inc | 56 - .../sec_loader/trunk/parse_def_sect.inc | 2121 ------ .../Kolibri-F/sec_loader/trunk/parse_err.inc | 66 - .../sec_loader/trunk/parse_loader.inc | 335 - .../Kolibri-F/sec_loader/trunk/sl_equ.inc | 98 - .../Kolibri-F/sec_loader/trunk/sl_proc.inc | 528 -- .../Kolibri-F/sec_loader/trunk/startos.ini | 98 - kernel/branches/Kolibri-F/sound/playnote.inc | 166 - kernel/branches/Kolibri-F/struct.inc | 240 - kernel/branches/Kolibri-F/sys.conf | 18 - kernel/branches/Kolibri-F/tools/kerpack | Bin 35856 -> 0 bytes kernel/branches/Kolibri-F/tools/kpack | Bin 39336 -> 0 bytes kernel/branches/Kolibri-F/unicode.inc | 117 - kernel/branches/Kolibri-F/unpacker.inc | 528 -- kernel/branches/Kolibri-F/video/arrow.cur | Bin 766 -> 0 bytes .../branches/Kolibri-F/video/arrow_clock.cur | Bin 2238 -> 0 bytes kernel/branches/Kolibri-F/video/blitter.inc | 536 -- kernel/branches/Kolibri-F/video/cursors.inc | 1238 ---- .../branches/Kolibri-F/video/framebuffer.inc | 250 - kernel/branches/Kolibri-F/video/vesa12.inc | 1004 --- kernel/branches/Kolibri-F/video/vesa20.inc | 2518 ------- kernel/branches/Kolibri-F/video/vga.inc | 534 -- 240 files changed, 124365 deletions(-) delete mode 100644 kernel/branches/Kolibri-F/COPYING.TXT delete mode 100644 kernel/branches/Kolibri-F/Makefile delete mode 100644 kernel/branches/Kolibri-F/Tupfile.lua delete mode 100644 kernel/branches/Kolibri-F/acpi/acpi.inc delete mode 100644 kernel/branches/Kolibri-F/asmxygen.py delete mode 100644 kernel/branches/Kolibri-F/blkdev/bd_drv.inc delete mode 100644 kernel/branches/Kolibri-F/blkdev/cd_drv.inc delete mode 100644 kernel/branches/Kolibri-F/blkdev/disk.inc delete mode 100644 kernel/branches/Kolibri-F/blkdev/disk_cache.inc delete mode 100644 kernel/branches/Kolibri-F/blkdev/fdc.inc delete mode 100644 kernel/branches/Kolibri-F/blkdev/flp_drv.inc delete mode 100644 kernel/branches/Kolibri-F/blkdev/hd_drv.inc delete mode 100644 kernel/branches/Kolibri-F/blkdev/ide_cache.inc delete mode 100644 kernel/branches/Kolibri-F/blkdev/rd.inc delete mode 100644 kernel/branches/Kolibri-F/blkdev/rdsave.inc delete mode 100644 kernel/branches/Kolibri-F/boot/ETFONT.FNT delete mode 100644 kernel/branches/Kolibri-F/boot/bootcode.inc delete mode 100644 kernel/branches/Kolibri-F/boot/booten.inc delete mode 100644 kernel/branches/Kolibri-F/boot/bootet.inc delete mode 100644 kernel/branches/Kolibri-F/boot/bootge.inc delete mode 100644 kernel/branches/Kolibri-F/boot/bootru.inc delete mode 100644 kernel/branches/Kolibri-F/boot/bootsp.inc delete mode 100644 kernel/branches/Kolibri-F/boot/bootstr.inc delete mode 100644 kernel/branches/Kolibri-F/boot/bootvesa.inc delete mode 100644 kernel/branches/Kolibri-F/boot/et.inc delete mode 100644 kernel/branches/Kolibri-F/boot/parsers.inc delete mode 100644 kernel/branches/Kolibri-F/boot/preboot.inc delete mode 100644 kernel/branches/Kolibri-F/boot/rdload.inc delete mode 100644 kernel/branches/Kolibri-F/boot/ru.inc delete mode 100644 kernel/branches/Kolibri-F/boot/shutdown.inc delete mode 100644 kernel/branches/Kolibri-F/bootbios.asm delete mode 100644 kernel/branches/Kolibri-F/bootloader/Tupfile.lua delete mode 100644 kernel/branches/Kolibri-F/bootloader/boot_fat12.asm delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/Tupfile.lua delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/build.bat delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/fat.inc delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/kordldr.win.asm delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/kordldr.win.txt delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/ntfs.inc delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/Tupfile.lua delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/bootsect.asm delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/bootsect.txt delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/build.bat delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/config.ini delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/Tupfile.lua delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/bootsect.asm delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/bootsect.txt delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/build.bat delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/kordldr.f1x.asm delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/Tupfile.lua delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/bootsect.asm delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/bootsect.txt delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/build.bat delete mode 100644 kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/kordldr.f32.asm delete mode 100644 kernel/branches/Kolibri-F/bootloader/floppy1440.inc delete mode 100644 kernel/branches/Kolibri-F/bootloader/floppy1680.inc delete mode 100644 kernel/branches/Kolibri-F/bootloader/floppy1743.inc delete mode 100644 kernel/branches/Kolibri-F/bootloader/floppy2880.inc delete mode 100644 kernel/branches/Kolibri-F/bootloader/grub4kos.asm delete mode 100644 kernel/branches/Kolibri-F/bootloader/readme delete mode 100644 kernel/branches/Kolibri-F/bootloader/uefi4kos/Tupfile.lua delete mode 100644 kernel/branches/Kolibri-F/bootloader/uefi4kos/kolibri.ini delete mode 100644 kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi.inc delete mode 100644 kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi32.inc delete mode 100644 kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi32kos.asm delete mode 100644 kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi64.inc delete mode 100644 kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi64kos.asm delete mode 100644 kernel/branches/Kolibri-F/build.bat delete mode 100755 kernel/branches/Kolibri-F/build.sh delete mode 100644 kernel/branches/Kolibri-F/bus/pci/PCIe.inc delete mode 100644 kernel/branches/Kolibri-F/bus/pci/pci16.inc delete mode 100644 kernel/branches/Kolibri-F/bus/pci/pci32.inc delete mode 100644 kernel/branches/Kolibri-F/bus/usb/common.inc delete mode 100644 kernel/branches/Kolibri-F/bus/usb/hccommon.inc delete mode 100644 kernel/branches/Kolibri-F/bus/usb/hub.inc delete mode 100644 kernel/branches/Kolibri-F/bus/usb/init.inc delete mode 100644 kernel/branches/Kolibri-F/bus/usb/memory.inc delete mode 100644 kernel/branches/Kolibri-F/bus/usb/pipe.inc delete mode 100644 kernel/branches/Kolibri-F/bus/usb/protocol.inc delete mode 100644 kernel/branches/Kolibri-F/const.inc delete mode 100644 kernel/branches/Kolibri-F/core/Tupfile.lua delete mode 100644 kernel/branches/Kolibri-F/core/apic.inc delete mode 100644 kernel/branches/Kolibri-F/core/clipboard.inc delete mode 100644 kernel/branches/Kolibri-F/core/conf_lib-sp.inc delete mode 100644 kernel/branches/Kolibri-F/core/conf_lib.inc delete mode 100644 kernel/branches/Kolibri-F/core/debug.inc delete mode 100644 kernel/branches/Kolibri-F/core/dll.inc delete mode 100644 kernel/branches/Kolibri-F/core/export.inc delete mode 100644 kernel/branches/Kolibri-F/core/exports.inc delete mode 100644 kernel/branches/Kolibri-F/core/ext_lib.inc delete mode 100644 kernel/branches/Kolibri-F/core/fpu.inc delete mode 100644 kernel/branches/Kolibri-F/core/heap.inc delete mode 100644 kernel/branches/Kolibri-F/core/hpet.inc delete mode 100644 kernel/branches/Kolibri-F/core/irq.inc delete mode 100644 kernel/branches/Kolibri-F/core/malloc.inc delete mode 100644 kernel/branches/Kolibri-F/core/memory.inc delete mode 100644 kernel/branches/Kolibri-F/core/mtrr.inc delete mode 100644 kernel/branches/Kolibri-F/core/mtrrtest.asm delete mode 100644 kernel/branches/Kolibri-F/core/peload.inc delete mode 100644 kernel/branches/Kolibri-F/core/sched.inc delete mode 100644 kernel/branches/Kolibri-F/core/slab.inc delete mode 100644 kernel/branches/Kolibri-F/core/string.inc delete mode 100644 kernel/branches/Kolibri-F/core/sync.inc delete mode 100644 kernel/branches/Kolibri-F/core/sys32-sp.inc delete mode 100644 kernel/branches/Kolibri-F/core/sys32.inc delete mode 100644 kernel/branches/Kolibri-F/core/syscall.inc delete mode 100644 kernel/branches/Kolibri-F/core/taskman.inc delete mode 100644 kernel/branches/Kolibri-F/core/test_malloc.asm delete mode 100644 kernel/branches/Kolibri-F/core/timers.inc delete mode 100644 kernel/branches/Kolibri-F/core/v86.inc delete mode 100644 kernel/branches/Kolibri-F/crc.inc delete mode 100644 kernel/branches/Kolibri-F/data16.inc delete mode 100644 kernel/branches/Kolibri-F/data32.inc delete mode 100644 kernel/branches/Kolibri-F/data32et.inc delete mode 100644 kernel/branches/Kolibri-F/data32sp.inc delete mode 100644 kernel/branches/Kolibri-F/detect/biosdisk.inc delete mode 100644 kernel/branches/Kolibri-F/detect/biosmem.inc delete mode 100644 kernel/branches/Kolibri-F/detect/dev_fd.inc delete mode 100644 kernel/branches/Kolibri-F/detect/dev_hdcd.inc delete mode 100644 kernel/branches/Kolibri-F/detect/disks.inc delete mode 100644 kernel/branches/Kolibri-F/detect/getcache.inc delete mode 100644 kernel/branches/Kolibri-F/detect/init_ata.inc delete mode 100644 kernel/branches/Kolibri-F/detect/sear_par.inc delete mode 100644 kernel/branches/Kolibri-F/detect/vortex86.inc delete mode 100644 kernel/branches/Kolibri-F/docs/apm.txt delete mode 100644 kernel/branches/Kolibri-F/docs/doxygen/doxygen.cfg delete mode 100644 kernel/branches/Kolibri-F/docs/drivers_api.txt delete mode 100644 kernel/branches/Kolibri-F/docs/events_subsystem.ru.txt delete mode 100644 kernel/branches/Kolibri-F/docs/events_subsystem.txt delete mode 100644 kernel/branches/Kolibri-F/docs/loader_doc.txt delete mode 100644 kernel/branches/Kolibri-F/docs/stack.txt delete mode 100644 kernel/branches/Kolibri-F/docs/sysfuncr.txt delete mode 100644 kernel/branches/Kolibri-F/docs/sysfuncs.txt delete mode 100644 kernel/branches/Kolibri-F/docs/usbapi.txt delete mode 100644 kernel/branches/Kolibri-F/encoding.inc delete mode 100644 kernel/branches/Kolibri-F/fdo.inc delete mode 100644 kernel/branches/Kolibri-F/fs/ext.inc delete mode 100644 kernel/branches/Kolibri-F/fs/fat.inc delete mode 100644 kernel/branches/Kolibri-F/fs/fs_common.inc delete mode 100644 kernel/branches/Kolibri-F/fs/fs_lfn.inc delete mode 100644 kernel/branches/Kolibri-F/fs/iso9660.inc delete mode 100644 kernel/branches/Kolibri-F/fs/ntfs.inc delete mode 100644 kernel/branches/Kolibri-F/fs/parse_fn.inc delete mode 100644 kernel/branches/Kolibri-F/fs/xfs.asm delete mode 100644 kernel/branches/Kolibri-F/fs/xfs.inc delete mode 100644 kernel/branches/Kolibri-F/gui/button.inc delete mode 100644 kernel/branches/Kolibri-F/gui/char.mt delete mode 100644 kernel/branches/Kolibri-F/gui/charUni.mt delete mode 100644 kernel/branches/Kolibri-F/gui/char_et.mt delete mode 100644 kernel/branches/Kolibri-F/gui/char_sp.mt delete mode 100644 kernel/branches/Kolibri-F/gui/event.inc delete mode 100644 kernel/branches/Kolibri-F/gui/font.inc delete mode 100644 kernel/branches/Kolibri-F/gui/mouse.inc delete mode 100644 kernel/branches/Kolibri-F/gui/mousepointer.inc delete mode 100644 kernel/branches/Kolibri-F/gui/skincode.inc delete mode 100644 kernel/branches/Kolibri-F/gui/skindata.inc delete mode 100644 kernel/branches/Kolibri-F/gui/window.inc delete mode 100644 kernel/branches/Kolibri-F/hid/keyboard.inc delete mode 100644 kernel/branches/Kolibri-F/hid/mousedrv.inc delete mode 100644 kernel/branches/Kolibri-F/hid/set_dtc.inc delete mode 100644 kernel/branches/Kolibri-F/imports.inc delete mode 100644 kernel/branches/Kolibri-F/init.inc delete mode 100644 kernel/branches/Kolibri-F/kernel.asm delete mode 100644 kernel/branches/Kolibri-F/kernel32.inc delete mode 100644 kernel/branches/Kolibri-F/kernelsp.inc delete mode 100644 kernel/branches/Kolibri-F/kglobals.inc delete mode 100644 kernel/branches/Kolibri-F/macros.inc delete mode 100644 kernel/branches/Kolibri-F/memmap.inc delete mode 100644 kernel/branches/Kolibri-F/network/ARP.inc delete mode 100644 kernel/branches/Kolibri-F/network/IPv4.inc delete mode 100644 kernel/branches/Kolibri-F/network/IPv6.inc delete mode 100644 kernel/branches/Kolibri-F/network/PPPoE.inc delete mode 100644 kernel/branches/Kolibri-F/network/ethernet.inc delete mode 100644 kernel/branches/Kolibri-F/network/icmp.inc delete mode 100644 kernel/branches/Kolibri-F/network/loopback.inc delete mode 100644 kernel/branches/Kolibri-F/network/queue.inc delete mode 100644 kernel/branches/Kolibri-F/network/socket.inc delete mode 100644 kernel/branches/Kolibri-F/network/stack.inc delete mode 100644 kernel/branches/Kolibri-F/network/tcp.inc delete mode 100644 kernel/branches/Kolibri-F/network/tcp_input.inc delete mode 100644 kernel/branches/Kolibri-F/network/tcp_output.inc delete mode 100644 kernel/branches/Kolibri-F/network/tcp_subr.inc delete mode 100644 kernel/branches/Kolibri-F/network/tcp_timer.inc delete mode 100644 kernel/branches/Kolibri-F/network/tcp_usreq.inc delete mode 100644 kernel/branches/Kolibri-F/network/udp.inc delete mode 100644 kernel/branches/Kolibri-F/posix/futex.inc delete mode 100644 kernel/branches/Kolibri-F/posix/pipe.inc delete mode 100644 kernel/branches/Kolibri-F/posix/posix.inc delete mode 100644 kernel/branches/Kolibri-F/proc32.inc delete mode 100644 kernel/branches/Kolibri-F/readme-ext-loader.txt delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/PrimaryLoader.txt delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/after_win/build.bat delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/after_win/fat.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/after_win/kordldr.win.asm delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/after_win/kordldr.win.txt delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/after_win/ntfs.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/build.bat delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/cdfs/bootsect.asm delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/cdfs/bootsect.txt delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/cdfs/build.bat delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/fat1x/bootsect.asm delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/fat1x/bootsect.txt delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/fat1x/build.bat delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/fat32/bootsect.asm delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/fat32/bootsect.txt delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/fat32/build.bat delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/fat32/kordldr.f32.asm delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/floppy.asc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot/mkfloppy.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/boot_st.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/build_ru.bat delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/debug_msg.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/listing.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/loader.asm delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/loader.lst delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/parse.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/parse_any.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/parse_dat.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/parse_def_sect.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/parse_err.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/parse_loader.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/sl_equ.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/sl_proc.inc delete mode 100644 kernel/branches/Kolibri-F/sec_loader/trunk/startos.ini delete mode 100644 kernel/branches/Kolibri-F/sound/playnote.inc delete mode 100644 kernel/branches/Kolibri-F/struct.inc delete mode 100644 kernel/branches/Kolibri-F/sys.conf delete mode 100755 kernel/branches/Kolibri-F/tools/kerpack delete mode 100755 kernel/branches/Kolibri-F/tools/kpack delete mode 100644 kernel/branches/Kolibri-F/unicode.inc delete mode 100644 kernel/branches/Kolibri-F/unpacker.inc delete mode 100644 kernel/branches/Kolibri-F/video/arrow.cur delete mode 100644 kernel/branches/Kolibri-F/video/arrow_clock.cur delete mode 100644 kernel/branches/Kolibri-F/video/blitter.inc delete mode 100644 kernel/branches/Kolibri-F/video/cursors.inc delete mode 100644 kernel/branches/Kolibri-F/video/framebuffer.inc delete mode 100644 kernel/branches/Kolibri-F/video/vesa12.inc delete mode 100644 kernel/branches/Kolibri-F/video/vesa20.inc delete mode 100644 kernel/branches/Kolibri-F/video/vga.inc diff --git a/kernel/branches/Kolibri-F/COPYING.TXT b/kernel/branches/Kolibri-F/COPYING.TXT deleted file mode 100644 index f6213b69c..000000000 --- a/kernel/branches/Kolibri-F/COPYING.TXT +++ /dev/null @@ -1,347 +0,0 @@ - - GNU GENERAL PUBLIC LICENSE - - Version 2, June 1991 - - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - - GNU GENERAL PUBLIC LICENSE - - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/kernel/branches/Kolibri-F/Makefile b/kernel/branches/Kolibri-F/Makefile deleted file mode 100644 index 8f924bca1..000000000 --- a/kernel/branches/Kolibri-F/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -FASM=fasm -FLAGS=-m 65536 -languages=en|ru|ge|et|sp - -.PHONY: all kernel bootloader clean - -all: kernel bootloader bootbios - -kernel: check_lang bootbios - @echo "*** building kernel with language '$(lang)' ..." - @mkdir -p bin - @echo "lang fix $(lang)" > lang.inc - @echo "--- building 'bin/kernel.mnt' ..." - @$(FASM) $(FLAGS) kernel.asm bin/kernel.mnt - @$(FASM) $(FLAGS) -dUEFI=1 kernel.asm bin/kernel.bin - @rm -f lang.inc - -bootbios: check_lang - @echo "*** building bootbios.bin with language '$(lang)' ..." - @mkdir -p bin - @echo "lang fix $(lang)" > lang.inc - @echo "--- building 'bootbios.bin' ..." - @$(FASM) $(FLAGS) bootbios.asm bootbios.bin - @rm -f lang.inc - -bootloader: check_lang - @echo "*** building bootloader with language '$(lang)' ..." - @mkdir -p bin - @echo "lang fix $(lang)" > lang.inc - @echo "--- building 'bin/boot_fat12.bin' ..." - @$(FASM) $(FLAGS) bootloader/boot_fat12.asm bin/boot_fat12.bin - @rm -f lang.inc - - -check_lang: - @case "$(lang)" in \ - $(languages)) \ - ;; \ - *) \ - echo "*** error: language is incorrect or not specified"; \ - exit 1; \ - ;; \ - esac - -clean: - rm -rf bin - rm -f lang.inc diff --git a/kernel/branches/Kolibri-F/Tupfile.lua b/kernel/branches/Kolibri-F/Tupfile.lua deleted file mode 100644 index cbed9e8c8..000000000 --- a/kernel/branches/Kolibri-F/Tupfile.lua +++ /dev/null @@ -1,7 +0,0 @@ -if tup.getconfig("NO_FASM") ~= "" then return end -tup.rule("echo lang fix " .. ((tup.getconfig("LANG") == "") and "en" or tup.getconfig("LANG")) .. " > %o", {"lang.inc"}) -tup.rule({"bootbios.asm", extra_inputs = {"lang.inc"}}, "fasm %f %o ", "bootbios.bin") -tup.rule({"bootbios.asm", extra_inputs = {"lang.inc"}}, "fasm %f %o -dextended_primary_loader=1", "bootbios.bin.ext_loader") -tup.rule({"kernel.asm", extra_inputs = {"bootbios.bin", "lang.inc"}}, "fasm -m 65536 %f %o " .. tup.getconfig("KERPACK_CMD"), "kernel.mnt") -tup.rule({"kernel.asm", extra_inputs = {"bootbios.bin.ext_loader", "lang.inc"}}, "fasm -m 65536 %f %o -dextended_primary_loader=1" .. tup.getconfig("KERPACK_CMD"), "kernel.mnt.ext_loader") -tup.rule({"kernel.asm", extra_inputs = {"lang.inc"}}, "fasm -m 65536 %f %o -dUEFI=1 -dextended_primary_loader=1", "kolibri.krn") diff --git a/kernel/branches/Kolibri-F/acpi/acpi.inc b/kernel/branches/Kolibri-F/acpi/acpi.inc deleted file mode 100644 index a91fa09b8..000000000 --- a/kernel/branches/Kolibri-F/acpi/acpi.inc +++ /dev/null @@ -1,303 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; ACPI Generic Address Structure -struct GAS - ASID db ? ; address space id - BitWidth db ? - BitOffset db ? - AccessSize db ? - Address DQ ? -ends - -ASID.SYSTEM_MEMORY = 0 -ASID.SYSTEM_IO = 1 -ASID.PCI_CONFIG = 2 -ASID.PCI_EC = 3 -ASID.PCI_SMBUS = 4 - -ACCESS_SIZE.UNDEFINED = 0 -ACCESS_SIZE.BYTE = 1 -ACCESS_SIZE.WORD = 2 -ACCESS_SIZE.DWORD = 3 -ACCESS_SIZE.QWORD = 4 - - -struct ACPI_RSDP - Signature DQ ? - Checksum db ? - OEMID rb 6 - Revision db ? - RsdtAddress dd ? - ; for Revision >= 2 - Length dd ? - XsdtAddress DQ ? - ExtChecksum db ? - Reserved rb 3 -ends - -struct ACPI_TABLE ; DESCRIPTION_HEADER - Signature dd ? - Length dd ? - Revision db ? - Checksum db ? - OEMID rb 6 - OEMTableID rb 8 - OEMRevision rb 4 - CreatorID rb 4 - CreatorRevision rb 4 -ends - -struct ACPI_RSDT ACPI_TABLE - Entry rd (0x1000-sizeof.ACPI_TABLE)/4 -ends - -struct ACPI_HPET ACPI_TABLE - ID dd ? - Base GAS - SeqNumber db ? - MainCounterMinimum dw ? - PageProtectionOEM db ? -ends - -struct ACPI_MADT ACPI_TABLE - Local_IC_Addr dd ? - Flags dd ? - IntController rb 0x1000-sizeof.ACPI_TABLE-ACPI_MADT.IntController -ends - -struct ACPI_FADT ACPI_TABLE - FirmwareCtrl dd ? - DSDT dd ? - db ? - PreferredPMProfile db ? - SCI_INT dw ? - SMI_CMD dd ? - ACPI_ENABLE db ? - ACPI_DISABLE db ? - S4BIOS_REQ db ? - PSTATE_CNT db ? - PM1a_EVT_BLK dd ? - PM1b_EVT_BLK dd ? - PM1a_CNT_BLK dd ? - PM1b_CNT_BLK dd ? - PM2_CNT_BLK dd ? - PM_TMR_BLK dd ? - GPE0_BLK dd ? - GPE1_BLK dd ? - PM1_EVT_LEN db ? - PM1_CNT_LEN db ? - PM2_CNT_LEN db ? - PM_TMR_LEN db ? - GPE0_BLK_LEN db ? - GPE1_BLK_LEN db ? - GPE1_BASE db ? - CST_CNT db ? - P_LVL2_LAT dw ? - P_LVL3_LAT dw ? - FLUSH_SIZE dw ? - FLUSH_STRIDE dw ? - DUTY_OFFSET db ? - DUTY_WIDTH db ? - DAY_ALRM db ? - MON_ALRM db ? - CENTURY db ? - IAPC_BOOT_ARCH dw ? - db ? - Flags dd ? - RESET_REG GAS - RESET_VALUE db ? - ARM_BOOT_ARCH dw ? - FADT_Minor_Version db ? - X_FIRMWARE_CTRL DQ ? - X_DSDT DQ ? - X_PM1a_EVT_BLK GAS - X_PM1b_EVT_BLK GAS - X_PM1a_CNT_BLK GAS - X_PM1b_CNT_BLK GAS - X_PM2_CNT_BLK GAS - X_PM_TMR_BLK GAS - X_GPE0_BLK GAS - X_GPE1_BLK GAS - SLEEP_CONTROL_REG GAS - SLEEP_STATUS_REG GAS - HypervisorVendorID rb 8 -ends - -MAX_SSDTS = 32 - -iglobal -align 4 -acpi_lapic_base dd 0xfee00000 ; default local apic base -endg - -uglobal -align 4 -acpi_dev_data rd 1 -acpi_dev_size rd 1 - -acpi_rsdp_base rd 1 -acpi_rsdt_base rd 1 -acpi_rsdt_size rd 1 -acpi_fadt_base rd 1 -acpi_fadt_size rd 1 -acpi_ssdt_base rd MAX_SSDTS -acpi_ssdt_size rd MAX_SSDTS -acpi_ssdt_cnt rd 1 -acpi_madt_base rd 1 -acpi_madt_size rd 1 -acpi_ioapic_base rd MAX_IOAPICS -acpi_hpet_base rd 1 -acpi_hpet_size rd 1 -cpu_count rd 1 -smpt rd 16 -endg - -align 4 -acpi_get_root_ptr: - mov eax, [acpi_rsdp_base] - ret - -align 4 -rsdt_find: ;ecx= rsdt edx= SIG - push ebx - push esi - - lea ebx, [ecx+ACPI_RSDT.Entry] - mov esi, [ecx+ACPI_RSDT.Length] - add esi, ecx -align 4 -.next: - mov eax, [ebx] - cmp [eax], edx - je .done - - add ebx, 4 - cmp ebx, esi - jb .next - - xor eax, eax - pop esi - pop ebx - ret - -.done: - mov eax, [ebx] - pop esi - pop ebx - ret - -align 4 -check_acpi: - cmp [acpi_rsdp_base], 0 - jz .done - stdcall map_io_mem, [acpi_rsdp_base], sizeof.ACPI_RSDP, \ - PG_GLOBAL+PAT_WB+PG_READ - mov [acpi_rsdp_base], eax -.rsdp_done: - cmp [acpi_rsdt_base], 0 - jz .rsdt_done - stdcall map_io_mem, [acpi_rsdt_base], [acpi_rsdt_size], \ - PG_GLOBAL+PAT_WB+PG_READ - mov [acpi_rsdt_base], eax -.rsdt_done: - cmp [acpi_fadt_base], 0 - jz .fadt_done - stdcall map_io_mem, [acpi_fadt_base], [acpi_fadt_size], \ - PG_GLOBAL+PAT_WB+PG_READ - mov [acpi_fadt_base], eax -.fadt_done: - cmp [acpi_hpet_base], 0 - jz .hpet_done - stdcall map_io_mem, [acpi_hpet_base], [acpi_hpet_size], \ - PG_GLOBAL+PAT_WB+PG_READ - mov [acpi_hpet_base], eax - mov eax, [eax+ACPI_HPET.Base.Address.lo] - mov [hpet_base], eax -.hpet_done: - cmp [acpi_madt_base], 0 - jz .madt_done - stdcall map_io_mem, [acpi_madt_base], [acpi_madt_size], \ - PG_GLOBAL+PAT_WB+PG_READ - mov [acpi_madt_base], eax - - mov ecx, [eax+ACPI_MADT.Local_IC_Addr] - mov [acpi_lapic_base], ecx - push eax - stdcall map_io_mem, ecx, 0x1000, PG_GLOBAL+PG_NOCACHE+PG_SWR - mov [LAPIC_BASE], eax - mov ecx, eax - pop eax - - mov edi, smpt - mov ebx, [ecx+APIC_ID] - shr ebx, 24 ; read APIC ID - - mov [edi], ebx ; bootstrap always first - inc [cpu_count] - add edi, 4 - - mov [ioapic_cnt], 0 - lea edx, [eax+ACPI_MADT.IntController] - mov ecx, [eax+ACPI_MADT.Length] - add ecx, eax -.check: - mov eax, [edx] - cmp al, 0 - je .lapic - cmp al, 1 - je .io_apic - jmp .next -.lapic: - shr eax, 24 ; get APIC ID - cmp eax, ebx ; skip self - je .next - - test [edx+4], byte 1 ; is enabled ? - jz .next - - cmp [cpu_count], 16 - jae .next - - stosd ; store APIC ID - inc [cpu_count] - jmp .next - -.io_apic: - mov eax, [ioapic_cnt] - push dword[edx+4] - pop [acpi_ioapic_base+eax*4] - push dword[edx+8] - pop [ioapic_gsi_base+eax*4] - inc [ioapic_cnt] - jmp .next - -.next: - mov eax, [edx] - movzx eax, ah - add edx, eax - cmp edx, ecx - jb .check -.madt_done: - - xor ecx, ecx -.next_ssdt: - cmp ecx, [acpi_ssdt_cnt] - jz .ssdt_done - push ecx - stdcall map_io_mem, [acpi_ssdt_base+ecx*4], [acpi_ssdt_size+ecx*4], \ - PG_GLOBAL+PAT_WB+PG_READ - pop ecx - mov [acpi_ssdt_base+ecx*4], eax - inc ecx - jmp .next_ssdt -.ssdt_done: - -.done: - ret diff --git a/kernel/branches/Kolibri-F/asmxygen.py b/kernel/branches/Kolibri-F/asmxygen.py deleted file mode 100644 index a4b5cc37a..000000000 --- a/kernel/branches/Kolibri-F/asmxygen.py +++ /dev/null @@ -1,2011 +0,0 @@ -import re -import os -import argparse -import sys - -# Parameters -# Path to doxygen folder to make doxygen files in: -o -doxygen_src_path = 'docs/doxygen' -# Remove generated doxygen files: --clean -clean_generated_stuff = False -# Dump all defined symbols: --dump -dump_symbols = False -# Print symbol stats: --stats -print_stats = False -# Do not write warnings file: --nowarn -enable_warnings = True - -# Constants -link_root = "http://websvn.kolibrios.org/filedetails.php?repname=Kolibri+OS&path=/kernel/trunk" - -# fasm keywords -keywords = [ - # Generic keywords - "align", - "equ", - "org", - "while", - "load", - "store", - "times", - "repeat", - "virtual", - "display", - "err", - "assert", - "if", - # Instructions - "aaa", - "aad", - "aam", - "aas", - "adc", - "adcx", - "add", - "addpd", - "addps", - "addsd", - "addss", - "addsubpd", - "addsubps", - "adox", - "aesdec", - "aesdeclast", - "aesenc", - "aesenclast", - "aesimc", - "aeskeygenassist", - "and", - "andn", - "andnpd", - "andnps", - "andpd", - "andps", - "arpl", - "bextr", - "blendpd", - "blendps", - "blendvpd", - "blendvps", - "blsi", - "blsmsk", - "blsr", - "bndcl", - "bndcn", - "bndcu", - "bndldx", - "bndmk", - "bndmov", - "bndstx", - "bound", - "bsf", - "bsr", - "bswap", - "bt", - "btc", - "btr", - "bts", - "bzhi", - "call", - "cbw", - "cdq", - "cdqe", - "clac", - "clc", - "cld", - "cldemote", - "clflush", - "clflushopt", - "cli", - "clts", - "clwb", - "cmc", - "cmova", - "cmovae", - "cmovb", - "cmovbe", - "cmovc", - "cmove", - "cmovg", - "cmovge", - "cmovl", - "cmovle", - "cmovna", - "cmovnae", - "cmovnb", - "cmovnbe", - "cmovnc", - "cmovne", - "cmovng", - "cmovnge", - "cmovnl", - "cmovnle", - "cmovno", - "cmovnp", - "cmovns", - "cmovnz", - "cmovo", - "cmovp", - "cmovpe", - "cmovpo", - "cmovs", - "cmovz", - "cmp", - "cmppd", - "cmpps", - "cmps", - "cmpsb", - "cmpsd", - "cmpsd", - "cmpsq", - "cmpss", - "cmpsw", - "cmpxchg", - "cmpxchg16b", - "cmpxchg8b", - "comisd", - "comiss", - "cpuid", - "cqo", - "crc32", - "cvtdq2pd", - "cvtdq2ps", - "cvtpd2dq", - "cvtpd2pi", - "cvtpd2ps", - "cvtpi2pd", - "cvtpi2ps", - "cvtps2dq", - "cvtps2pd", - "cvtps2pi", - "cvtsd2si", - "cvtsd2ss", - "cvtsi2sd", - "cvtsi2ss", - "cvtss2sd", - "cvtss2si", - "cvttpd2dq", - "cvttpd2pi", - "cvttps2dq", - "cvttps2pi", - "cvttsd2si", - "cvttss2si", - "cwd", - "cwde", - "daa", - "das", - "dec", - "div", - "divpd", - "divps", - "divsd", - "divss", - "dppd", - "dpps", - "emms", - "enter", - "extractps", - "f2xm1", - "fabs", - "fadd", - "faddp", - "fbld", - "fbstp", - "fchs", - "fclex", - "fcmova", - "fcmovae", - "fcmovb", - "fcmovbe", - "fcmovc", - "fcmove", - "fcmovg", - "fcmovge", - "fcmovl", - "fcmovle", - "fcmovna", - "fcmovnae", - "fcmovnb", - "fcmovnbe", - "fcmovnc", - "fcmovne", - "fcmovng", - "fcmovnge", - "fcmovnl", - "fcmovnle", - "fcmovno", - "fcmovnp", - "fcmovns", - "fcmovnz", - "fcmovo", - "fcmovp", - "fcmovpe", - "fcmovpo", - "fcmovs", - "fcmovz", - "fcom", - "fcomi", - "fcomip", - "fcomp", - "fcompp", - "fcos", - "fdecstp", - "fdiv", - "fdivp", - "fdivr", - "fdivrp", - "ffree", - "fiadd", - "ficom", - "ficomp", - "fidiv", - "fidivr", - "fild", - "fimul", - "fincstp", - "finit", - "fist", - "fistp", - "fisttp", - "fisub", - "fisubr", - "fld", - "fld1", - "fldcw", - "fldenv", - "fldl2e", - "fldl2t", - "fldlg2", - "fldln2", - "fldpi", - "fldz", - "fmul", - "fmulp", - "fnclex", - "fninit", - "fnop", - "fnsave", - "fnstcw", - "fnstenv", - "fnstsw", - "fpatan", - "fprem", - "fprem1", - "fptan", - "frndint", - "frstor", - "fsave", - "fscale", - "fsin", - "fsincos", - "fsqrt", - "fst", - "fstcw", - "fstenv", - "fstp", - "fstsw", - "fsub", - "fsubp", - "fsubr", - "fsubrp", - "ftst", - "fucom", - "fucomi", - "fucomip", - "fucomp", - "fucompp", - "fwait", - "fxam", - "fxch", - "fxrstor", - "fxsave", - "fxtract", - "fyl2x", - "fyl2xp1", - "gf2p8affineinvqb", - "gf2p8affineqb", - "gf2p8mulb", - "haddpd", - "haddps", - "hlt", - "hsubpd", - "hsubps", - "idiv", - "imul", - "in", - "inc", - "ins", - "insb", - "insd", - "insertps", - "insw", - "int", - "int1", - "int3", - "into", - "invd", - "invlpg", - "invpcid", - "iret", - "iretd", - "jmp", - "ja", - "jae", - "jb", - "jbe", - "jc", - "jcxz", - "jecxz", - "je", - "jg", - "jge", - "jl", - "jle", - "jna", - "jnae", - "jnb", - "jnbe", - "jnc", - "jne", - "jng", - "jnge", - "jnl", - "jnle", - "jno", - "jnp", - "jns", - "jnz", - "jo", - "jp", - "jpe", - "jpo", - "js", - "jz", - "kaddb", - "kaddd", - "kaddq", - "kaddw", - "kandb", - "kandd", - "kandnb", - "kandnd", - "kandnq", - "kandnw", - "kandq", - "kandw", - "kmovb", - "kmovd", - "kmovq", - "kmovw", - "knotb", - "knotd", - "knotq", - "knotw", - "korb", - "kord", - "korq", - "kortestb", - "kortestd", - "kortestq", - "kortestw", - "korw", - "kshiftlb", - "kshiftld", - "kshiftlq", - "kshiftlw", - "kshiftrb", - "kshiftrd", - "kshiftrq", - "kshiftrw", - "ktestb", - "ktestd", - "ktestq", - "ktestw", - "kunpckbw", - "kunpckdq", - "kunpckwd", - "kxnorb", - "kxnord", - "kxnorq", - "kxnorw", - "kxorb", - "kxord", - "kxorq", - "kxorw", - "lahf", - "lar", - "lddqu", - "ldmxcsr", - "lds", - "lea", - "leave", - "les", - "lfence", - "lfs", - "lgdt", - "lgs", - "lidt", - "lldt", - "lmsw", - "lock", - "lods", - "lodsb", - "lodsd", - "lodsq", - "lodsw", - "loop", - "loopa", - "loopae", - "loopb", - "loopbe", - "loopc", - "loope", - "loopg", - "loopge", - "loopl", - "loople", - "loopna", - "loopnae", - "loopnb", - "loopnbe", - "loopnc", - "loopne", - "loopng", - "loopnge", - "loopnl", - "loopnle", - "loopno", - "loopnp", - "loopns", - "loopnz", - "loopo", - "loopp", - "looppe", - "looppo", - "loops", - "loopz", - "lsl", - "lss", - "ltr", - "lzcnt", - "maskmovdqu", - "maskmovq", - "maxpd", - "maxps", - "maxsd", - "maxss", - "mfence", - "minpd", - "minps", - "minsd", - "minss", - "monitor", - "mov", - "movapd", - "movaps", - "movbe", - "movd", - "movddup", - "movdir64b", - "movdiri", - "movdq2q", - "movdqa", - "movdqu", - "movhlps", - "movhpd", - "movhps", - "movlhps", - "movlpd", - "movlps", - "movmskpd", - "movmskps", - "movntdq", - "movntdqa", - "movnti", - "movntpd", - "movntps", - "movntq", - "movq", - "movq", - "movq2dq", - "movs", - "movsb", - "movsd", - "movsd", - "movshdup", - "movsldup", - "movsq", - "movss", - "movsw", - "movsx", - "movsxd", - "movupd", - "movups", - "movzx", - "mpsadbw", - "mul", - "mulpd", - "mulps", - "mulsd", - "mulss", - "mulx", - "mwait", - "neg", - "nop", - "not", - "or", - "orpd", - "orps", - "out", - "outs", - "outsb", - "outsd", - "outsw", - "pabsb", - "pabsd", - "pabsq", - "pabsw", - "packssdw", - "packsswb", - "packusdw", - "packuswb", - "paddb", - "paddd", - "paddq", - "paddsb", - "paddsw", - "paddusb", - "paddusw", - "paddw", - "palignr", - "pand", - "pandn", - "pause", - "pavgb", - "pavgw", - "pblendvb", - "pblendw", - "pclmulqdq", - "pcmpeqb", - "pcmpeqd", - "pcmpeqq", - "pcmpeqw", - "pcmpestri", - "pcmpestrm", - "pcmpgtb", - "pcmpgtd", - "pcmpgtq", - "pcmpgtw", - "pcmpistri", - "pcmpistrm", - "pdep", - "pext", - "pextrb", - "pextrd", - "pextrq", - "pextrw", - "phaddd", - "phaddsw", - "phaddw", - "phminposuw", - "phsubd", - "phsubsw", - "phsubw", - "pinsrb", - "pinsrd", - "pinsrq", - "pinsrw", - "pmaddubsw", - "pmaddwd", - "pmaxsb", - "pmaxsd", - "pmaxsq", - "pmaxsw", - "pmaxub", - "pmaxud", - "pmaxuq", - "pmaxuw", - "pminsb", - "pminsd", - "pminsq", - "pminsw", - "pminub", - "pminud", - "pminuq", - "pminuw", - "pmovmskb", - "pmovsx", - "pmovzx", - "pmuldq", - "pmulhrsw", - "pmulhuw", - "pmulhw", - "pmulld", - "pmullq", - "pmullw", - "pmuludq", - "pop", - "popa", - "popad", - "popcnt", - "popf", - "popfd", - "popfq", - "por", - "prefetchw", - "prefetchh", - "psadbw", - "pshufb", - "pshufd", - "pshufhw", - "pshuflw", - "pshufw", - "psignb", - "psignd", - "psignw", - "pslld", - "pslldq", - "psllq", - "psllw", - "psrad", - "psraq", - "psraw", - "psrld", - "psrldq", - "psrlq", - "psrlw", - "psubb", - "psubd", - "psubq", - "psubsb", - "psubsw", - "psubusb", - "psubusw", - "psubw", - "ptest", - "ptwrite", - "punpckhbw", - "punpckhdq", - "punpckhqdq", - "punpckhwd", - "punpcklbw", - "punpckldq", - "punpcklqdq", - "punpcklwd", - "push", - "pushw", - "pushd", - "pusha", - "pushad", - "pushf", - "pushfd", - "pushfq", - "pxor", - "rcl", - "rcpps", - "rcpss", - "rcr", - "rdfsbase", - "rdgsbase", - "rdmsr", - "rdpid", - "rdpkru", - "rdpmc", - "rdrand", - "rdseed", - "rdtsc", - "rdtscp", - "rep", - "repe", - "repne", - "repnz", - "repz", - "ret", - "rol", - "ror", - "rorx", - "roundpd", - "roundps", - "roundsd", - "roundss", - "rsm", - "rsqrtps", - "rsqrtss", - "sahf", - "sal", - "sar", - "sarx", - "sbb", - "scas", - "scasb", - "scasd", - "scasw", - "seta", - "setae", - "setb", - "setbe", - "setc", - "sete", - "setg", - "setge", - "setl", - "setle", - "setna", - "setnae", - "setnb", - "setnbe", - "setnc", - "setne", - "setng", - "setnge", - "setnl", - "setnle", - "setno", - "setnp", - "setns", - "setnz", - "seto", - "setp", - "setpe", - "setpo", - "sets", - "setz", - "sfence", - "sgdt", - "sha1msg1", - "sha1msg2", - "sha1nexte", - "sha1rnds4", - "sha256msg1", - "sha256msg2", - "sha256rnds2", - "shl", - "shld", - "shlx", - "shr", - "shrd", - "shrx", - "shufpd", - "shufps", - "sidt", - "sldt", - "smsw", - "sqrtpd", - "sqrtps", - "sqrtsd", - "sqrtss", - "stac", - "stc", - "std", - "sti", - "stmxcsr", - "stos", - "stosb", - "stosd", - "stosq", - "stosw", - "str", - "sub", - "subpd", - "subps", - "subsd", - "subss", - "swapgs", - "syscall", - "sysenter", - "sysexit", - "sysret", - "test", - "tpause", - "tzcnt", - "ucomisd", - "ucomiss", - "ud", - "umonitor", - "umwait", - "unpckhpd", - "unpckhps", - "unpcklpd", - "unpcklps", - "valignd", - "valignq", - "vblendmpd", - "vblendmps", - "vbroadcast", - "vcompresspd", - "vcompressps", - "vcvtpd2qq", - "vcvtpd2udq", - "vcvtpd2uqq", - "vcvtph2ps", - "vcvtps2ph", - "vcvtps2qq", - "vcvtps2udq", - "vcvtps2uqq", - "vcvtqq2pd", - "vcvtqq2ps", - "vcvtsd2usi", - "vcvtss2usi", - "vcvttpd2qq", - "vcvttpd2udq", - "vcvttpd2uqq", - "vcvttps2qq", - "vcvttps2udq", - "vcvttps2uqq", - "vcvttsd2usi", - "vcvttss2usi", - "vcvtudq2pd", - "vcvtudq2ps", - "vcvtuqq2pd", - "vcvtuqq2ps", - "vcvtusi2sd", - "vcvtusi2ss", - "vdbpsadbw", - "verr", - "verw", - "vexpandpd", - "vexpandps", - "vextractf128", - "vextractf32x4", - "vextractf32x8", - "vextractf64x2", - "vextractf64x4", - "vextracti128", - "vextracti32x4", - "vextracti32x8", - "vextracti64x2", - "vextracti64x4", - "vfixupimmpd", - "vfixupimmps", - "vfixupimmsd", - "vfixupimmss", - "vfmadd132pd", - "vfmadd132ps", - "vfmadd132sd", - "vfmadd132ss", - "vfmadd213pd", - "vfmadd213ps", - "vfmadd213sd", - "vfmadd213ss", - "vfmadd231pd", - "vfmadd231ps", - "vfmadd231sd", - "vfmadd231ss", - "vfmaddsub132pd", - "vfmaddsub132ps", - "vfmaddsub213pd", - "vfmaddsub213ps", - "vfmaddsub231pd", - "vfmaddsub231ps", - "vfmsub132pd", - "vfmsub132ps", - "vfmsub132sd", - "vfmsub132ss", - "vfmsub213pd", - "vfmsub213ps", - "vfmsub213sd", - "vfmsub213ss", - "vfmsub231pd", - "vfmsub231ps", - "vfmsub231sd", - "vfmsub231ss", - "vfmsubadd132pd", - "vfmsubadd132ps", - "vfmsubadd213pd", - "vfmsubadd213ps", - "vfmsubadd231pd", - "vfmsubadd231ps", - "vfnmadd132pd", - "vfnmadd132ps", - "vfnmadd132sd", - "vfnmadd132ss", - "vfnmadd213pd", - "vfnmadd213ps", - "vfnmadd213sd", - "vfnmadd213ss", - "vfnmadd231pd", - "vfnmadd231ps", - "vfnmadd231sd", - "vfnmadd231ss", - "vfnmsub132pd", - "vfnmsub132ps", - "vfnmsub132sd", - "vfnmsub132ss", - "vfnmsub213pd", - "vfnmsub213ps", - "vfnmsub213sd", - "vfnmsub213ss", - "vfnmsub231pd", - "vfnmsub231ps", - "vfnmsub231sd", - "vfnmsub231ss", - "vfpclasspd", - "vfpclassps", - "vfpclasssd", - "vfpclassss", - "vgatherdpd", - "vgatherdpd", - "vgatherdps", - "vgatherdps", - "vgatherqpd", - "vgatherqpd", - "vgatherqps", - "vgatherqps", - "vgetexppd", - "vgetexpps", - "vgetexpsd", - "vgetexpss", - "vgetmantpd", - "vgetmantps", - "vgetmantsd", - "vgetmantss", - "vinsertf128", - "vinsertf32x4", - "vinsertf32x8", - "vinsertf64x2", - "vinsertf64x4", - "vinserti128", - "vinserti32x4", - "vinserti32x8", - "vinserti64x2", - "vinserti64x4", - "vmaskmov", - "vmovdqa32", - "vmovdqa64", - "vmovdqu16", - "vmovdqu32", - "vmovdqu64", - "vmovdqu8", - "vpblendd", - "vpblendmb", - "vpblendmd", - "vpblendmq", - "vpblendmw", - "vpbroadcast", - "vpbroadcastb", - "vpbroadcastd", - "vpbroadcastm", - "vpbroadcastq", - "vpbroadcastw", - "vpcmpb", - "vpcmpd", - "vpcmpq", - "vpcmpub", - "vpcmpud", - "vpcmpuq", - "vpcmpuw", - "vpcmpw", - "vpcompressd", - "vpcompressq", - "vpconflictd", - "vpconflictq", - "vperm2f128", - "vperm2i128", - "vpermb", - "vpermd", - "vpermi2b", - "vpermi2d", - "vpermi2pd", - "vpermi2ps", - "vpermi2q", - "vpermi2w", - "vpermilpd", - "vpermilps", - "vpermpd", - "vpermps", - "vpermq", - "vpermt2b", - "vpermt2d", - "vpermt2pd", - "vpermt2ps", - "vpermt2q", - "vpermt2w", - "vpermw", - "vpexpandd", - "vpexpandq", - "vpgatherdd", - "vpgatherdd", - "vpgatherdq", - "vpgatherdq", - "vpgatherqd", - "vpgatherqd", - "vpgatherqq", - "vpgatherqq", - "vplzcntd", - "vplzcntq", - "vpmadd52huq", - "vpmadd52luq", - "vpmaskmov", - "vpmovb2m", - "vpmovd2m", - "vpmovdb", - "vpmovdw", - "vpmovm2b", - "vpmovm2d", - "vpmovm2q", - "vpmovm2w", - "vpmovq2m", - "vpmovqb", - "vpmovqd", - "vpmovqw", - "vpmovsdb", - "vpmovsdw", - "vpmovsqb", - "vpmovsqd", - "vpmovsqw", - "vpmovswb", - "vpmovusdb", - "vpmovusdw", - "vpmovusqb", - "vpmovusqd", - "vpmovusqw", - "vpmovuswb", - "vpmovw2m", - "vpmovwb", - "vpmultishiftqb", - "vprold", - "vprolq", - "vprolvd", - "vprolvq", - "vprord", - "vprorq", - "vprorvd", - "vprorvq", - "vpscatterdd", - "vpscatterdq", - "vpscatterqd", - "vpscatterqq", - "vpsllvd", - "vpsllvq", - "vpsllvw", - "vpsravd", - "vpsravq", - "vpsravw", - "vpsrlvd", - "vpsrlvq", - "vpsrlvw", - "vpternlogd", - "vpternlogq", - "vptestmb", - "vptestmd", - "vptestmq", - "vptestmw", - "vptestnmb", - "vptestnmd", - "vptestnmq", - "vptestnmw", - "vrangepd", - "vrangeps", - "vrangesd", - "vrangess", - "vrcp14pd", - "vrcp14ps", - "vrcp14sd", - "vrcp14ss", - "vreducepd", - "vreduceps", - "vreducesd", - "vreducess", - "vrndscalepd", - "vrndscaleps", - "vrndscalesd", - "vrndscaless", - "vrsqrt14pd", - "vrsqrt14ps", - "vrsqrt14sd", - "vrsqrt14ss", - "vscalefpd", - "vscalefps", - "vscalefsd", - "vscalefss", - "vscatterdpd", - "vscatterdps", - "vscatterqpd", - "vscatterqps", - "vshuff32x4", - "vshuff64x2", - "vshufi32x4", - "vshufi64x2", - "vtestpd", - "vtestps", - "vzeroall", - "vzeroupper", - "wait", - "wbinvd", - "wrfsbase", - "wrgsbase", - "wrmsr", - "wrpkru", - "xabort", - "xacquire", - "xadd", - "xbegin", - "xchg", - "xend", - "xgetbv", - "xlat", - "xlatb", - "xor", - "xorpd", - "xorps", - "xrelease", - "xrstor", - "xrstors", - "xsave", - "xsavec", - "xsaveopt", - "xsaves", - "xsetbv", - "xtest" -] - -fasm_types = [ - "db", "rb", - "dw", "rw", - "dd", "rd", - "dp", "rp", - "df", "rf", - "dq", "rq", - "dt", "rt", - "du", -] - -# Dict where an identifier is assicoated with a string -# The string contains characters specifying flags -# Available flags: -# k - Keyword -# m - Macro name -# t - fasm data Type name (db, rq, etc.) -# s - Struct type name -# e - equated constant (name equ value) -# = - set constants (name = value) -ID_KIND_KEYWORD = 'k' -ID_KIND_MACRO_NAME = 'm' -ID_KIND_FASM_TYPE = 't' -ID_KIND_STRUCT_NAME = 's' -ID_KIND_EQUATED_CONSTANT = 'e' -ID_KIND_SET_CONSTANT = '=' -id2kind = {} - -# Add kind flag to identifier in id2kind -def id_add_kind(identifier, kind): - if identifier not in id2kind: - id2kind[identifier] = '' - id2kind[identifier] += kind - -# Remove kind flag of identifier in id2kind -def id_remove_kind(identifier, kind): - if identifier in id2kind: - if kind in id2kind[identifier]: - id2kind[identifier] = id2kind[identifier].replace(kind, '') - -# Get kind of an identifier -def id_get_kind(identifier): - if identifier in id2kind: - return id2kind[identifier] - else: - return '' - -for keyword in keywords: - id_add_kind(keyword, ID_KIND_KEYWORD) - -for fasm_type in fasm_types: - id_add_kind(fasm_type, ID_KIND_FASM_TYPE) - -# Warning list -warnings = "" - -# Parse arguments -parser = argparse.ArgumentParser() -parser.add_argument("-o", help="Doxygen output folder") -parser.add_argument("--clean", help="Remove generated files", action="store_true") -parser.add_argument("--dump", help="Dump all defined symbols", action="store_true") -parser.add_argument("--stats", help="Print symbol stats", action="store_true") -parser.add_argument("--nowarn", help="Do not write warnings file", action="store_true") -parser.add_argument("--noemit", help="Do not emit doxygen files (for testing)", action="store_true") -args = parser.parse_args() -doxygen_src_path = args.o if args.o else 'docs/doxygen' -clean_generated_stuff = args.clean -dump_symbols = args.dump -print_stats = args.stats -enable_warnings = not args.nowarn -noemit = args.noemit - -# Variables, functions, labels, macros, structure types -elements = [] - -class LegacyAsmReader: - def __init__(self, file): - self.file = file - self.lines = open(file, "r", encoding="utf-8").readlines() - self.line_idx = 0 - self.i = 0 - - def curr(self): - try: return self.lines[self.line_idx][self.i] - except: return '' - - def step(self): - c = self.curr() - self.i += 1 - # Wrap the line if '\\' followed by whitespaces and/or comment - while self.curr() == '\\': - i_of_backslash = self.i - self.i += 1 - while self.curr().isspace(): - self.i += 1 - if self.curr() == ';' or self.curr() == '': - self.line_idx += 1 - self.i = 0 - else: - # There's something other than a comment after the backslash - # So don't interpret the backslash as a line wrap - self.i = i_of_backslash - break - return c - - def nextline(self): - c = self.curr() - while c != '': - c = self.step() - self.line_idx += 1 - self.i = 0 - - def no_lines(self): - if self.line_idx >= len(self.lines): - return True - return False - - def location(self): - return f"{self.file}:{self.line_idx + 1}" - - def skip_spaces(self): - while self.curr().isspace(): - self.step() - -class AsmReaderRecognizingStrings(LegacyAsmReader): - def __init__(self, file): - super().__init__(file) - self.in_string = None - self.should_recognize_strings = True - - def step(self): - c = super().step() - if self.should_recognize_strings and (c == '"' or c == "'"): - # If just now we was at the double or single quotation mark - # and we aren't in a string yet - # then say "we are in a string openned with this quotation mark now" - if self.in_string == None: - self.in_string = c - # If just now we was at the double or single quotation mark - # and we are in the string entered with the same quotation mark - # then say "we aren't in a string anymore" - elif self.in_string == c: - self.in_string = None - return c - -class AsmReaderReadingComments(AsmReaderRecognizingStrings): - def __init__(self, file): - super().__init__(file) - self.status = dict() - self.status_reset() - self.comment = '' - - def status_reset(self): - # If the line has non-comment code - self.status_has_code = False - # If the line has a comment at the end - self.status_has_comment = False - # Let it recognize strings further, we are definitely out of a comment - self.should_recognize_strings = True - - def status_set_has_comment(self): - self.status_has_comment = True - # Don't let it recognize strings cause we are in a comment now - self.should_recognize_strings = False - - def status_set_has_code(self): - self.status_has_code = True - - def update_status(self): - # If we aren't in a comment and we aren't in a string - say we are now in a comment if ';' met - if not self.status_has_comment and not self.in_string and self.curr() == ';': - self.status_set_has_comment() - # Else if we are in a comment - collect the comment - elif self.status_has_comment: - self.comment += self.curr() - # Else if there's some non-whitespace character out of a comment - # then the line has code - elif not self.status_has_comment and not self.curr().isspace(): - self.status_set_has_code() - - def step(self): - # Get to the next character - c = super().step() - # Update status of the line according to the next character - self.update_status() - return c - - def nextline(self): - super().nextline() - # If the line we leave was not a comment-only line - # then forget the collected comment - # Otherwise the collected comment should be complemented by comment from next line in step() - if self.status_has_code: - self.comment = '' - # Reset the line status (now it's the status of the new line) - self.status_reset() - # Set new status for this line according to the first character in the line - self.update_status() - -class AsmReaderFetchingIdentifiers(AsmReaderReadingComments): - def __init__(self, file): - super().__init__(file) - - def fetch_identifier(self): - self.skip_spaces() - result = '' - while is_id(self.curr()): - result += self.step() - return result - -class AsmReader(AsmReaderFetchingIdentifiers): - def __init__(self, file): - super().__init__(file) - -created_files = [] - -class AsmElement: - def __init__(self, location, name, comment): - global warnings - - self.location = location - self.file = self.location.split(':')[0].replace('\\', '/') - self.line = self.location.split(':')[1] - self.name = name - self.comment = comment - - if self.comment == '': - warnings += f'{self.location}: Undocumented element\n' - - def dump(self): - print(f"{self.comment}") - print(f"{self.location}: {self.name}") - - def emit(self, dest, doxycomment = '', declaration = ''): - # Do not emit anything if the symbol is marked as hidden in its comment - if '@dont_give_a_doxygen' in self.comment: - return - - global warnings - # Redefine default declaration - if declaration == '': - declaration = f'#define {self.name}' - # Check doxycomment - if not doxycomment.endswith('\n'): - doxycomment += '\n' - if doxycomment.split('@brief ')[1][0].islower(): - warnings += f"{self.location}: Brief comment starting from lowercase\n" - # Build contents to emit - contents = '' - contents += '/**\n' - contents += doxycomment - contents += (f"@par Source\n" + - f"{self.file}:{self.line}\n") - contents += '*/\n' - contents += declaration - contents += '\n\n' - # Get path to file to emit this - full_path = dest + '/' + self.file - # Remove the file on first access if it was created by previous generation - if full_path not in created_files: - if os.path.isfile(full_path): - os.remove(full_path) - created_files.append(full_path) - # Create directories need for the file - os.makedirs(os.path.dirname(full_path), exist_ok=True) - f = open(full_path, "a") - contents = ''.join([i if ord(i) < 128 else '?' for i in contents]) - f.write(contents) - f.close() - -class AsmVariable(AsmElement): - def __init__(self, location, name, comment, type, init): - super().__init__(location, name, comment) - self.type = type - self.init = init - - def dump(self): - super().dump() - print(f"Variable") - - def emit(self, dest): - # Build doxycomment specific for the variable - doxycomment = '' - doxycomment += self.comment - if '@brief' not in doxycomment: - doxycomment = '@brief ' + doxycomment - doxycomment += (f"@par Initial value\n" + - f"{self.init}\n") - # Build the declaration - name = self.name.replace(".", "_") - var_type = self.type.replace(".", "_") - declaration = f"{var_type} {name};" - # Emit this - super().emit(dest, doxycomment, declaration) - -class AsmFunction(AsmElement): - def __init__(self, location, name, comment, calling_convention, args, used_regs): - super().__init__(location, name, comment) - self.calling_convention = calling_convention - self.args = args - self.used_regs = used_regs - - def dump(self): - super().dump() - print(f"Function") - - def emit(self, dest): - # Build doxycomment specific for the variable - doxycomment = '' - doxycomment += self.comment - if '@brief' not in doxycomment: - doxycomment = '@brief ' + doxycomment - # Build the arg list for declaration - arg_list = '(' - if len(self.args) > 0: - argc = 0 - for arg in self.args: - if argc != 0: - arg_list += ", " - arg_list += f"{arg[1]} {arg[0]}" - argc += 1 - arg_list += ')' - # Build the declaration - name = self.name.replace(".", "_") - declaration = f"void {name}{arg_list};" - # Emit this - super().emit(dest, doxycomment, declaration) - -class AsmLabel(AsmElement): - def __init__(self, location, name, comment): - super().__init__(location, name, comment) - - def dump(self): - super().dump() - print(f"Label") - - def emit(self, dest): - # Build doxycomment specific for the variable - doxycomment = '' - doxycomment += self.comment - if '@brief' not in doxycomment: - doxycomment = '@brief ' + doxycomment - # Build the declaration - name = self.name.replace(".", "_") - declaration = f"label {name};" - # Emit this - super().emit(dest, doxycomment, declaration) - -class AsmMacro(AsmElement): - def __init__(self, location, name, comment, args): - super().__init__(location, name, comment) - self.args = args - - def dump(self): - super().dump() - print(f"Macro") - print(f"Parameters: {self.args}") - - def emit(self, dest): - # Construct arg list without '['s, ']'s and '*'s - args = [arg for arg in self.args if arg not in "[]*"] - # Construct C-like arg list - arg_list = "" - if len(args) > 0: - arg_list += '(' - argc = 0 - for arg in args: - if argc != 0: - arg_list += ", " - arg_list += arg - argc += 1 - arg_list += ')' - # Build doxycomment - doxycomment = '' - doxycomment += self.comment - if '@brief' not in doxycomment: - doxycomment = '@brief ' + doxycomment - # Build declaration - declaration = f"#define {self.name}{arg_list}" - # Emit this - super().emit(dest, doxycomment, declaration) - -class AsmStruct(AsmElement): - def __init__(self, location, name, comment, members): - super().__init__(location, name, comment) - self.members = members - - def dump(self): - super().dump() - print(f"Struct") - - def emit(self, dest): - # Build doxycomment - doxycomment = '' - doxycomment += self.comment - if '@brief' not in doxycomment: - doxycomment = '@brief ' + doxycomment - doxycomment += '\n' - # Build declaration - declaration = f"struct {self.name}" + " {\n" - for member in self.members: - if type(member) == AsmVariable: - declaration += f'\t{member.type} {member.name}; /**< {member.comment} */\n' - declaration += '};' - # Emit this - super().emit(dest, doxycomment, declaration) - -class AsmUnion(AsmElement): - def __init__(self, location, name, comment, members): - super().__init__(location, name, comment) - self.members = members - - def dump(self): - super().dump() - print(f"Union") - - def emit(self, dest): - # Build doxycomment - doxycomment = '' - doxycomment += self.comment - if '@brief' not in doxycomment: - doxycomment = '@brief ' + doxycomment - # Build declaration - declaration = f"union {self.name}" + " {};" - # Emit this - super().emit(dest, doxycomment, declaration) - -class VariableNameIsMacroName: - def __init__(self, name): - self.name = name - -def is_id(c): - return c.isprintable() and c not in "+-/*=<>()[]{};:,|&~#`'\" \n\r\t\v" - -def is_starts_as_id(s): - return not s[0].isdigit() - -def parse_after_macro(r): - location = r.location() - - # Skip spaces after the "macro" keyword - r.skip_spaces() - # Read macro name - name = "" - while is_id(r.curr()) or r.curr() == '#': - name += r.step() - # Skip spaces after macro name - r.skip_spaces() - # Find all arguments - args = [] - arg = '' - while r.curr() and r.curr() != ';' and r.curr() != '{': - # Collect identifier - if is_id(r.curr()): - arg += r.step() - # Save the collected identifier - elif r.curr() == ',': - args.append(arg) - arg = '' - r.step() - # Just push the '[' - elif r.curr() == '[': - args.append(r.step()) - # Just push the identifier and get ']' ready to be pushed on next comma - elif r.curr() == ']': - args.append(arg) - arg = r.step() - # Just push the identifier and get '*' ready to be pushed on next comma - elif r.curr() == '*': - args.append(arg) - arg = r.step() - # Just skip whitespaces - elif r.curr().isspace(): - r.step() - # Something unexpected - else: - raise Exception(f"Unexpected symbol '{r.curr()}' at index #{r.i} " + - f"in the macro declaration at {location} " + - f"(line: {r.lines[r.line_idx]})\n''") - # Append the last argument - if arg != '': - args.append(arg) - # Skip t spaces after the argument list - r.skip_spaces() - # Get a comment if it is: read till the end of the line and get the comment from the reader - while r.curr() != '': - r.step() - comment = r.comment - # Find end of the macro - prev = '' - while True: - if r.curr() == '}' and prev != '\\': - break - elif r.curr() == '': - prev = '' - r.nextline() - continue - prev = r.step() - # Build the output - return AsmMacro(location, name, comment, args) - -def parse_variable(r, first_word = None): - global warnings - location = r.location() - - # Skip spaces before variable name - r.skip_spaces() - # Get variable name - name = "" - # Read it if it was not supplied - if first_word == None: - while is_id(r.curr()): - name += r.step() - # Or use the supplied one instead - else: - name = first_word - # Check the name - # If it's 0 len, that means threr's something else than an identifier at the beginning - if len(name) == 0: - return None - # If it starts from digit or othervice illegally it's illegal - if not is_starts_as_id(name): - return None - # Get kind of the identifier from id2kind table - kind = id_get_kind(name) - # If it's a keyword, that's not a variable declaration - if ID_KIND_KEYWORD in kind: - return None - # If it's a macro name, that's not a variable declaration - if ID_KIND_MACRO_NAME in kind: - return VariableNameIsMacroName(name) - # If it's a datatype or a structure name that's not a variable declaration: that's just a data - # don't document just a data for now - if ID_KIND_STRUCT_NAME in kind or ID_KIND_FASM_TYPE in kind: - return None - # Skip spaces before type name - r.skip_spaces() - # Read type name - var_type = "" - while is_id(r.curr()): - var_type += r.step() - # Check the type name - if len(var_type) == 0: - # If there's no type identifier after the name - # maybe the name is something meaningful for the next parser - # return it - return name - # If it starts from digit or othervice illegally it's illegal - if not is_starts_as_id(var_type): - return None - # Get kind of type identifier - type_kind = id_get_kind(var_type) - # If it's a keyword, that's not a variable declaration - # return the two words of the lexical structure - if ID_KIND_KEYWORD in type_kind: - return (name, var_type) - # Skip spaces before the value - r.skip_spaces() - # Read the value until the comment or end of the line - value = "" - while r.curr() != ';' and r.curr() != '' and r.curr() != '\n': - value += r.step() - # Skip spaces after the value - r.skip_spaces() - # Read till end of the line to get a comment from the reader - while r.curr() != '': - r.step() - # Build the result - return AsmVariable(location, name, r.comment, var_type, value) - -def parse_after_struct(r, as_union = True): - global warnings - location = r.location() - - # Skip spaces after "struct" keyword - r.skip_spaces() - # Read struct name - name = "" - while is_id(r.curr()): - name += r.step() - # Read till end of the line and get the comment from the reader - while r.curr() != '': - r.step() - comment = r.comment - # Get to the next line to parse struct members - r.nextline() - # Parse struct members - members = [] - while True: - r.skip_spaces() - var = parse_variable(r) - if type(var) == AsmVariable: - members.append(var) - elif type(var) == str: - if var == 'union': - # Parse the union as a struct - union = parse_after_struct(r, as_union = True) - members.append(union) - # Skip the ends of the union - r.nextline() - elif r.curr() == ':': - warnings += f"{r.location()}: Skept the label in the struct\n" - else: - raise Exception(f"Garbage in struct member at {location} (got '{var}' identifier)") - elif type(var) == VariableNameIsMacroName: - if var.name == 'ends': - break - r.nextline() - # Return the result - if as_union: - return AsmStruct(location, name, comment, members) - else: - return AsmUnion(location, name, comment, members) - -def parse_after_proc(r): - # Get proc name - name = r.fetch_identifier() - # Next identifier after the proc name - identifier = r.fetch_identifier() - # Check if the id is 'stdcall' or 'c' (calling convention specifier) - # and if so - save the convention and lookup the next identifier - calling_convention = '' - if identifier == 'stdcall' or identifier == 'c': - calling_convention = identifier - # If next is a comma, just skip it - if r.curr() == ',': - r.step() - # Read the next identifier - identifier = r.fetch_identifier() - # Check if the id is 'uses' (used register list specifier) - # and if so save the used register list - used_regs = [] - if identifier == 'uses': - # Read the registers - while True: - reg_name = r.fetch_identifier() - if reg_name != '': - used_regs.append(reg_name) - else: - break - # If next is a comma, just skip it - if r.curr() == ',': - r.step() - # Read the next identifier - identifier = r.fetch_identifier() - # Check if there are argument identifiers - args = [] - while identifier != '': - arg_name = identifier - arg_type = 'arg_t' - # Skip spaces after argument name - r.skip_spaces() - # If there's a ':' after the name - the next identifier is type - if r.curr() == ':': - r.step() - arg_type = r.fetch_identifier() - # If there's a comma - there's one more argument - # else no arguments anymore - if r.curr() == ',': - r.step() - identifier = r.fetch_identifier() - else: - identifier = '' - args.append((arg_name, arg_type)) - # Get to the end of the line and get a comment from the reader - while r.curr() != '': - r.step() - comment = r.comment - # Build the element - return AsmFunction(r.location(), name, comment, calling_convention, args, used_regs) - -def get_declarations(asm_file_contents, asm_file_name): - r = AsmReader(asm_file_name) - - while not r.no_lines(): - # Skip leading spaces - r.skip_spaces() - # Skip the line if it's starting with a comment - if r.curr() == ';': - r.nextline() - continue - # Get first word - first_word = "" - while is_id(r.curr()): - first_word += r.step() - # Match macro declaration - if first_word == "macro": - macro = parse_after_macro(r) - elements.append(macro) - id_add_kind(macro.name, ID_KIND_MACRO_NAME) - # Match structure declaration - elif first_word == "struct": - struct = parse_after_struct(r) - elements.append(struct) - id_add_kind(struct.name, ID_KIND_STRUCT_NAME) - # Match function definition - elif first_word == "proc": - proc = parse_after_proc(r) - elements.append(proc) - elif first_word == 'format': - # Skip the format directive - pass - elif first_word == 'include': - # Skip the include directive - pass - elif first_word == 'if': - # Skip the conditional directive - pass - elif first_word == 'repeat': - # Skip the repeat directive - pass - elif first_word == 'purge': - while True: - # Skip spaces after the 'purge' keyword or after the comma what separated the previous macro name - r.skip_spaces() - # Get the purged macro name - name = '' - while is_id(r.curr()): - name += r.step() - # Remove the purged macro from the macro names list - try: - id_remove_kind(name, ID_KIND_MACRO_NAME) - except: - pass - # Skip spaces after the name - r.skip_spaces() - # If it's comma (',') after then that's not the last purged macro, continue purging - if r.curr() == ',': - r.step() - continue - # Here we purged all the macros should be purged - break - # Match label or a variable - elif len(first_word) != 0: - # Skip spaces after the identifier - r.skip_spaces() - # Match a variable - var = parse_variable(r, first_word) - if type(var) == AsmVariable: - elements.append(var) - # If it wasn't a variable but there was an identifier - # Maybe that's a label and the identifier is the label name - # The parse_variable returns the first found or supplied identifier - # In this case it returns the first_word which is supplied - # If it didn't match a type identifier after the word - elif type(var) == str: - name = var - # Match label beginning (':' after name) - if r.curr() == ':': - # Get to the end of the line and get the coment from the reader - while r.curr() != '': - r.step() - comment = r.comment - # Only handle non-local labels - if name[0] != '.' and name != "@@" and name != "$Revision": - elements.append(AsmLabel(r.location(), name, comment)) - elif r.curr() == '=': - # Save the identifier as a set constant - id_add_kind(first_word, ID_KIND_SET_CONSTANT) - elif type(var) == tuple: - (word_one, word_two) = var - if word_two == 'equ': - # Save the identifier as an equated constant - id_add_kind(word_one, ID_KIND_EQUATED_CONSTANT) - r.nextline() - -def it_neds_to_be_parsed(source_file): - dest = doxygen_src_path + '/' + source_file - # If there's no the doxygen file it should be compiled to - # then yes, we should compile it to doxygen - if not os.path.isfile(dest): - return True - source_change_time = os.path.getmtime(source_file) - dest_change_file = os.path.getmtime(dest) - # If the source is newer than the doxygen it was compiled to - # then the source should be recompiled (existing doxygen is old) - if source_change_time > dest_change_file: - return True - return False - -def handle_file(handled_files, asm_file_name, subdir = "."): - # Canonicalize the file path and get it relative to cwd - cwd = os.path.abspath(os.path.dirname(sys.argv[0])) - asm_file_name = os.path.realpath(asm_file_name) - asm_file_name = asm_file_name[len(cwd) + 1:] - # If it's lang.inc - skip it - if asm_file_name == 'lang.inc': - return - # If the file was handled in this execution before - skip it - if asm_file_name in handled_files: - return - # Say that the file was handled in this execution - handled_files.append(asm_file_name) - # Check if the file should be parsed (if it was modified or wasn't parsed yet) - should_get_declarations = True - if not it_neds_to_be_parsed(asm_file_name): - print(f"Skipping {asm_file_name} (already newest)") - should_get_declarations = False - else: - print(f"Handling {asm_file_name}") - # Read the source - asm_file_contents = open(asm_file_name, "r", encoding="utf-8").read() - # Find includes, fix their paths and handle em recoursively - includes = re.findall(r'^include (["\'])(.*)\1', asm_file_contents, flags=re.MULTILINE) - for include in includes: - include = include[1].replace('\\', '/'); - full_path = subdir + '/' + include; - # If the path isn't valid, maybe that's not relative path - if not os.path.isfile(full_path): - full_path = include - new_subdir = full_path.rsplit('/', 1)[0] - handle_file(handled_files, full_path, new_subdir) - # Only collect declarations from the file if it wasn't parsed before - if should_get_declarations and not clean_generated_stuff: - get_declarations(asm_file_contents, asm_file_name) - -kernel_files = [] - -handle_file(kernel_files, "./kernel.asm"); - -if dump_symbols: - for asm_element in elements: - asm_element.dump() - -if clean_generated_stuff: - kernel_files_set = set(kernel_files) - for file in kernel_files: - doxygen_file = f"{doxygen_src_path}/{file}" - if (os.path.isfile(doxygen_file)): - print(f"Removing {file}... ", end = '') - os.remove(doxygen_file) - print("Done.") -elif not noemit: - print(f"Writing doumented sources to {doxygen_src_path}") - - i = 0 - for element in elements: - print(f"[{i + 1}/{len(elements)}] Emitting {element.name} from {element.location}") - element.emit(doxygen_src_path) - i += 1 - -if print_stats: - var_count = 0 - mac_count = 0 - lab_count = 0 - fun_count = 0 - uni_count = 0 - str_count = 0 - for element in elements: - if type(element) == AsmVariable: - var_count += 1 - elif type(element) == AsmMacro: - mac_count += 1 - elif type(element) == AsmLabel: - lab_count += 1 - elif type(element) == AsmFunction: - fun_count += 1 - elif type(element) == AsmUnion: - uni_count += 1 - elif type(element) == AsmStruct: - str_count += 1 - print(f'Parsed variable count: {var_count}') - print(f'Parsed macro count: {mac_count}') - print(f'Parsed label count: {lab_count}') - print(f'Parsed function count: {fun_count}') - print(f'Parsed union type count: {uni_count}') - print(f'Parsed structure type count: {str_count}') - -if enable_warnings: - open('asmxygen.txt', "w", encoding = "utf-8").write(warnings) diff --git a/kernel/branches/Kolibri-F/blkdev/bd_drv.inc b/kernel/branches/Kolibri-F/blkdev/bd_drv.inc deleted file mode 100644 index 1e0580329..000000000 --- a/kernel/branches/Kolibri-F/blkdev/bd_drv.inc +++ /dev/null @@ -1,301 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; Disk access through BIOS -iglobal -align 4 -bd_callbacks: - dd bd_callbacks.end - bd_callbacks ; strucsize - dd 0 ; no close function - dd 0 ; no closemedia function - dd bd_querymedia - dd bd_read_interface - dd bd_write_interface - dd 0 ; no flush function - dd 0 ; use default cache size -.end: -endg - -uglobal -bios_hdpos dd 0 -bios_cur_sector dd ? -bios_read_len dd ? -cache_chain_ptr dd ? -int13_regs_in rb sizeof.v86_regs -int13_regs_out rb sizeof.v86_regs -cache_chain_size db ? -endg - -struct BiosDiskData - DriveNumber db ? - IRQ db ? - ATADEVbit dw ? - SectorSize dd ? - Capacity dq ? -ends -;----------------------------------------------------------------- -proc bd_read_interface stdcall uses edi, \ - userdata, buffer, startsector:qword, numsectors - ; userdata = old [hdpos] = 80h + index in NumBiosDisks - ; buffer = pointer to buffer for data - ; startsector = 64-bit start sector - ; numsectors = pointer to number of sectors on input, - ; must be filled with number of sectors really read -locals -sectors_todo dd ? -endl -; 1. Initialize number of sectors: get number of requested sectors -; and say that no sectors were read yet. - mov ecx, [numsectors] - mov eax, [ecx] - mov dword [ecx], 0 - mov [sectors_todo], eax -; 2. Acquire the global lock. - mov ecx, ide_mutex - call mutex_lock -; 3. Convert parameters to the form suitable for worker procedures. -; Underlying procedures do not know about 64-bit sectors. -; Worker procedures use global variables and edi for [buffer]. - cmp dword [startsector+4], 0 - jnz .fail - and [hd_error], 0 - mov eax, [userdata] - mov [hdpos], eax - mov eax, dword [startsector] - mov edi, [buffer] -; 4. Worker procedures take one sectors per time, so loop over all sectors to read. -.sectors_loop: - call bd_read - cmp [hd_error], 0 - jnz .fail - mov ecx, [numsectors] - inc dword [ecx] ; one more sector is read - dec [sectors_todo] - jz .done - inc eax - jnz .sectors_loop -; 5. Loop is done, either due to error or because everything is done. -; Release the global lock and return the corresponding status. -.fail: - mov ecx, ide_mutex - call mutex_unlock - or eax, -1 - ret -.done: - mov ecx, ide_mutex - call mutex_unlock - xor eax, eax - ret -endp -;----------------------------------------------------------------- -proc bd_write_interface stdcall uses esi edi, \ - userdata, buffer, startsector:qword, numsectors - ; userdata = old [hdpos] = 80h + index in NumBiosDisks - ; buffer = pointer to buffer with data - ; startsector = 64-bit start sector - ; numsectors = pointer to number of sectors on input, - ; must be filled with number of sectors really written -locals -sectors_todo dd ? -endl -; 1. Initialize number of sectors: get number of requested sectors -; and say that no sectors were read yet. - mov ecx, [numsectors] - mov eax, [ecx] - mov dword [ecx], 0 - mov [sectors_todo], eax -; 2. Acquire the global lock. - mov ecx, ide_mutex - call mutex_lock -; 3. Convert parameters to the form suitable for worker procedures. -; Underlying procedures do not know about 64-bit sectors. -; Worker procedures use global variables and esi for [buffer]. - cmp dword [startsector+4], 0 - jnz .fail - and [hd_error], 0 - mov eax, [userdata] - mov [hdpos], eax - mov esi, [buffer] - lea edi, [startsector] - mov [cache_chain_ptr], edi -; 4. Worker procedures take max 16 sectors per time, -; loop until all sectors will be processed. -.sectors_loop: - mov ecx, 16 - cmp ecx, [sectors_todo] - jbe @f - mov ecx, [sectors_todo] -@@: - mov [cache_chain_size], cl - call bd_write_cache_chain - cmp [hd_error], 0 - jnz .fail - movzx ecx, [cache_chain_size] - mov eax, [numsectors] - add [eax], ecx - sub [sectors_todo], ecx - jz .done - add [edi], ecx - jc .fail - shl ecx, 9 - add esi, ecx - jmp .sectors_loop -; 5. Loop is done, either due to error or because everything is done. -; Release the global lock and return the corresponding status. -.fail: - mov ecx, ide_mutex - call mutex_unlock - or eax, -1 - ret -.done: - mov ecx, ide_mutex - call mutex_unlock - xor eax, eax - ret -endp -;----------------------------------------------------------------- -proc bd_querymedia stdcall, hd_data, mediainfo - mov edx, [mediainfo] - mov eax, [hd_data] - lea eax, [(eax-80h)*4] - lea eax, [BiosDisksData+eax*4] - mov [edx+DISKMEDIAINFO.Flags], 0 - mov ecx, [eax+BiosDiskData.SectorSize] - mov [edx+DISKMEDIAINFO.SectorSize], ecx - mov ecx, dword [eax+BiosDiskData.Capacity+0] - mov eax, dword [eax+BiosDiskData.Capacity+4] - mov dword [edx+DISKMEDIAINFO.Capacity+0], ecx - mov dword [edx+DISKMEDIAINFO.Capacity+4], eax - xor eax, eax - ret -endp -;----------------------------------------------------------------- -bd_read: - push eax - push edx - mov edx, [bios_hdpos] - cmp edx, [hdpos] - jne .notread - mov edx, [bios_cur_sector] - cmp eax, edx - jb .notread - add edx, [bios_read_len] - dec edx - cmp eax, edx - ja .notread - sub eax, [bios_cur_sector] - shl eax, 9 - add eax, (OS_BASE+0x99000) - push ecx esi - mov esi, eax - mov ecx, 512/4 - cld - rep movsd - pop esi ecx - pop edx - pop eax - ret -.notread: - push ecx - mov dl, 42h - mov ecx, 16 - call int13_call - pop ecx - test eax, eax - jnz .v86err - test edx, edx - jz .readerr - mov [bios_read_len], edx - mov edx, [hdpos] - mov [bios_hdpos], edx - pop edx - pop eax - mov [bios_cur_sector], eax - jmp bd_read -.readerr: -.v86err: - pop edx - pop eax - mov [hd_error], 1 - jmp hd_read_error -;----------------------------------------------------------------- -bd_write_cache_chain: - pusha - mov edi, OS_BASE + 0x99000 - movzx ecx, [cache_chain_size] - push ecx - shl ecx, 9-2 - rep movsd - pop ecx - mov dl, 43h - mov eax, [cache_chain_ptr] - mov eax, [eax] - call int13_call - test eax, eax - jnz .v86err - cmp edx, ecx - jnz .writeerr - popa - ret -.v86err: -.writeerr: - popa - mov [hd_error], 1 - jmp hd_write_error -;----------------------------------------------------------------- -int13_call: -; Because this code uses fixed addresses, -; it can not be run simultaniously by many threads. -; In current implementation it is protected by common mutex 'ide_status' - mov word [OS_BASE + 510h], 10h ; packet length - mov word [OS_BASE + 512h], cx ; number of sectors - mov dword [OS_BASE + 514h], 99000000h ; buffer 9900:0000 - mov dword [OS_BASE + 518h], eax - and dword [OS_BASE + 51Ch], 0 - push ebx ecx esi edi - mov ebx, int13_regs_in - mov edi, ebx - mov ecx, sizeof.v86_regs/4 - xor eax, eax - rep stosd - mov byte [ebx+v86_regs.eax+1], dl - mov eax, [hdpos] - lea eax, [(eax-80h)*4] - lea eax, [BiosDisksData+eax*4] - mov dl, [eax] - mov byte [ebx+v86_regs.edx], dl - movzx edx, byte [eax+1] -; mov dl, 5 - test edx, edx - jnz .hasirq - dec edx - jmp @f -.hasirq: - pushad - stdcall enable_irq, edx - popad -@@: - mov word [ebx+v86_regs.esi], 510h - mov word [ebx+v86_regs.ss], 9000h - mov word [ebx+v86_regs.esp], 09000h - mov word [ebx+v86_regs.eip], 500h - mov [ebx+v86_regs.eflags], 20200h - mov esi, [sys_v86_machine] - mov ecx, 0x502 - push fs - call v86_start - pop fs - and [bios_hdpos], 0 - pop edi esi ecx ebx - movzx edx, byte [OS_BASE + 512h] - test byte [int13_regs_out+v86_regs.eflags], 1 - jnz @f - mov edx, ecx -@@: - ret diff --git a/kernel/branches/Kolibri-F/blkdev/cd_drv.inc b/kernel/branches/Kolibri-F/blkdev/cd_drv.inc deleted file mode 100644 index 8e8a5b1c0..000000000 --- a/kernel/branches/Kolibri-F/blkdev/cd_drv.inc +++ /dev/null @@ -1,1218 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -;----------------------------------------------------------------------------- -;********************************************************** -; Direct work with CD (ATAPI) device -;********************************************************** -; Author of a part of the source code - Kulakov Vladimir Gennadievich -; Adaptation, revision and development - Mario79, - -; Maximum number of repeats of a read operation -MaxRetr = 10 -; Maximum waiting time for ready to receive a command -; (in ticks) -BSYWaitTime = 1000 ;2 -NoTickWaitTime = 0xfffff -CDBlockSize = 2048 -;******************************************** -;* READING SECTOR WITH REPEATS * -;* Repeated reads on failures * -;******************************************** -ReadCDWRetr: -;----------------------------------------------------------- -; input : eax = block to read -; ebx = destination -;----------------------------------------------------------- - pushad - mov eax, [CDSectorAddress] - mov ebx, [CDDataBuf_pointer] - call cd_calculate_cache - xor edi, edi - add esi, 8 - inc edi -;-------------------------------------- -align 4 -.hdreadcache: - cmp [esi], eax ; correct sector - je .yeshdcache - - add esi, 8 - inc edi - dec ecx - jnz .hdreadcache - - call find_empty_slot_CD_cache ; ret in edi - - push edi - push eax - call cd_calculate_cache_2 - shl edi, 11 - add edi, eax - mov [CDDataBuf_pointer], edi - pop eax - pop edi - - call ReadCDWRetr_1 - cmp [DevErrorCode], 0 - jne .exit - - mov [CDDataBuf_pointer], ebx - call cd_calculate_cache_1 - lea esi, [edi*8+esi] - mov [esi], eax ; sector number -;-------------------------------------- -.yeshdcache: - mov esi, edi - shl esi, 11 ;9 - push eax - call cd_calculate_cache_2 - add esi, eax - pop eax - mov edi, ebx ;[CDDataBuf_pointer] - mov ecx, 512 ;/4 - cld - rep movsd ; move data -;-------------------------------------- -.exit: - popad - ret -;----------------------------------------------------------------------------- -ReadCDWRetr_1: - pushad -; Loop until the command is successful or the number of attempts is over - mov ecx, MaxRetr -;-------------------------------------- -align 4 -@@NextRetr: -; Send a command -;************************************************* -;* FULL READ OF COMPACT DISK SECTOR * -;* User data, subchannel * -;* information and control information are read * -;* Input parameters are passed through global * -;* variables: * -;* ChannelNumber - channel number; * -;* DiskNumber - disc number on channel; * -;* CDSectorAddress - address of reading sector. * -;* The data is read into the CDDataBuf array. * -;************************************************* -;ReadCD: - push ecx -; Flush the packet command buffer - call clear_packet_buffer -; Generate a packet command to read a data sector -; Set the command code Read CD - mov [PacketCommand], byte 0x28 ;0xBE -; Set the sector address - mov ax, word [CDSectorAddress+2] - xchg al, ah - mov word [PacketCommand+2], ax - mov ax, word [CDSectorAddress] - xchg al, ah - mov word [PacketCommand+4], ax -; Set the number of sectors to read - mov [PacketCommand+8], byte 1 -; Send a command - call SendPacketDatCommand - pop ecx - - test eax, eax - jz @@End_4 - - or ecx, ecx ;{SPraid.simba} (for cd load) - jz @@End_4 - - dec ecx - - cmp [timer_ticks_enable], 0 - jne @f - - mov eax, NoTickWaitTime -;-------------------------------------- -align 4 -.wait: - dec eax - jz @@NextRetr - - jmp .wait -;-------------------------------------- -align 4 -@@: - loop @@NextRetr -;-------------------------------------- -@@End_4: - mov dword [DevErrorCode], eax - popad - ret -;----------------------------------------------------------------------------- -; General purpose procedures to execute packet commands in PIO Mode -; Maximum allowable waiting time for the device to respond to a packet command (in ticks) -;----------------------------------------------------------------------------- -MaxCDWaitTime = 1000 ;200 ;10 seconds -uglobal -; Memory area for generating a packet command -PacketCommand: - rb 12 ;DB 12 DUP (?) -; address of reading data sector -CDSectorAddress: dd ? -; Start time of the next disk operation -TickCounter_1 dd 0 -; Time to start waiting for device readiness -WURStartTime dd 0 -; pointer to buffer to read data into -CDDataBuf_pointer dd 0 -endg -;----------------------------------------------------------------------------- -;**************************************************** -;* SEND TO ATAPI DEVICE PACKET COMMAND, * -;* THAT MEANS TRASMIT ONE DATA SECTOR OF SIZE * -;* 2048 BYTE FROM DEVICE TO HOST * -;* Input parameters are passed through global * -;* variables: * -;* ChannelNumber - channel number; * -;* DiskNumber - disk number on channel. * -;* PacketCommand - 12-byte command packet; * -;* CDBlockSize - size of receiving data block. * -; return eax DevErrorCode -;**************************************************** -SendPacketDatCommand: - xor eax, eax -; Set CHS mode - mov byte [ATAAddressMode], al -; Send ATA command to send packet command - mov byte [ATAFeatures], al - mov byte [ATASectorCount], al - mov byte [ATASectorNumber], al -; Load the size of the sending block - mov [ATAHead], al - mov [ATACylinder], CDBlockSize - mov [ATACommand], 0xA0 - call SendCommandToHDD_1 - test eax, eax - jnz @@End_8 ; finish, saving the error code -; Waiting for the drive to be ready to receive a packet command - mov dx, [ATABasePortAddr] - add dx, 7 ; port 1x7h - mov ecx, NoTickWaitTime -;-------------------------------------- -align 4 -@@WaitDevice0: - cmp [timer_ticks_enable], 0 - jne @f - - dec ecx - jz @@Err1_1 - - jmp .test -;-------------------------------------- -align 4 -@@: - call change_task - ; Check command execution time - mov eax, [timer_ticks] - sub eax, [TickCounter_1] - cmp eax, BSYWaitTime - ja @@Err1_1 ; time out error - ; Check readiness -;-------------------------------------- -align 4 -.test: - in al, dx - test al, 0x80 ; BSY signal state - jnz @@WaitDevice0 - - test al, 1 ; ERR signal state - jnz @@Err6 - - test al, 0x8 ; DRQ signal state - jz @@WaitDevice0 -; Send a packet command - cli - mov dx, [ATABasePortAddr] - mov ax, [PacketCommand] - out dx, ax - mov ax, [PacketCommand+2] - out dx, ax - mov ax, [PacketCommand+4] - out dx, ax - mov ax, [PacketCommand+6] - out dx, ax - mov ax, [PacketCommand+8] - out dx, ax - mov ax, [PacketCommand+10] - out dx, ax - sti -; Waiting for data to be ready - mov dx, [ATABasePortAddr] - add dx, 7 ; port 1x7h - mov ecx, NoTickWaitTime -;-------------------------------------- -align 4 -@@WaitDevice1: - cmp [timer_ticks_enable], 0 - jne @f - - dec ecx - jz @@Err1_1 - - jmp .test_1 -;-------------------------------------- -align 4 -@@: - call change_task - ; Check command execution time - mov eax, [timer_ticks] - sub eax, [TickCounter_1] - cmp eax, MaxCDWaitTime - ja @@Err1_1 ; time out error - ; Check readiness -;-------------------------------------- -align 4 -.test_1: - in al, dx - test al, 0x80 ; BSY signal state - jnz @@WaitDevice1 - - test al, 1 ; ERR signal state - jnz @@Err6_temp - - test al, 0x8 ; DRQ signal state - jz @@WaitDevice1 -; Receive data block from controller - mov edi, [CDDataBuf_pointer] - ; Load controller's data register address - mov dx, [ATABasePortAddr] - ; Load the block size in bytes into the counter - xor ecx, ecx - mov cx, CDBlockSize - ; Calculate block size in 16-bit words - shr cx, 1 ; divide block size by 2 - ; Receive data block - cli - cld - rep insw - sti -;-------------------------------------- -; Successful completion of data receive -@@End_8: - xor eax, eax - ret -;-------------------------------------- -; Write error code -@@Err1_1: - xor eax, eax - inc eax - ret -;-------------------------------------- -@@Err6_temp: - mov eax, 7 - ret -;-------------------------------------- -@@Err6: - mov eax, 6 - ret -;----------------------------------------------------------------------------- -;*********************************************** -;* SEND TO ATAPI DEVICE PACKET COMMAND, * -;* THAT DOESNT MEAN TRANSMIT DATA * -;* Input parameters are passed through global * -;* variables: * -;* ChannelNumber - channel number; * -;* DiskNumber - disk number on channel. * -;* PacketCommand - 12-byte command packet. * -;*********************************************** -SendPacketNoDatCommand: - pushad - xor eax, eax -; Set CHS mode - mov byte [ATAAddressMode], al -; Send ATA command to send packet command - mov byte [ATAFeatures], al - mov byte [ATASectorCount], al - mov byte [ATASectorNumber], al - mov word [ATACylinder], ax - mov byte [ATAHead], al - mov [ATACommand], 0xA0 - call SendCommandToHDD_1 - test eax, eax - jnz @@End_9 ; finish, saving the error code -; Waiting for the drive to be ready to receive a packet command - mov dx, [ATABasePortAddr] - add dx, 7 ; port 1x7h -;-------------------------------------- -align 4 -@@WaitDevice0_1: - call change_task - ; Check waiting time - mov eax, [timer_ticks] - sub eax, [TickCounter_1] - cmp eax, BSYWaitTime - ja @@Err1_3 ; time out error - ; Check readiness - in al, dx - test al, 0x80 ; BSY signal state - jnz @@WaitDevice0_1 - - test al, 1 ; ERR signal state - jnz @@Err6_1 - - test al, 0x8 ; DRQ signal state - jz @@WaitDevice0_1 -; Send packet command -; cli - mov dx, [ATABasePortAddr] - mov ax, word [PacketCommand] - out dx, ax - mov ax, word [PacketCommand+2] - out dx, ax - mov ax, word [PacketCommand+4] - out dx, ax - mov ax, word [PacketCommand+6] - out dx, ax - mov ax, word [PacketCommand+8] - out dx, ax - mov ax, word [PacketCommand+10] - out dx, ax -; sti - cmp [ignore_CD_eject_wait], 1 - je @@clear_DEC -; Waiting for confirmation of command receive - mov dx, [ATABasePortAddr] - add dx, 7 ; port 1x7h -;-------------------------------------- -align 4 -@@WaitDevice1_1: - call change_task - ; Check command execution time - mov eax, [timer_ticks] - sub eax, [TickCounter_1] - cmp eax, MaxCDWaitTime - ja @@Err1_3 ; time out error - ; Wait for device release - in al, dx - test al, 0x80 ; BSY signal state - jnz @@WaitDevice1_1 - - test al, 1 ; ERR signal state - jnz @@Err6_1 - - test al, 0x40 ; DRDY signal state - jz @@WaitDevice1_1 -;-------------------------------------- -@@clear_DEC: - and [DevErrorCode], 0 - popad - ret -;-------------------------------------- -; Write error code -@@Err1_3: - xor eax, eax - inc eax - jmp @@End_9 -;-------------------------------------- -@@Err6_1: - mov eax, 6 -;-------------------------------------- -@@End_9: - mov [DevErrorCode], eax - popad - ret -;----------------------------------------------------------------------------- -;**************************************************** -;* SEND COMMAND TO GIVEN DISK * -;* Input parameters are passed through the global * -;* variables: * -;* ChannelNumber - channel number (1 or 2); * -;* DiskNumber - disk number (0 or 1); * -;* ATAFeatures - "features"; * -;* ATASectorCount - sector count; * -;* ATASectorNumber - initial sector number; * -;* ATACylinder - initial cylinder number; * -;* ATAHead - initial head number; * -;* ATAAddressMode - addressing mode (0-CHS, 1-LBA); * -;* ATACommand - command code. * -;* If the function finished successfully: * -;* in ATABasePortAddr - base address of HDD; * -;* in DevErrorCode - zero. * -;* If error has occured then in DevErrorCode will * -;* be the error code. * -;**************************************************** -SendCommandToHDD_1: -; Check the addressing mode code - cmp [ATAAddressMode], 1 - ja @@Err2_4 -; Check the channel number correctness - movzx ebx, [ChannelNumber] - dec ebx - cmp ebx, 1 - ja @@Err3_4 -; Set the base address - shl ebx, 2 - mov eax, [cdpos] - dec eax - shr eax, 2 - imul eax, sizeof.IDE_DATA - add eax, IDE_controller_1 - add eax, ebx - mov ax, [eax+IDE_DATA.BAR0_val] - mov [ATABasePortAddr], ax -; Waiting for HDD ready to receive a command - ; Choose desired disk - mov dx, [ATABasePortAddr] - add dx, 6 ; address of the heads register - mov al, [DiskNumber] - cmp al, 1 ; check the disk number - ja @@Err4_4 - - shl al, 4 - or al, 10100000b - out dx, al - ; Waiting for disk ready - inc dx - mov eax, [timer_ticks] - mov [TickCounter_1], eax - mov ecx, NoTickWaitTime -;-------------------------------------- -align 4 -@@WaitHDReady_2: - cmp [timer_ticks_enable], 0 - jne @f - - dec ecx - jz @@Err1_4 - - jmp .test -;-------------------------------------- -align 4 -@@: - call change_task - ; Check waiting time - mov eax, [timer_ticks] - sub eax, [TickCounter_1] - cmp eax, BSYWaitTime ;300 ; wait for 3 seconds - ja @@Err1_4 ; time out error -;-------------------------------------- -align 4 -.test: - in al, dx ; Read the state register - ; Check the state of BSY signal - test al, 0x80 - jnz @@WaitHDReady_2 - ; Check the state of DRQ signal - test al, 0x8 - jnz @@WaitHDReady_2 -; load command to controller's registers - cli - mov dx, [ATABasePortAddr] - inc dx ; "features" register - mov al, [ATAFeatures] - out dx, al - inc dx ; sector counter - mov al, [ATASectorCount] - out dx, al - inc dx ; sector number register - mov al, [ATASectorNumber] - out dx, al - inc dx ; cylinder number (low byte) - mov ax, [ATACylinder] - out dx, al - inc dx ; cylinder number (high byte) - mov al, ah - out dx, al - inc dx ; head number / disk number - mov al, [DiskNumber] - shl al, 4 - cmp [ATAHead], 0xF ; check head number - ja @@Err5_4 - - or al, [ATAHead] - or al, 10100000b - mov ah, [ATAAddressMode] - shl ah, 6 - or al, ah - out dx, al -; Send command - mov al, [ATACommand] - inc dx ; command register - out dx, al - sti -;-------------------------------------- -@@End_10: - xor eax, eax - ret -;-------------------------------------- -; Write error code -@@Err1_4: - xor eax, eax - inc eax - ret -;-------------------------------------- -@@Err2_4: - mov eax, 2 - ret -;-------------------------------------- -@@Err3_4: - mov eax, 3 - ret -;-------------------------------------- -@@Err4_4: - mov eax, 4 - ret -;-------------------------------------- -@@Err5_4: - mov eax, 5 - ret -;----------------------------------------------------------------------------- -;************************************************* -;* WAIT FOR THE DEVICE IS READY FOR WORK * -;* Input parameters are passed through global * -;* variables: * -;* ChannelNumber - channel number; * -;* DiskNumber - disk number on channel. * -;************************************************* -WaitUnitReady: - pusha -; Remember the peration start time - mov eax, [timer_ticks] - mov [WURStartTime], eax -; Clear the packet command buffer - call clear_packet_buffer -; Generate TEST UNIT READY command - mov [PacketCommand], word 0 -; waiting loop for device readiness - mov ecx, NoTickWaitTime -;-------------------------------------- -align 4 -@@SendCommand: - ; Send readiness check command - call SendPacketNoDatCommand - cmp [timer_ticks_enable], 0 - jne @f - - cmp [DevErrorCode], 0 - je @@End_11 - - dec ecx - jz .Error - - jmp @@SendCommand -;-------------------------------------- -align 4 -@@: - call change_task - ; Check the error code - cmp [DevErrorCode], 0 - je @@End_11 - ; Check waiting time - mov eax, [timer_ticks] - sub eax, [WURStartTime] - cmp eax, MaxCDWaitTime - jb @@SendCommand -;-------------------------------------- -.Error: - ; time out error - mov [DevErrorCode], 1 -;-------------------------------------- -@@End_11: - popa - ret -;----------------------------------------------------------------------------- -;************************************************* -;* FORBID DISK CHANGE * -;* Input parameters are passed through global * -;* variables: * -;* ChannelNumber - channel number; * -;* DiskNumber - disk number on channel. * -;************************************************* -prevent_medium_removal: - pusha -; Clear the packet command buffer - call clear_packet_buffer -; Set command code - mov [PacketCommand], byte 0x1E -; Set "Forbid" code - mov [PacketCommand+4], byte 11b -; Send command - call SendPacketNoDatCommand - mov eax, ATAPI_IDE0_lock - add eax, [cdpos] - dec eax - mov [eax], byte 1 - popa - ret -;----------------------------------------------------------------------------- -;************************************************* -;* ALLOW DISK CHANGE * -;* Input parameters are passed through global * -;* variables: * -;* ChannelNumber - channel number; * -;* DiskNumber - disk number on channel. * -;************************************************* -allow_medium_removal: - pusha -; Clear the packet command buffer - call clear_packet_buffer -; Set command code - mov [PacketCommand], byte 0x1E -; unset "Forbid" code - mov [PacketCommand+4], byte 0 -; Send command - call SendPacketNoDatCommand - mov eax, ATAPI_IDE0_lock - add eax, [cdpos] - dec eax - mov [eax], byte 0 - popa - ret -;----------------------------------------------------------------------------- -;************************************************* -;* LOAD DISK TO THE DRIVE * -;* Input parameters are passed through global * -;* variables: * -;* ChannelNumber - channel number; * -;* DiskNumber - disk number on channel. * -;************************************************* -LoadMedium: - pusha -; Clear the packet command buffer - call clear_packet_buffer -; Generate START/STOP UNIT command - ; Set command code - mov [PacketCommand], word 0x1B - ; Set disk loading operation - mov [PacketCommand+4], word 00000011b -; Send command - call SendPacketNoDatCommand - popa - ret -;----------------------------------------------------------------------------- -;************************************************* -;* REMOVE THE DISK FROM THE DRIVE * -;* Input parameters are passed through global * -;* variables: * -;* ChannelNumber - channel number; * -;* DiskNumber - disk number on channel. * -;************************************************* -EjectMedium: - pusha -; Clear the packet command buffer - call clear_packet_buffer -; Generate START/STOP UNIT command - ; Set command code - mov [PacketCommand], word 0x1B - ; Set the operation to eject disk - mov [PacketCommand+4], word 00000010b -; Send command - call SendPacketNoDatCommand - popa - ret -;----------------------------------------------------------------------------- -;************************************************* -;* Check the event of pressing the eject button * -;* * -;* Input parameters are passed through global * -;* variables: * -;* ChannelNumber - channel number; * -;* DiskNumber - disk number on channel. * -;************************************************* -proc check_ATAPI_device_event_has_work? - mov eax, [timer_ticks] - sub eax, [timer_ATAPI_check] - cmp eax, 100 - jb .no - - xor eax, eax - inc eax - ret -;-------------------------------------- -.no: - xor eax, eax - ret -endp -;----------------------------------------------------------------------------- -align 4 -check_ATAPI_device_event: - pusha - mov eax, [timer_ticks] - sub eax, [timer_ATAPI_check] - cmp eax, 100 - jb .end_1 - - pushfd - mov al, [DRIVE_DATA+1] - and al, 11b - cmp al, 10b - jz .ide3 -;-------------------------------------- -.ide2_1: - mov al, [DRIVE_DATA+1] - and al, 1100b - cmp al, 1000b - jz .ide2 -;-------------------------------------- -.ide1_1: - mov al, [DRIVE_DATA+1] - and al, 110000b - cmp al, 100000b - jz .ide1 -;-------------------------------------- -.ide0_1: - mov al, [DRIVE_DATA+1] - and al, 11000000b - cmp al, 10000000b - jz .ide0 -;-------------------------------------- -.ide7_1: - mov al, [DRIVE_DATA+6] - and al, 11b - cmp al, 10b - jz .ide7 -;-------------------------------------- -.ide6_1: - mov al, [DRIVE_DATA+6] - and al, 1100b - cmp al, 1000b - jz .ide6 -;-------------------------------------- -.ide5_1: - mov al, [DRIVE_DATA+6] - and al, 110000b - cmp al, 100000b - jz .ide5 -;-------------------------------------- -.ide4_1: - mov al, [DRIVE_DATA+6] - and al, 11000000b - cmp al, 10000000b - jz .ide4 -;-------------------------------------- -.ide11_1: - mov al, [DRIVE_DATA+11] - and al, 11b - cmp al, 10b - jz .ide11 -;-------------------------------------- -.ide10_1: - mov al, [DRIVE_DATA+11] - and al, 1100b - cmp al, 1000b - jz .ide10 -;-------------------------------------- -.ide9_1: - mov al, [DRIVE_DATA+11] - and al, 110000b - cmp al, 100000b - jz .ide9 -;-------------------------------------- -.ide8_1: - mov al, [DRIVE_DATA+11] - and al, 11000000b - cmp al, 10000000b - jz .ide8 -;-------------------------------------- -.end: - popfd - mov eax, [timer_ticks] - mov [timer_ATAPI_check], eax -;-------------------------------------- -.end_1: - popa - ret -;----------------------------------------------------------------------------- -.ide3: - cli - cmp [ATAPI_IDE3_lock], 1 - jne .ide2_1 - - cmp [cd_status], 0 - jne .end - - mov ecx, ide_channel2_mutex - call mutex_lock - call reserve_ok2 - mov [ChannelNumber], 2 - mov [DiskNumber], 1 - mov [cdpos], 4 - call GetEvent_StatusNotification - cmp [CDDataBuf+4], byte 1 - jne @f - - call .eject -;-------------------------------------- -@@: - call syscall_cdaudio.free - jmp .ide2_1 -;----------------------------------------------------------------------------- -.ide2: - cli - cmp [ATAPI_IDE2_lock], 1 - jne .ide1_1 - - cmp [cd_status], 0 - jne .end - - mov ecx, ide_channel2_mutex - call mutex_lock - call reserve_ok2 - mov [ChannelNumber], 2 - mov [DiskNumber], 0 - mov [cdpos], 3 - call GetEvent_StatusNotification - cmp [CDDataBuf+4], byte 1 - jne @f - - call .eject -;-------------------------------------- -@@: - call syscall_cdaudio.free - jmp .ide1_1 -;----------------------------------------------------------------------------- -.ide1: - cli - cmp [ATAPI_IDE1_lock], 1 - jne .ide0_1 - - cmp [cd_status], 0 - jne .end - - mov ecx, ide_channel1_mutex - call mutex_lock - call reserve_ok2 - mov [ChannelNumber], 1 - mov [DiskNumber], 1 - mov [cdpos], 2 - call GetEvent_StatusNotification - cmp [CDDataBuf+4], byte 1 - jne @f - - call .eject -;-------------------------------------- -@@: - call syscall_cdaudio.free - jmp .ide0_1 -;----------------------------------------------------------------------------- -.ide0: - cli - cmp [ATAPI_IDE0_lock], 1 - jne .ide7_1 - - cmp [cd_status], 0 - jne .end - - mov ecx, ide_channel1_mutex - call mutex_lock - call reserve_ok2 - mov [ChannelNumber], 1 - mov [DiskNumber], 0 - mov [cdpos], 1 - call GetEvent_StatusNotification - cmp [CDDataBuf+4], byte 1 - jne @f - - call .eject -;-------------------------------------- -@@: - call syscall_cdaudio.free - jmp .ide7_1 -;----------------------------------------------------------------------------- -.ide7: - cli - cmp [ATAPI_IDE7_lock], 1 - jne .ide6_1 - - cmp [cd_status], 0 - jne .end - - mov ecx, ide_channel4_mutex - call mutex_lock - call reserve_ok2 - mov [ChannelNumber], 2 - mov [DiskNumber], 1 - mov [cdpos], 8 - call GetEvent_StatusNotification - cmp [CDDataBuf+4], byte 1 - jne @f - - call .eject -;-------------------------------------- -@@: - call syscall_cdaudio.free - jmp .ide6_1 -;----------------------------------------------------------------------------- -.ide6: - cli - cmp [ATAPI_IDE6_lock], 1 - jne .ide5_1 - - cmp [cd_status], 0 - jne .end - - mov ecx, ide_channel4_mutex - call mutex_lock - call reserve_ok2 - mov [ChannelNumber], 2 - mov [DiskNumber], 0 - mov [cdpos], 7 - call GetEvent_StatusNotification - cmp [CDDataBuf+4], byte 1 - jne @f - - call .eject -;-------------------------------------- -@@: - call syscall_cdaudio.free - jmp .ide5_1 -;----------------------------------------------------------------------------- -.ide5: - cli - cmp [ATAPI_IDE5_lock], 1 - jne .ide4_1 - - cmp [cd_status], 0 - jne .end - - mov ecx, ide_channel3_mutex - call mutex_lock - call reserve_ok2 - mov [ChannelNumber], 1 - mov [DiskNumber], 1 - mov [cdpos], 6 - call GetEvent_StatusNotification - cmp [CDDataBuf+4], byte 1 - jne @f - - call .eject -;-------------------------------------- -@@: - call syscall_cdaudio.free - jmp .ide4_1 -;----------------------------------------------------------------------------- -.ide4: - cli - cmp [ATAPI_IDE4_lock], 1 - jne .ide11_1 - - cmp [cd_status], 0 - jne .end - - mov ecx, ide_channel3_mutex - call mutex_lock - call reserve_ok2 - mov [ChannelNumber], 1 - mov [DiskNumber], 0 - mov [cdpos], 5 - call GetEvent_StatusNotification - cmp [CDDataBuf+4], byte 1 - jne @f - - call .eject -;-------------------------------------- -@@: - call syscall_cdaudio.free - jmp .ide11_1 -;----------------------------------------------------------------------------- -.ide11: - cli - cmp [ATAPI_IDE11_lock], 1 - jne .ide10_1 - - cmp [cd_status], 0 - jne .end - - mov ecx, ide_channel6_mutex - call mutex_lock - call reserve_ok2 - mov [ChannelNumber], 2 - mov [DiskNumber], 1 - mov [cdpos], 12 - call GetEvent_StatusNotification - cmp [CDDataBuf+4], byte 1 - jne @f - - call .eject -;-------------------------------------- -@@: - call syscall_cdaudio.free - jmp .ide10_1 -;----------------------------------------------------------------------------- -.ide10: - cli - cmp [ATAPI_IDE10_lock], 1 - jne .ide9_1 - - cmp [cd_status], 0 - jne .end - - mov ecx, ide_channel6_mutex - call mutex_lock - call reserve_ok2 - mov [ChannelNumber], 2 - mov [DiskNumber], 0 - mov [cdpos], 11 - call GetEvent_StatusNotification - cmp [CDDataBuf+4], byte 1 - jne @f - - call .eject -;-------------------------------------- -@@: - call syscall_cdaudio.free - jmp .ide9_1 -;----------------------------------------------------------------------------- -.ide9: - cli - cmp [ATAPI_IDE9_lock], 1 - jne .ide8_1 - - cmp [cd_status], 0 - jne .end - - mov ecx, ide_channel5_mutex - call mutex_lock - call reserve_ok2 - mov [ChannelNumber], 1 - mov [DiskNumber], 1 - mov [cdpos], 10 - call GetEvent_StatusNotification - cmp [CDDataBuf+4], byte 1 - jne @f - - call .eject -;-------------------------------------- -@@: - call syscall_cdaudio.free - jmp .ide8_1 -;----------------------------------------------------------------------------- -.ide8: - cli - cmp [ATAPI_IDE8_lock], 1 - jne .end - - cmp [cd_status], 0 - jne .end - - mov ecx, ide_channel5_mutex - call mutex_lock - call reserve_ok2 - mov [ChannelNumber], 1 - mov [DiskNumber], 0 - mov [cdpos], 9 - call GetEvent_StatusNotification - cmp [CDDataBuf+4], byte 1 - jne @f - - call .eject -;-------------------------------------- -@@: - call syscall_cdaudio.free - jmp .end -;----------------------------------------------------------------------------- -.eject: - call clear_CD_cache - call allow_medium_removal - mov [ignore_CD_eject_wait], 1 - call EjectMedium - mov [ignore_CD_eject_wait], 0 - ret -;----------------------------------------------------------------------------- -iglobal -timer_ATAPI_check dd 0 -ATAPI_IDE0_lock db 0 -ATAPI_IDE1_lock db 0 -ATAPI_IDE2_lock db 0 -ATAPI_IDE3_lock db 0 -ATAPI_IDE4_lock db 0 -ATAPI_IDE5_lock db 0 -ATAPI_IDE6_lock db 0 -ATAPI_IDE7_lock db 0 -ATAPI_IDE8_lock db 0 -ATAPI_IDE9_lock db 0 -ATAPI_IDE10_lock db 0 -ATAPI_IDE11_lock db 0 -ignore_CD_eject_wait db 0 -endg -;----------------------------------------------------------------------------- -;************************************************* -;* Get an event or device status message * -;* * -;* Input parameters are passed through global * -;* variables: * -;* ChannelNumber - channel number; * -;* DiskNumber - disk number on channel * -;************************************************* -GetEvent_StatusNotification: - pusha - mov [CDDataBuf_pointer], CDDataBuf -; Clear the packet command buffer - call clear_packet_buffer -; Set command code - mov [PacketCommand], byte 4Ah - mov [PacketCommand+1], byte 00000001b -; Set message class request - mov [PacketCommand+4], byte 00010000b -; Size of allocated area - mov [PacketCommand+7], byte 8h - mov [PacketCommand+8], byte 0h -; Send command - call SendPacketDatCommand - popa - ret -;----------------------------------------------------------------------------- -;************************************************* -; Read information from TOC (Table of contents) * -;* Input parameters are passed through global * -;* variables: * -;* ChannelNumber - channel number; * -;* DiskNumber - disk number on channel * -;************************************************* -Read_TOC: - pusha - mov [CDDataBuf_pointer], CDDataBuf -; Clear the packet command buffer - call clear_packet_buffer -; Generate a packet command to read a data sector - mov [PacketCommand], byte 0x43 - ; Set format - mov [PacketCommand+2], byte 1 -; Size of allocated area - mov [PacketCommand+7], byte 0xFF - mov [PacketCommand+8], byte 0h -; Send a command - call SendPacketDatCommand - popa - ret -;----------------------------------------------------------------------------- -;***************************************************** -;* DETERMINE THE TOTAL NUMBER OF SECTORS ON THE DISK * -;* Input parameters are passed through global * -;* variables: * -;* ChannelNumber - channel number; * -;* DiskNumber - disk number on channel * -;***************************************************** -;ReadCapacity: -; pusha -;; Clear the packet command buffer -; call clear_packet_buffer -;; Set the buffer size in bytes -; mov [CDBlockSize],8 -;; Generate READ CAPACITY command -; mov [PacketCommand],word 25h -;; Send command -; call SendPacketDatCommand -; popa -; ret -;----------------------------------------------------------------------------- -clear_packet_buffer: -; Clear the packet command buffer - and [PacketCommand], dword 0 - and [PacketCommand+4], dword 0 - and [PacketCommand+8], dword 0 - ret -;----------------------------------------------------------------------------- diff --git a/kernel/branches/Kolibri-F/blkdev/disk.inc b/kernel/branches/Kolibri-F/blkdev/disk.inc deleted file mode 100644 index f2a0a4ccd..000000000 --- a/kernel/branches/Kolibri-F/blkdev/disk.inc +++ /dev/null @@ -1,1625 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2011-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; ============================================================================= -; ================================= Constants ================================= -; ============================================================================= -; Error codes for callback functions. -DISK_STATUS_OK = 0 ; success -DISK_STATUS_GENERAL_ERROR = -1; if no other code is suitable -DISK_STATUS_INVALID_CALL = 1 ; invalid input parameters -DISK_STATUS_NO_MEDIA = 2 ; no media present -DISK_STATUS_END_OF_MEDIA = 3 ; end of media while reading/writing data -DISK_STATUS_NO_MEMORY = 4 ; insufficient memory for driver operation -; Driver flags. Represent bits in DISK.DriverFlags. -DISK_NO_INSERT_NOTIFICATION = 1 -; Media flags. Represent bits in DISKMEDIAINFO.Flags. -DISK_MEDIA_READONLY = 1 - -; If too many partitions are detected,there is probably an error on the disk. -; 256 partitions should be enough for any reasonable use. -; Also, the same number is limiting the number of MBRs to process; if -; too many MBRs are visible,there probably is a loop in the MBR structure. -MAX_NUM_PARTITIONS = 256 - -; ============================================================================= -; ================================ Structures ================================= -; ============================================================================= -; This structure defines all callback functions for working with the physical -; device. They are implemented by a driver. Objects with this structure reside -; in a driver. -struct DISKFUNC - strucsize dd ? -; Size of the structure. This field is intended for possible extensions of -; this structure. If a new function is added to this structure and a driver -; implements an old version, the caller can detect this by checking .strucsize, -; so the driver remains compatible. - close dd ? -; The pointer to the function which frees all driver-specific resources for -; the disk. -; Optional, may be NULL. -; void close(void* userdata); - closemedia dd ? -; The pointer to the function which informs the driver that the kernel has -; finished all processing with the current media. If media is removed, the -; driver should decline all requests to that media with DISK_STATUS_NO_MEDIA, -; even if new media is inserted, until this function is called. If media is -; removed, a new call to 'disk_media_changed' is not allowed until this -; function is called. -; Optional, may be NULL (if media is not removable). -; void closemedia(void* userdata); - querymedia dd ? -; The pointer to the function which determines capabilities of the media. -; int querymedia(void* userdata, DISKMEDIAINFO* info); -; Return value: one of DISK_STATUS_* - read dd ? -; The pointer to the function which reads data from the device. -; int read(void* userdata, void* buffer, __int64 startsector, int* numsectors); -; input: *numsectors = number of sectors to read -; output: *numsectors = number of sectors which were successfully read -; Return value: one of DISK_STATUS_* - write dd ? -; The pointer to the function which writes data to the device. -; Optional, may be NULL. -; int write(void* userdata, void* buffer, __int64 startsector, int* numsectors); -; input: *numsectors = number of sectors to write -; output: *numsectors = number of sectors which were successfully written -; Return value: one of DISK_STATUS_* - flush dd ? -; The pointer to the function which flushes the internal device cache. -; Optional, may be NULL. -; int flush(void* userdata); -; Return value: one of DISK_STATUS_* -; Note that read/write are called by the cache manager, so a driver should not -; create a software cache. This function is implemented for flushing a hardware -; cache, if it exists. - adjust_cache_size dd ? -; The pointer to the function which returns the cache size for this device. -; Optional, may be NULL. -; unsigned int adjust_cache_size(void* userdata, unsigned int suggested_size); -; Return value: 0 = disable cache, otherwise = used cache size in bytes. -ends - -; This structure holds information on a medium. -; Objects with this structure are allocated by the kernel as a part of the DISK -; structure and are filled by a driver in the 'querymedia' callback. -struct DISKMEDIAINFO - Flags dd ? -; Combination of DISK_MEDIA_* bits. - SectorSize dd ? -; Size of the sector. - Capacity dq ? -; Size of the media in sectors. -ends - -; This structure represents the disk cache. To follow the old implementation, -; there are two distinct caches for a disk, one for "system" data,and the other -; for "application" data. -struct DISKCACHE -; The following fields are inherited from data32.inc:cache_ideX. - pointer dd ? - data_size dd ? ; unused - data dd ? - sad_size dd ? - search_start dd ? - sector_size_log dd ? -ends - -; This structure represents a disk device and its media for the kernel. -; This structure is allocated by the kernel in the 'disk_add' function, -; freed in the 'disk_dereference' function. -struct DISK -; Fields of disk object - Next dd ? - Prev dd ? -; All disk devices are linked in one list with these two fields. -; Head of the list is the 'disk_list' variable. - Functions dd ? -; Pointer to the 'DISKFUNC' structure with driver functions. - Name dd ? -; Pointer to the string used for accesses through the global filesystem. - UserData dd ? -; This field is passed to all callback functions so a driver can decide which -; physical device is addressed. - DriverFlags dd ? -; Bitfield. Currently only DISK_NO_INSERT_NOTIFICATION bit is defined. -; If it is set, the driver will never issue 'disk_media_changed' notification -; with argument set to true, so the kernel must try to detect media during -; requests from the file system. - RefCount dd ? -; Count of active references to this structure. One reference is kept during -; the lifetime of the structure between 'disk_add' and 'disk_del'. -; Another reference is taken during any filesystem operation for this disk. -; One reference is added if media is inserted. -; The structure is destroyed when the reference count decrements to zero: -; this usually occurs in 'disk_del', but can be delayed to the end of last -; filesystem operation, if one is active. - MediaLock MUTEX -; Lock to protect the MEDIA structure. See the description after -; 'disk_list_mutex' for the locking strategy. -; Fields of media object - MediaInserted db ? -; 0 if media is not inserted, nonzero otherwise. - MediaUsed db ? -; 0 if media fields are not used, nonzero otherwise. If .MediaRefCount is -; nonzero, this field is nonzero too; however, when .MediaRefCount goes -; to zero, there is some time interval during which media object is still used. - dw ? ; padding -; The following fields are not valid unless either .MediaInserted is nonzero -; or they are accessed from a code which has obtained the reference when -; .MediaInserted was nonzero. - MediaRefCount dd ? -; Count of active references to the media object. One reference is kept during -; the lifetime of the media between two calls to 'disk_media_changed'. -; Another reference is taken during any filesystem operation for this media. -; The callback 'closemedia' is called when the reference count decrements to -; zero: this usually occurs in 'disk_media_changed', but can be delayed to the -; end of the last filesystem operation, if one is active. - MediaInfo DISKMEDIAINFO -; This field keeps information on the current media. - NumPartitions dd ? -; Number of partitions on this media. - Partitions dd ? -; Pointer to array of .NumPartitions pointers to PARTITION structures. - cache_size dd ? -; inherited from cache_ideX_size - CacheLock MUTEX -; Lock to protect both caches. - SysCache DISKCACHE - AppCache DISKCACHE -; Two caches for the disk. -ends - -; This structure represents one partition for the kernel. This is a base -; template, the actual contents after common fields is determined by the -; file system code for this partition. -struct PARTITION - FirstSector dq ? -; First sector of the partition. - Length dq ? -; Length of the partition in sectors. - Disk dd ? -; Pointer to parent DISK structure. - FSUserFunctions dd ? -; Handlers for the sysfunction 70h. This field is a pointer to the following -; array. The first dword is pointer to disconnect handler. -; The first dword is a number of supported subfunctions, other dwords -; point to handlers of corresponding subfunctions. -; ...fs-specific data may follow... -ends - -; This is an external structure, it represents an entry in the partition table. -struct PARTITION_TABLE_ENTRY - Bootable db ? -; 80h = bootable partition, 0 = non-bootable partition, other values = invalid - FirstHead db ? - FirstSector db ? - FirstTrack db ? -; Coordinates of first sector in CHS. - Type db ? -; Partition type, one of predefined constants. 0 = empty, several types denote -; extended partition (see process_partition_table_entry), we are not interested -; in other values. - LastHead db ? - LastSector db ? - LastTrack db ? -; Coordinates of last sector in CHS. - FirstAbsSector dd ? -; Coordinate of first sector in LBA. - Length dd ? -; Length of the partition in sectors. -ends - -; GUID Partition Table Header, UEFI 2.6, Table 18 -struct GPTH - Signature rb 8 -; 'EFI PART' - Revision dd ? -; 0x00010000 - HeaderSize dd ? -; Size of this header in bytes, must fit to one sector. - HeaderCRC32 dd ? -; Set this field to zero, compute CRC32 via 0xEDB88320, compare. - Reserved dd ? -; Must be zero. - MyLBA dq ? -; LBA of the sector containing this GPT header. - AlternateLBA dq ? -; LBA of the sector containing the other GPT header. -; AlternateLBA of Primary GPTH points to Backup one and vice versa. - FirstUsableLBA dq ? -; Only sectors between first and last UsableLBA may form partitions - LastUsableLBA dq ? - DiskGUID rb 16 -; Globally Unique IDentifier - PartitionEntryLBA dq ? -; First LBA of Partition Entry Array. -; Length in bytes is computed as a product of two following fields. - NumberOfPartitionEntries dd ? -; Actual number of partitions depends on the contents of Partition Entry Array. -; A partition entry is unused if zeroed. - SizeOfPartitionEntry dd ? ; in bytes - PartitionEntryArrayCRC32 dd ? -; Same CRC as for GPT header. -ends - -; GPT Partition Entry, UEFI 2.6, Table 19 -struct GPE - PartitionTypeGUID rb 16 - UniquePartitionGUID rb 16 - StartingLBA dq ? - EndingLBA dq ? -; Length in sectors is EndingLBA - StartingLBA + 1. - Attributes dq ? - PartitionName rb 72 -ends - -; ============================================================================= -; ================================ Global data ================================ -; ============================================================================= -iglobal -; The pseudo-item for the list of all DISK structures. -; Initialized to the empty list. -disk_list: - dd disk_list - dd disk_list -endg -uglobal -; This mutex guards all operations with the global list of DISK structures. -disk_list_mutex MUTEX -; * There are two dependent objects, a disk and a media. In the simplest case, -; disk and media are both non-removable. However, in the general case both -; can be removed at any time, simultaneously or only media,and this makes things -; complicated. -; * For efficiency, both disk and media objects are located in the one -; structure named DISK. However, logically they are different. -; * The following operations use data of disk object: adding (disk_add); -; deleting (disk_del); filesystem (fs_lfn which eventually calls -; dyndisk_handler or dyndisk_enum_root). -; * The following operations use data of media object: adding/removing -; (disk_media_changed); filesystem (fs_lfn which eventually calls -; dyndisk_handler; dyndisk_enum_root doesn't work with media). -; * Notifications disk_add, disk_media_changed, disk_del are synchronized -; between themselves, this is a requirement for the driver. However, file -; system operations are asynchronous, can be issued at any time by any -; thread. -; * We must prevent a situation when a filesystem operation thinks that the -; object is still valid but in fact the notification has destroyed the -; object. So we keep a reference counter for both disk and media and destroy -; the object when this counter goes to zero. -; * The driver must know when it is safe to free driver-allocated resources. -; The object can be alive even after death notification has completed. -; We use special callbacks to satisfy both assertions: 'close' for the disk -; and 'closemedia' for the media. The destruction of the object includes -; calling the corresponding callback. -; * Each filesystem operation keeps one reference for the disk and one -; reference for the media. Notification disk_del forces notification on the -; media death, so the reference counter for the disk is always not less than -; the reference counter for the media. -; * Two operations "get the object" and "increment the reference counter" can -; not be done simultaneously. We use a mutex to guard the consistency here. -; It must be a part of the container for the object, so that this mutex can -; be acquired as a part of getting the object from the container. The -; container for disk object is the global list, and this list is guarded by -; 'disk_list_mutex'. The container for media object is the disk object, and -; the corresponding mutex is DISK.MediaLock. -; * Notifications do not change the data of objects, they can only remove -; objects. Thus we don't need another synchronization at this level. If two -; filesystem operations are referencing the same filesystem data, this is -; better resolved at the level of the filesystem. -endg - -iglobal -; The function 'disk_scan_partitions' needs three sector-sized buffers for -; MBR, bootsector and fs-temporary sector data. It can not use the static -; buffers always, since it can be called for two or more disks in parallel. -; However, this case is not typical. We reserve three static 512-byte buffers -; and a flag that these buffers are currently used. If 'disk_scan_partitions' -; detects that the buffers are currently used, it allocates buffers from the -; heap. Also, the heap is used when sector size is other than 512. -; The flag is implemented as a global dword variable. When the static buffers -; are not used, the value is -1. When the static buffers are used, the value -; is normally 0 and temporarily can become greater. The function increments -; this value. If the resulting value is zero, it uses the buffers and -; decrements the value when the job is done. Otherwise, it immediately -; decrements the value and uses buffers from the heap, allocated in the -; beginning and freed in the end. -partition_buffer_users dd -1 -endg -uglobal -; The static buffers for MBR, bootsector and fs-temporary sector data. -align 16 -mbr_buffer rb 512 -bootsect_buffer rb 512 -fs_tmp_buffer rb 512 -endg - -iglobal -; This is the array of default implementations of driver callbacks. -; Same as DRIVERFUNC structure except for the first field; all functions must -; have the default implementations. -align 4 -disk_default_callbacks: - dd disk_default_close - dd disk_default_closemedia - dd disk_default_querymedia - dd disk_default_read - dd disk_default_write - dd disk_default_flush - dd disk_default_adjust_cache_size -endg - -; ============================================================================= -; ================================= Functions ================================= -; ============================================================================= - -; This function registers a disk device. -; This includes: -; - allocating an internal structure describing this device; -; - registering this structure in the global filesystem. -; The function initializes the disk as if there is no media. If a media is -; present, the function 'disk_media_changed' should be called after this -; function succeeds. -; Parameters: -; [esp+4] = pointer to DISKFUNC structure with the callbacks -; [esp+8] = pointer to name (ASCIIZ string) -; [esp+12] = userdata to be passed to the callbacks as is. -; [esp+16] = flags, bitfield. Currently only DISK_NO_INSERT_NOTIFICATION bit -; is defined. -; Return value: -; NULL = operation has failed -; non-NULL = handle of the disk. This handle can be used -; in the operations with other Disk* functions. -; The handle is the pointer to the internal structure DISK. -disk_add: - push ebx esi ; save used registers to be stdcall -; 1. Allocate the DISK structure. -; 1a. Call the heap manager. - movi eax, sizeof.DISK - call malloc -; 1b. Check the result. If allocation failed, return (go to 9) with eax = 0. - test eax, eax - jz .nothing -; 2. Copy the disk name to the DISK structure. -; 2a. Get length of the name, including the terminating zero. - mov ebx, [esp+8+8] ; ebx = pointer to name - push eax ; save allocated pointer to DISK - xor eax, eax ; the argument of malloc() is in eax -@@: - inc eax - cmp byte [ebx+eax-1], 0 - jnz @b -; 2b. Call the heap manager. - call malloc -; 2c. Check the result. If allocation failed, go to 7. - pop esi ; restore allocated pointer to DISK - test eax, eax - jz .free -; 2d. Store the allocated pointer to the DISK structure. - mov [esi+DISK.Name], eax -; 2e. Copy the name. -@@: - mov dl, [ebx] - mov [eax], dl - inc ebx - inc eax - test dl, dl - jnz @b -; 3. Copy other arguments of the function to the DISK structure. - mov eax, [esp+4+8] - mov [esi+DISK.Functions], eax - mov eax, [esp+12+8] - mov [esi+DISK.UserData], eax - mov eax, [esp+16+8] - mov [esi+DISK.DriverFlags], eax -; 4. Initialize other fields of the DISK structure. -; Media is not inserted, reference counter is 1. - lea ecx, [esi+DISK.MediaLock] - call mutex_init - xor eax, eax - mov dword [esi+DISK.MediaInserted], eax - mov [esi+DISK.MediaRefCount], eax - inc eax - mov [esi+DISK.RefCount], eax -; The DISK structure is initialized. -; 5. Insert the new structure to the global list. -; 5a. Acquire the mutex. - mov ecx, disk_list_mutex - call mutex_lock -; 5b. Insert item to the tail of double-linked list. - mov edx, disk_list - list_add_tail esi, edx ;esi= new edx= list head -; 5c. Release the mutex. - call mutex_unlock -; 6. Return with eax = pointer to DISK. - xchg eax, esi - jmp .nothing -.free: -; Memory allocation for DISK structure succeeded, but for disk name failed. -; 7. Free the DISK structure. - xchg eax, esi - call free -; 8. Return with eax = 0. - xor eax, eax -.nothing: -; 9. Return. - pop esi ebx ; restore used registers to be stdcall - ret 16 ; purge 4 dword arguments to be stdcall - -; This function deletes a disk device from the global filesystem. -; This includes: -; - removing a media including all partitions; -; - deleting this structure from the global filesystem; -; - dereferencing the DISK structure and possibly destroying it. -; Parameters: -; [esp+4] = handle of the disk, i.e. the pointer to the DISK structure. -; Return value: none. -disk_del: - push esi ; save used registers to be stdcall -; 1. Force media to be removed. If the media is already removed, the -; call does nothing. - mov esi, [esp+4+4] ; esi = handle of the disk - stdcall disk_media_changed, esi, 0 -; 2. Delete the structure from the global list. -; 2a. Acquire the mutex. - mov ecx, disk_list_mutex - call mutex_lock -; 2b. Delete item from double-linked list. - mov eax, [esi+DISK.Next] - mov edx, [esi+DISK.Prev] - mov [eax+DISK.Prev], edx - mov [edx+DISK.Next], eax -; 2c. Release the mutex. - call mutex_unlock -; 3. The structure still has one reference created in disk_add. Remove this -; reference. If there are no other references, disk_dereference will free the -; structure. - call disk_dereference -; 4. Return. - pop esi ; restore used registers to be stdcall - ret 4 ; purge 1 dword argument to be stdcall - -; This is an internal function which removes a previously obtained reference -; to the disk. If this is the last reference, this function lets the driver -; finalize all associated data, and afterwards frees the DISK structure. -; esi = pointer to DISK structure -disk_dereference: -; 1. Decrement reference counter. Use atomic operation to correctly handle -; possible simultaneous calls. - lock dec [esi+DISK.RefCount] -; 2. If the result is nonzero, there are other references, so nothing to do. -; In this case, return (go to 4). - jnz .nothing -; 3. If we are here, we just removed the last reference and must destroy the -; disk object. -; 3a. Call the driver. - mov al, DISKFUNC.close - stdcall disk_call_driver -; 3b. Free the structure. - xchg eax, esi - push ebx - call free - pop ebx -; 4. Return. -.nothing: - ret - -; This is an internal function which removes a previously obtained reference -; to the media. If this is the last reference, this function calls 'closemedia' -; callback to signal the driver that the processing has finished and it is safe -; to inform about a new media. -; esi = pointer to DISK structure -disk_media_dereference: -; 1. Decrement reference counter. Use atomic operation to correctly handle -; possible simultaneous calls. - lock dec [esi+DISK.MediaRefCount] -; 2. If the result is nonzero, there are other references, so nothing to do. -; In this case, return (go to 4). - jnz .nothing -; 3. If we are here, we just removed the last reference and must destroy the -; media object. -; Note that the same place inside the DISK structure is reused for all media -; objects, so we must guarantee that reusing does not happen while freeing. -; Reusing is only possible when someone processes a new media. There are two -; mutually exclusive variants: -; * driver issues media insert notifications (DISK_NO_INSERT_NOTIFICATION bit -; in DISK.DriverFlags is not set). In this case, we require from the driver -; that such notification (except for the first one) can occur only after a -; call to 'closemedia' callback. -; * driver does not issue media insert notifications. In this case, the kernel -; itself must sometimes check whether media is inserted. We have the flag -; DISK.MediaUsed, visible to the kernel. This flag signals to the other parts -; of kernel that the way is free. -; In the first case other parts of the kernel do not use DISK.MediaUsed, so it -; does not matter when this flag is cleared. In the second case this flag must -; be cleared after all other actions, including call to 'closemedia'. -; 3a. Free all partitions. - push esi edi - mov edi, [esi+DISK.NumPartitions] - mov esi, [esi+DISK.Partitions] - test edi, edi - jz .nofree -.freeloop: - lodsd - mov ecx, [eax+PARTITION.FSUserFunctions] - call dword [ecx] - dec edi - jnz .freeloop -.nofree: - pop edi esi -; 3b. Free the cache. - call disk_free_cache -; 3c. Call the driver. - mov al, DISKFUNC.closemedia - stdcall disk_call_driver -; 3d. Clear the flag. - mov [esi+DISK.MediaUsed], 0 -.nothing: - ret - -; This function is called by the driver and informs the kernel that the media -; has changed. If the media is non-removable, it is called exactly once -; immediately after 'disk_add' and once from 'disk_del'. -; Parameters: -; [esp+4] = handle of the disk, i.e. the pointer to the DISK structure. -; [esp+8] = new status of the media: zero = no media, nonzero = media inserted. -disk_media_changed: - push ebx esi edi ; save used registers to be stdcall -; 1. Remove the existing media, if it is present. - mov esi, [esp+4+12] ; esi = pointer to DISK -; 1a. Check whether it is present. Since DISK.MediaInserted is changed only -; in this function and calls to this function are synchronized, no lock is -; required for checking. - cmp [esi+DISK.MediaInserted], 0 - jz .noremove -; We really need to remove the media. -; 1b. Acquire mutex. - lea ecx, [esi+DISK.MediaLock] - call mutex_lock -; 1c. Clear the flag. - mov [esi+DISK.MediaInserted], 0 -; 1d. Release mutex. - call mutex_unlock -; 1e. Remove the "lifetime" reference and possibly destroy the structure. - call disk_media_dereference -.noremove: -; 2. Test whether there is new media. - cmp dword [esp+8+12], 0 - jz .noinsert -; Yep, there is. -; 3. Process the new media. We assume that all media fields are available to -; use, see comments in 'disk_media_dereference' (this covers using by previous -; media referencers) and note that calls to this function are synchronized -; (this covers using by new media referencers). -; 3a. Call the 'querymedia' callback. -; .Flags are set to zero for possible future extensions. - lea edx, [esi+DISK.MediaInfo] - and [edx+DISKMEDIAINFO.Flags], 0 - mov al, DISKFUNC.querymedia - stdcall disk_call_driver, edx -; 3b. Check the result of the callback. Abort if it failed. - test eax, eax - jnz .noinsert -; 3c. Allocate the cache unless disabled by the driver. Abort if failed. - call disk_init_cache - test al, al - jz .noinsert -; 3d. Acquire the lifetime reference for the media object. - inc [esi+DISK.MediaRefCount] -; 3e. Scan for partitions. Ignore result; the list of partitions is valid even -; on errors. - call disk_scan_partitions -; 3f. Media is inserted and available for use. - inc [esi+DISK.MediaInserted] -.noinsert: -; 4. Return. - pop edi esi ebx ; restore used registers to be stdcall - ret 8 ; purge 2 dword arguments to be stdcall - -; This function is a thunk for all functions of a disk driver. -; It checks whether the referenced function is implemented in the driver. -; If so, this function jumps to the function in the driver. -; Otherwise, it jumps to the default implementation. -; al = offset of function in the DISKFUNC structure; -; esi = pointer to the DISK structure; -; stack is the same as for the corresponding function except that the -; first parameter (void* userdata) is prepended automatically. -disk_call_driver: - movzx eax, al ; eax = offset of function in the DISKFUNC structure -; 1. Prepend the first argument to the stack. - pop ecx ; ecx = return address - push [esi+DISK.UserData] ; add argument - push ecx ; save return address -; 2. Check that the required function is inside the table. If not, go to 5. - mov ecx, [esi+DISK.Functions] - cmp eax, [ecx+DISKFUNC.strucsize] - jae .default -; 3. Check that the required function is implemented. If not, go to 5. - mov ecx, [ecx+eax] - test ecx, ecx - jz .default -; 4. Jump to the required function. - jmp ecx -.default: -; 5. Driver does not implement the required function; use default implementation. - jmp dword [disk_default_callbacks+eax-4] - -; The default implementation of DISKFUNC.querymedia. -disk_default_querymedia: - movi eax, DISK_STATUS_INVALID_CALL - ret 8 - -; The default implementation of DISKFUNC.read and DISKFUNC.write. -disk_default_read: -disk_default_write: - movi eax, DISK_STATUS_INVALID_CALL - ret 20 - -; The default implementation of DISKFUNC.close, DISKFUNC.closemedia and -; DISKFUNC.flush. -disk_default_close: -disk_default_closemedia: -disk_default_flush: - xor eax, eax - ret 4 - -; The default implementation of DISKFUNC.adjust_cache_size. -disk_default_adjust_cache_size: - mov eax, [esp+8] - ret 8 - -; This is an internal function called from 'disk_media_changed' when a new media -; is detected. It creates the list of partitions for the media. -; If media is not partitioned, then the list consists of one partition which -; covers all the media. -; esi = pointer to the DISK structure. -disk_scan_partitions: -; 1. Initialize .NumPartitions and .Partitions fields as zeros: empty list. - and [esi+DISK.NumPartitions], 0 - and [esi+DISK.Partitions], 0 -; 2. Acquire the buffer for MBR and bootsector tests. See the comment before -; the 'partition_buffer_users' variable. - mov eax, [esi+DISK.MediaInfo.SectorSize] - cmp eax, 512 - jnz @f - mov ebx, mbr_buffer ; assume the global buffer is free - lock inc [partition_buffer_users] - jz .buffer_acquired ; yes, it is free - lock dec [partition_buffer_users] ; no, we must allocate -@@: - lea eax, [eax*3] - stdcall kernel_alloc, eax - test eax, eax - jz .nothing - xchg eax, ebx -.buffer_acquired: -; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no -; more than MAX_NUM_PARTITION times. -; 3. Prepare things for the loop. -; ebp will hold the sector number for current MBR/EBR. -; [esp] will hold the sector number for current extended partition, if there -; is one. -; [esp+4] will hold the counter that prevents long loops. - push ebp ; save ebp - push MAX_NUM_PARTITIONS ; the counter of max MBRs to process - xor ebp, ebp ; start from sector zero - push ebp ; no extended partition yet -; 4. MBR is 512 bytes long. If sector size is less than 512 bytes, -; assume no MBR, no partitions and go to 11. - cmp [esi+DISK.MediaInfo.SectorSize], 512 - jb .notmbr -.new_mbr: -; 5. Read the current sector. -; Note that 'read' callback operates with 64-bit sector numbers, so we must -; push additional zero as a high dword of sector number. - mov al, DISKFUNC.read - push 1 - stdcall disk_call_driver, ebx, ebp, 0, esp - pop ecx -; 6. If the read has failed, abort the loop. - dec ecx - jnz .mbr_failed -; 7. Check the MBR/EBR signature. If it is wrong, abort the loop. -; Soon we will access the partition table which starts at ebx+0x1BE, -; so we can fill its address right now. If we do it now, then the addressing -; [ecx+0x40] is shorter than [ebx+0x1fe]: one-byte offset vs 4-bytes offset. - lea ecx, [ebx+0x1be] ; ecx -> partition table - cmp word [ecx+0x40], 0xaa55 - jnz .mbr_failed -; 8. The MBR is treated differently from EBRs. For MBR we additionally need to -; execute step 10 and possibly step 11. - test ebp, ebp - jnz .mbr -; 9. Handle GUID Partition Table -; 9a. Check if MBR is protective - call is_protective_mbr - jnz .no_gpt -; 9b. If so, try to scan GPT headers - call disk_scan_gpt -; 9c. If any GPT header is valid, ignore MBR - jz .done -; Otherwise process legacy/protective MBR -.no_gpt: -; The partition table can be present or not present. In the first case, we just -; read the MBR. In the second case, we just read the bootsector for a -; filesystem. -; The following algorithm is used to distinguish between these cases. -; A. If at least one entry of the partition table is invalid, this is -; a bootsector. See the description of 'is_partition_table_entry' for -; definition of validity. -; B. If all entries are empty (filesystem type field is zero) and the first -; byte is jmp opcode (0EBh or 0E9h), this is a bootsector which happens to -; have zeros in the place of partition table. -; C. Otherwise, this is an MBR. -; 10. Test for MBR vs bootsector. -; 10a. Check entries. If any is invalid, go to 11 (rule A). - call is_partition_table_entry - jc .notmbr - add ecx, 10h - call is_partition_table_entry - jc .notmbr - add ecx, 10h - call is_partition_table_entry - jc .notmbr - add ecx, 10h - call is_partition_table_entry - jc .notmbr -; 10b. Check types of the entries. If at least one is nonzero, go to 12 (rule C). - mov al, [ecx-30h+PARTITION_TABLE_ENTRY.Type] - or al, [ecx-20h+PARTITION_TABLE_ENTRY.Type] - or al, [ecx-10h+PARTITION_TABLE_ENTRY.Type] - or al, [ecx+PARTITION_TABLE_ENTRY.Type] - jnz .mbr -; 10c. Empty partition table or bootsector with many zeroes? (rule B) - cmp byte [ebx], 0EBh - jz .notmbr - cmp byte [ebx], 0E9h - jnz .mbr -.notmbr: -; 11. This is not an MBR. The media is not partitioned. Create one partition -; which covers all the media and abort the loop. - stdcall disk_add_partition, 0, 0, \ - dword [esi+DISK.MediaInfo.Capacity], dword [esi+DISK.MediaInfo.Capacity+4], esi - jmp .done -.mbr: -; 12. Process all entries of the new MBR/EBR - lea ecx, [ebx+0x1be] ; ecx -> partition table - push 0 ; assume no extended partition - call process_partition_table_entry - add ecx, 10h - call process_partition_table_entry - add ecx, 10h - call process_partition_table_entry - add ecx, 10h - call process_partition_table_entry - pop ebp -; 13. Test whether we found a new EBR and should continue the loop. -; 13a. If there was no next EBR, return. - test ebp, ebp - jz .done -; Ok, we have EBR. -; 13b. EBRs addresses are relative to the start of extended partition. -; For simplicity, just abort if an 32-bit overflow occurs; large disks -; are most likely partitioned with GPT, not MBR scheme, since the precise -; calculation here would increase limit just twice at the price of big -; compatibility problems. - pop eax ; load extended partition - add ebp, eax - jc .mbr_failed -; 13c. If extended partition has not yet started, start it. - test eax, eax - jnz @f - mov eax, ebp -@@: -; 13d. If the limit is not exceeded, continue the loop. - dec dword [esp] - push eax ; store extended partition - jnz .new_mbr -.mbr_failed: -.done: -; 14. Cleanup after the loop. - pop eax ; not important anymore - pop eax ; not important anymore - pop ebp ; restore ebp -; 15. Release the buffer. -; 15a. Test whether it is the global buffer or we have allocated it. - cmp ebx, mbr_buffer - jz .release_partition_buffer -; 15b. If we have allocated it, free it. - xchg eax, ebx - call free - jmp .nothing -; 15c. Otherwise, release reference. -.release_partition_buffer: - lock dec [partition_buffer_users] -.nothing: -; 16. Return. - ret - - -; This function is called from disk_scan_partitions to validate and parse -; primary and backup GPTs. -proc disk_scan_gpt - push ecx -; Scan primary GPT (second sector) - stdcall scan_gpt, 1, 0 - test eax, eax -; There is no code to restore backup GPT if it's corrupt. -; Therefore just exit if Primary GPT has been parsed successfully. - jz .exit - DEBUGF 1, 'K : Primary GPT is corrupt, trying backup one\n' - mov eax, dword[esi+DISK.MediaInfo.Capacity+0] - mov edx, dword[esi+DISK.MediaInfo.Capacity+4] - sub eax, 1 - sbb edx, 0 -; Scan backup GPT (last sector) - stdcall scan_gpt, eax, edx - test eax, eax - jz .exit - DEBUGF 1, 'K : Backup GPT is also corrupt, fallback to legacy MBR\n' -.exit: -; Return value is ZF - pop ecx - ret -endp - - -; This function is called from disk_scan_gpt to process a single GPT. -proc scan_gpt _mylba:qword -locals - GPEA_len dd ? ; Length of GPT Partition Entry Array in bytes -endl - push ebx edi -; Allocalte memory for GPT header - mov eax, [esi+DISK.MediaInfo.SectorSize] - stdcall kernel_alloc, eax - test eax, eax - jz .fail -; Save pointer to stack, just in case - push eax - mov ebx, eax -; Read GPT header - mov al, DISKFUNC.read - push 1 - stdcall disk_call_driver, ebx, dword[_mylba+0], dword[_mylba+4], esp - pop ecx - test eax, eax - jnz .fail_free_gpt -; Check signature - cmp dword[ebx+GPTH.Signature+0], 'EFI ' - jnz .fail_free_gpt - cmp dword[ebx+GPTH.Signature+4], 'PART' - jnz .fail_free_gpt -; Check Revision - cmp [ebx+GPTH.Revision], 0x00010000 - jnz .fail_free_gpt -; Compute and check CRC32 - xor edx, edx - xchg edx, [ebx+GPTH.HeaderCRC32] - mov eax, -1 - stdcall crc_32, 0xEDB88320, ebx, [ebx+GPTH.HeaderSize] - xor eax, -1 - cmp eax, edx - jnz .fail_free_gpt -; Reserved must be zero - cmp [ebx+GPTH.Reserved], 0 - jnz .fail_free_gpt -; MyLBA of GPT header at LBA X must equal X - mov eax, dword[ebx+GPTH.MyLBA+0] - mov edx, dword[ebx+GPTH.MyLBA+4] - cmp eax, dword[_mylba+0] - jnz .fail_free_gpt - cmp edx, dword[_mylba+4] - jnz .fail_free_gpt -; Capacity - MyLBA = AlternateLBA - mov eax, dword[esi+DISK.MediaInfo.Capacity+0] - mov edx, dword[esi+DISK.MediaInfo.Capacity+4] - sub eax, dword[_mylba+0] - sbb edx, dword[_mylba+4] - cmp eax, dword[ebx+GPTH.AlternateLBA+0] - jnz .fail_free_gpt - cmp edx, dword[ebx+GPTH.AlternateLBA+4] - jnz .fail_free_gpt - -; Compute GPT Partition Entry Array (GPEA) length in bytes - mov eax, [ebx+GPTH.NumberOfPartitionEntries] - mul [ebx+GPTH.SizeOfPartitionEntry] - test edx, edx ; far too big - jnz .fail_free_gpt -; Round up to sector boundary - mov ecx, [esi+DISK.MediaInfo.SectorSize] ; power of two - dec ecx - add eax, ecx - jc .fail_free_gpt ; too big - not ecx - and eax, ecx -; We will need this length to compute CRC32 of GPEA - mov [GPEA_len], eax -; Allocate memory for GPEA - stdcall kernel_alloc, eax - test eax, eax - jz .fail_free_gpt -; Save to not juggle with registers - push eax - mov edi, eax - mov eax, [GPEA_len] - xor edx, edx -; Get the number of sectors GPEA fits into - div [esi+DISK.MediaInfo.SectorSize] - push eax ; esp = pointer to the number of sectors - mov al, DISKFUNC.read - stdcall disk_call_driver, edi, dword[ebx+GPTH.PartitionEntryLBA+0], \ - dword[ebx+GPTH.PartitionEntryLBA+4], esp - test eax, eax - pop eax - jnz .fail_free_gpea_gpt -; Compute and check CRC32 of GPEA - mov eax, -1 - stdcall crc_32, 0xEDB88320, edi, [GPEA_len] - xor eax, -1 - cmp eax, [ebx+GPTH.PartitionEntryArrayCRC32] - jnz .fail_free_gpea_gpt - -; Process partitions, skip zeroed ones. -.next_gpe: - xor eax, eax - mov ecx, [ebx+GPTH.SizeOfPartitionEntry] - repz scasb - jz .skip - add edi, ecx - sub edi, [ebx+GPTH.SizeOfPartitionEntry] -; Length of a partition in sectors is EndingLBA - StartingLBA + 1 - mov eax, dword[edi+GPE.EndingLBA+0] - mov edx, dword[edi+GPE.EndingLBA+4] - sub eax, dword[edi+GPE.StartingLBA+0] - sbb edx, dword[edi+GPE.StartingLBA+4] - add eax, 1 - adc edx, 0 - push ebx - mov ebx, [ebp-8] ; three-sectors-sized buffer - stdcall disk_add_partition, dword[edi+GPE.StartingLBA+0], \ - dword[edi+GPE.StartingLBA+4], eax, edx, esi - pop ebx - add edi, [ebx+GPTH.SizeOfPartitionEntry] -.skip: - dec [ebx+GPTH.NumberOfPartitionEntries] - jnz .next_gpe - -; Pointers to GPT header and GPEA are on the stack - stdcall kernel_free - stdcall kernel_free - pop edi ebx - xor eax, eax - ret -.fail_free_gpea_gpt: - stdcall kernel_free -.fail_free_gpt: - stdcall kernel_free -.fail: - pop edi ebx - xor eax, eax - inc eax - ret -endp - -; ecx = pointer to partition records array (MBR + 446) -is_protective_mbr: - push ecx edi - xor eax, eax - cmp [ecx-2], ax - jnz .exit -; Partition record 0 has specific fields - cmp [ecx+0], al - jnz .exit - cmp byte[ecx+4], 0xEE - jnz .exit - cmp dword[ecx+8], 1 - jnz .exit - mov edi, -1 - cmp [ecx+12], edi - jz @f - add edi, dword[esi+DISK.MediaInfo.Capacity+0] - cmp [ecx+12], edi - jnz .exit -@@: -; Check that partition records 1-3 are filled with zero - lea edi, [ecx+16] - mov ecx, 16*3/2 ; 3 partitions - repz scasw -.exit: - pop edi ecx -; Return value is ZF - ret - -; This is an internal function called from disk_scan_partitions. It checks -; whether the entry pointed to by ecx is a valid entry of partition table. -; The entry is valid if the first byte is 0 or 80h, the first sector plus the -; length is less than twice the size of media. Multiplication by two is -; required since the size mentioned in the partition table can be slightly -; greater than the real size. -is_partition_table_entry: -; 1. Check .Bootable field. - mov al, [ecx+PARTITION_TABLE_ENTRY.Bootable] - and al, 7Fh - jnz .invalid -; 3. Calculate first sector + length. Note that .FirstAbsSector is relative -; to the MBR/EBR, so the real sum is ebp + .FirstAbsSector + .Length. - mov eax, ebp - xor edx, edx - add eax, [ecx+PARTITION_TABLE_ENTRY.FirstAbsSector] - adc edx, 0 - add eax, [ecx+PARTITION_TABLE_ENTRY.Length] - adc edx, 0 -; 4. Divide by two. - shr edx, 1 - rcr eax, 1 -; 5. Compare with capacity. If the subtraction (edx:eax) - .Capacity does not -; overflow, this is bad. - sub eax, dword [esi+DISK.MediaInfo.Capacity] - sbb edx, dword [esi+DISK.MediaInfo.Capacity+4] - jnc .invalid -.valid: -; 5. Return success: CF is cleared. - clc - ret -.invalid: -; 6. Return fail: CF is set. - stc - ret - -; This is an internal function called from disk_scan_partitions. It processes -; the entry pointed to by ecx. -; * If the entry is invalid, just ignore this entry. -; * If the type is zero, just ignore this entry. -; * If the type is one of types for extended partition, store the address -; of this partition as the new MBR in [esp+4]. -; * Otherwise, add the partition to the list of partitions for this disk. -; We don't use the type from the entry to identify the file system; -; fs-specific checks do this more reliably. -process_partition_table_entry: -; 1. Check for valid entry. If invalid, return (go to 5). - call is_partition_table_entry - jc .nothing -; 2. Check for empty entry. If invalid, return (go to 5). - mov al, [ecx+PARTITION_TABLE_ENTRY.Type] - test al, al - jz .nothing -; 3. Check for extended partition. If extended, go to 6. -irp type,\ - 0x05,\ ; DOS: extended partition - 0x0f,\ ; WIN95: extended partition, LBA-mapped - 0xc5,\ ; DRDOS/secured: extended partition - 0xd5 ; Old Multiuser DOS secured: extended partition -{ - cmp al, type - jz .extended -} -; 4. If we are here, that is a normal partition. Add it to the list. -; Note that the first sector is relative to MBR/EBR. - mov eax, ebp - xor edx, edx - add eax, [ecx+PARTITION_TABLE_ENTRY.FirstAbsSector] - adc edx, 0 - push ecx - stdcall disk_add_partition, eax, edx, \ - [ecx+PARTITION_TABLE_ENTRY.Length], 0, esi - pop ecx -.nothing: -; 5. Return. - ret -.extended: -; 6. If we are here, that is an extended partition. Store the address. - mov eax, [ecx+PARTITION_TABLE_ENTRY.FirstAbsSector] - mov [esp+4], eax - ret - -; This is an internal function called from disk_scan_partitions and -; process_partition_table_entry. It adds one partition to the list of -; partitions for the media. -; Important note: start, length, disk MUST be present and -; MUST be in the same order as in PARTITION structure. -; esi duplicates [disk]. -proc disk_add_partition stdcall uses ebx edi, start:qword, length:qword, disk:dword -; 1. Check that this partition will not exceed the limit on total number. - cmp [esi+DISK.NumPartitions], MAX_NUM_PARTITIONS - jae .nothing -; 2. Check that this partition does not overlap with any already registered -; partition. Since any file system assumes that the disk data will not change -; outside of its control, such overlap could be destructive. -; Since the number of partitions is usually very small and is guaranteed not -; to be large, the simple linear search is sufficient. -; 2a. Prepare the loop: edi will point to the current item of .Partitions -; array, ecx will be the current item, ebx will hold number of items left. - mov edi, [esi+DISK.Partitions] - mov ebx, [esi+DISK.NumPartitions] - test ebx, ebx - jz .partitionok -.scan_existing: -; 2b. Get the next partition. - mov ecx, [edi] - add edi, 4 -; The range [.FirstSector, .FirstSector+.Length) must be either entirely to -; the left of [start, start+length) or entirely to the right. -; 2c. Subtract .FirstSector - start. The possible overflow distinguish between -; cases "to the left" (2e) and "to the right" (2d). - mov eax, dword [ecx+PARTITION.FirstSector] - mov edx, dword [ecx+PARTITION.FirstSector+4] - sub eax, dword [start] - sbb edx, dword [start+4] - jb .less -; 2d. .FirstSector is greater than or equal to start. Check that .FirstSector -; is greater than or equal to start+length; the subtraction -; (.FirstSector-start) - length must not cause overflow. Go to 2g if life is -; good or to 2f in the other case. - sub eax, dword [length] - sbb edx, dword [length+4] - jb .overlap - jmp .next_existing -.less: -; 2e. .FirstSector is less than start. Check that .FirstSector+.Length is less -; than or equal to start. If the addition (.FirstSector-start) + .Length does -; not cause overflow, then .FirstSector + .Length is strictly less than start; -; since the equality is also valid, use decrement preliminarily. Go to 2g or -; 2f depending on the overflow. - sub eax, 1 - sbb edx, 0 - add eax, dword [ecx+PARTITION.Length] - adc edx, dword [ecx+PARTITION.Length+4] - jnc .next_existing -.overlap: -; 2f. The partition overlaps with previously registered partition. Say warning -; and return with nothing done. - dbgstr 'two partitions overlap, ignoring the last one' - jmp .nothing -.next_existing: -; 2g. The partition does not overlap with the current partition. Continue the -; loop. - dec ebx - jnz .scan_existing -.partitionok: -; 3. The partition has passed tests. Reallocate the partitions array for a new -; entry. -; 3a. Call the allocator. - mov eax, [esi+DISK.NumPartitions] - inc eax ; one more entry - shl eax, 2 ; each entry is dword - call malloc -; 3b. Test the result. If failed, return with nothing done. - test eax, eax - jz .nothing -; 3c. Copy the old array to the new array. - mov edi, eax - push esi - mov ecx, [esi+DISK.NumPartitions] - mov esi, [esi+DISK.Partitions] - rep movsd - pop esi -; 3d. Set the field in the DISK structure to the new array. - xchg [esi+DISK.Partitions], eax -; 3e. Free the old array. - call free -; 4. Recognize the file system. -; 4a. Call the filesystem recognizer. It will allocate the PARTITION structure -; with possible filesystem-specific fields. - call disk_detect_partition -; 4b. Check return value. If zero, return with list not changed; so far only -; the array was reallocated, this is ok for other code. - test eax, eax - jz .nothing -; 5. Insert the new partition to the list. - stosd - inc [esi+DISK.NumPartitions] -; 6. Return. -.nothing: - ret -endp - -; This is an internal function called from disk_add_partition. -; It tries to recognize the file system on the partition and allocates the -; corresponding PARTITION structure with filesystem-specific fields. -disk_detect_partition: -; This function inherits the stack frame from disk_add_partition. In stdcall -; with ebp-based frame arguments start from ebp+8, since [ebp]=saved ebp -; and [ebp+4]=return address. -virtual at ebp+8 -.start dq ? -.length dq ? -.disk dd ? -end virtual -; 1. Read the bootsector to the buffer. -; When disk_add_partition is called, ebx contains a pointer to -; a three-sectors-sized buffer. This function saves ebx in the stack -; immediately before ebp. - mov ebx, [ebp-4] ; get buffer - add ebx, [esi+DISK.MediaInfo.SectorSize] ; advance over MBR data to bootsector data - add ebp, 8 ; ebp points to part of PARTITION structure - xor eax, eax ; first sector of the partition - call fs_read32_sys - push eax -; 2. Run tests for all supported filesystems. If at least one test succeeded, -; go to 4. -; For tests: -; ebp -> first three fields of PARTITION structure, .start, .length, .disk; -; [esp] = error code after bootsector read: 0 = ok, otherwise = failed, -; ebx points to the buffer for bootsector, -; ebx+[esi+DISK.MediaInfo.SectorSize] points to sector-sized buffer that can be used for anything. - call fat_create_partition - test eax, eax - jnz .success - call ntfs_create_partition - test eax, eax - jnz .success - call ext2_create_partition - test eax, eax - jnz .success - call xfs_create_partition - test eax, eax - jnz .success -; 3. No file system has recognized the volume, so just allocate the PARTITION -; structure without extra fields. - movi eax, sizeof.PARTITION - call malloc - test eax, eax - jz .nothing - mov edx, dword [ebp+PARTITION.FirstSector] - mov dword [eax+PARTITION.FirstSector], edx - mov edx, dword [ebp+PARTITION.FirstSector+4] - mov dword [eax+PARTITION.FirstSector+4], edx - mov edx, dword [ebp+PARTITION.Length] - mov dword [eax+PARTITION.Length], edx - mov edx, dword [ebp+PARTITION.Length+4] - mov dword [eax+PARTITION.Length+4], edx - mov [eax+PARTITION.Disk], esi - mov [eax+PARTITION.FSUserFunctions], default_fs_functions -.success: -.nothing: - sub ebp, 8 ; restore ebp -; 4. Return with eax = pointer to PARTITION or NULL. - pop ecx - ret - -iglobal -align 4 -default_fs_functions: - dd free - dd 0 ; no user functions -endg - -; This function is called from syscall_file_system_lfn. -; This handler gets the control each time when fn 70 is called -; with unknown item of root subdirectory. -; in: esi = ebp -> path string -; out: if the handler processes path, it must not return in syscall_file_system_lfn, -; but instead pop return address and return directly to the caller -; otherwise simply return -dyndisk_handler: - push ebx edi ; save registers used in syscall_file_system_lfn -; 1. Acquire the mutex. - mov ecx, disk_list_mutex - call mutex_lock -; 2. Loop over the list of DISK structures. -; 2a. Initialize. - mov ebx, disk_list -.scan: -; 2b. Get the next item. - mov ebx, [ebx+DISK.Next] -; 2c. Check whether the list is done. If so, go to 3. - cmp ebx, disk_list - jz .notfound -; 2d. Compare names. If names match, go to 5. - mov edi, [ebx+DISK.Name] - push esi -@@: -; esi points to the name from fs operation; it is terminated by zero or slash. - lodsb - test al, al - jz .eoin_dec - cmp al, '/' - jz .eoin -; edi points to the disk name. - inc edi -; edi points to lowercase name, this is a requirement for the driver. -; Characters at esi can have any register. Lowercase the current character. -; This lowercasing works for latin letters and digits; since the disk name -; should not contain other symbols, this is ok. - or al, 20h - cmp al, [edi-1] - jz @b -.wrongname: -; 2f. Names don't match. Continue the loop. - pop esi - jmp .scan -.notfound: -; The loop is done and no name matches. -; 3. Release the mutex. - call mutex_unlock -; 4. Return normally. - pop edi ebx ; restore registers used in syscall_file_system_lfn - ret -; part of 2d: the name matches partially, but we must check that this is full -; equality. -.eoin_dec: - dec esi -.eoin: - cmp byte [edi], 0 - jnz .wrongname -; We found the addressed DISK structure. -; 5. Reference the disk. - lock inc [ebx+DISK.RefCount] -; 6. Now we are sure that the DISK structure is not going to die at least -; while we are working with it, so release the global mutex. - call mutex_unlock - pop ecx ; pop from the stack saved value of esi -; 7. Acquire the mutex for media object. - pop edi ; restore edi - lea ecx, [ebx+DISK.MediaLock] - call mutex_lock -; 8. Get the media object. If it is not NULL, reference it. - xor edx, edx - cmp [ebx+DISK.MediaInserted], dl - jz @f - mov edx, ebx - inc [ebx+DISK.MediaRefCount] -@@: -; 9. Now we are sure that the media object, if it exists, is not going to die -; at least while we are working with it, so release the mutex for media object. - call mutex_unlock - mov ecx, ebx - pop ebx eax ; restore ebx, pop return address -; 10. Check whether the fs operation wants to enumerate partitions (go to 11) -; or work with some concrete partition (go to 12). - cmp byte [esi], 0 - jnz .haspartition -; 11. The fs operation wants to enumerate partitions. -; Check whether the media is inserted. - mov esi, fs_dyndisk_next_nomedia - test edx, edx - jz @f - mov esi, fs_dyndisk_next -@@: ; Let the procedure from fs_lfn.inc do the job. - jmp syscall_file_system_lfn.maindir_noesi - -.root: - pop ecx edx - xor eax, eax - cmp byte [ebx], 9 - jz .cleanup_ecx -.access_denied: - movi eax, ERROR_ACCESS_DENIED -.cleanup_ecx: - mov [esp+32], eax - mov esi, ecx ; disk*dereference assume that esi points to DISK - test edx, edx ; if there are no media, we didn't reference it - jz @f - call disk_media_dereference -@@: - call disk_dereference - stdcall kernel_free, ebp - ret - -.dyndisk_cleanup: - pop ecx edx - movi eax, ERROR_FILE_NOT_FOUND - jmp .cleanup_ecx - -.haspartition: -; 12. The fs operation has specified some partition. - push edx ecx - xor eax, eax - lodsb - sub eax, '0' - jz .dyndisk_cleanup - cmp eax, 10 - jnc .dyndisk_cleanup - mov ecx, eax - lodsb - cmp eax, '/' - jz @f - test eax, eax - jnz .dyndisk_cleanup - dec esi -@@: - cmp byte [esi], 0 - jnz @f - cmp byte [ebx], 1 - jz @f - cmp byte [ebx], 5 - jnz .root -@@: - dec ecx ; convert to zero-based partition index - pop edx ; edx = pointer to DISK, dword [esp] = NULL or edx -; If the driver does not support insert notifications and we are the only fs -; operation with this disk, ask the driver whether the media -; was inserted/removed/changed. Otherwise, assume that media status is valid. - test byte [edx+DISK.DriverFlags], DISK_NO_INSERT_NOTIFICATION - jz .media_accurate - push ecx esi - mov esi, edx - cmp dword [esp+8], 0 - jz .test_no_media - cmp [esi+DISK.MediaRefCount], 2 - jnz .media_accurate_pop - lea edx, [esi+DISK.MediaInfo] - and [edx+DISKMEDIAINFO.Flags], 0 - mov al, DISKFUNC.querymedia - stdcall disk_call_driver, edx - test eax, eax - jz .media_accurate_pop - stdcall disk_media_dereference ; drop our reference so that disk_media_changed could close the media - stdcall disk_media_changed, esi, 0 - and dword [esp+8], 0 ; no media -.test_no_media: - stdcall disk_media_changed, esi, 1 ; issue fake notification -; if querymedia() inside disk_media_changed returns error, the notification is ignored - cmp [esi+DISK.MediaInserted], 0 - jz .media_accurate_pop - lock inc [esi+DISK.MediaRefCount] - mov dword [esp+8], esi -.media_accurate_pop: - mov edx, esi - pop esi ecx -.media_accurate: - pop eax - test eax, eax - jz .nomedia - cmp ecx, [edx+DISK.NumPartitions] - jae .notfound2 - mov eax, [edx+DISK.Partitions] - mov eax, [eax+ecx*4] - mov edi, [eax+PARTITION.FSUserFunctions] - mov ecx, [ebx] - cmp [edi+4], ecx - jbe .unsupported - pushd edx ebp eax [edi+8+ecx*4] - cmp ecx, 10 - jnz .callFS - or ecx, -1 - mov edi, esi - xor eax, eax - repnz scasb - mov edx, edi - dec edi - mov al, '/' - std - repnz scasb - cld - inc edi - mov [edi], ah - mov ebp, [current_slot] - add ebp, APPDATA.cur_dir - pushd ebx esi edx [ebp] ebp edi - sub esi, 2 - mov [ebp], esi - mov edi, edx - mov esi, [ebx+16] - mov eax, [ebx+20] - cmp eax, 4 - jc @f - xor eax, eax -@@: - call getFullPath - pop edi ebp - mov byte [edi], '/' - popd [ebp] edi esi ebx - add edi, 2 - test eax, eax - jz .errorRename - cmp byte [edi], 0 - jz .errorRename -.callFS: - pop eax ebp - call eax - pop ebp edx - mov dword [esp+20], ebx -.cleanup: - mov dword [esp+32], eax - mov esi, edx - call disk_media_dereference -@@: - call disk_dereference - stdcall kernel_free, ebp - ret - -.unsupported: - movi eax, ERROR_UNKNOWN_FS - cmp edi, default_fs_functions - jz .cleanup - movi eax, ERROR_UNSUPPORTED_FS - jmp .cleanup - -.errorRename: - pop eax eax ebp edx -.notfound2: - movi eax, ERROR_FILE_NOT_FOUND - jmp .cleanup - -.nomedia: - test ecx, ecx - jnz .notfound2 - mov dword [esp+32], ERROR_DEVICE - mov esi, edx - jmp @b - -; This is a callback for enumerating partitions called from -; syscall_file_system_lfn.maindir in the case of inserted media. -; It just increments eax until DISK.NumPartitions reached and then -; cleans up. -fs_dyndisk_next: - mov ecx, [esp+8] - cmp eax, [ecx+DISK.NumPartitions] - jae .nomore - inc eax - clc - ret -.nomore: - pusha - mov esi, ecx - call disk_media_dereference - call disk_dereference - popa - stc - ret - -; This is a callback for enumerating partitions called from -; syscall_file_system_lfn.maindir in the case of missing media. -; In this case we create one pseudo-partition. -fs_dyndisk_next_nomedia: - cmp eax, 1 - jae .nomore - inc eax - clc - ret -.nomore: - mov ecx, [esp+8] - pusha - mov esi, ecx - call disk_dereference - popa - stc - ret - -; This function is called from syscall_file_system_lfn. -; This handler is called when virtual root is enumerated -; and must return all items which can be handled by this. -; It is called several times, first time with eax=0 -; in: eax = 0 for first call, previously returned value for subsequent calls -; out: eax = 0 => no more items -; eax != 0 => buffer pointed to by edi contains name of item -dyndisk_enum_root: - push edx ; save register used in syscall_file_system_lfn - mov ecx, disk_list_mutex ; it will be useful -; 1. If this is the first call, acquire the mutex and initialize. - test eax, eax - jnz .notfirst - call mutex_lock - mov eax, disk_list -.notfirst: -; 2. Get next item. - mov eax, [eax+DISK.Next] -; 3. If there are no more items, go to 6. - cmp eax, disk_list - jz .last -; 4. Copy name from the DISK structure to edi. - push eax esi - mov esi, [eax+DISK.Name] -@@: - lodsb - stosb - test al, al - jnz @b - pop esi eax -; 5. Return with eax = item. - pop edx ; restore register used in syscall_file_system_lfn - ret -.last: -; 6. Release the mutex and return with eax = 0. - call mutex_unlock - xor eax, eax - pop edx ; restore register used in syscall_file_system_lfn - ret diff --git a/kernel/branches/Kolibri-F/blkdev/disk_cache.inc b/kernel/branches/Kolibri-F/blkdev/disk_cache.inc deleted file mode 100644 index a6cfd309d..000000000 --- a/kernel/branches/Kolibri-F/blkdev/disk_cache.inc +++ /dev/null @@ -1,1387 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2011-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; Read/write functions try to do large operations, -; it is significantly faster than several small operations. -; This requires large buffers. -; We can't use input/output buffers directly - they can be controlled -; by user-mode application, so they can be modified between the operation -; and copying to/from cache, giving invalid data in cache. -; It is unclear how to use cache directly, currently cache items are -; allocated/freed sector-wise, so items for sequential sectors can be -; scattered over all the cache. -; So read/write functions allocate a temporary buffer which is -; 1) not greater than half of free memory and -; 2) not greater than the following constant. -CACHE_MAX_ALLOC_SIZE = 4 shl 20 - -; Legacy interface for filesystems fs_{read,write}32_{sys,app} -; gives only one sector for FS. However, per-sector reading is inefficient, -; so internally fs_read32_{sys,app} reads to the cache several sequential -; sectors, hoping that they will be useful. -; Total number of sectors is given by the following constant. -CACHE_LEGACY_READ_SIZE = 16 - -; This structure describes one item in the cache. -struct CACHE_ITEM -SectorLo dd ? ; low 32 bits of sector -SectorHi dd ? ; high 32 bits of sector -Status dd ? ; one of CACHE_ITEM_* -ends - -; Possible values for CACHE_ITEM_* -CACHE_ITEM_EMPTY = 0 -CACHE_ITEM_COPY = 1 -CACHE_ITEM_MODIFIED = 2 - -; Read several sequential sectors using cache #1. -; in: edx:eax = start sector, relative to start of partition -; in: ecx = number of sectors to read -; in: ebx -> buffer -; in: ebp -> PARTITION -; out: eax = error code, 0 = ok -; out: ecx = number of sectors that were read -fs_read64_sys: -; Save ebx, set ebx to SysCache and let the common part do its work. - push ebx ebx - mov ebx, [ebp+PARTITION.Disk] - add ebx, DISK.SysCache - jmp fs_read64_common - -; Read several sequential sectors using cache #2. -; in: edx:eax = start sector, relative to start of partition -; in: ecx = number of sectors to read -; in: edi -> buffer -; in: ebp -> PARTITION -; out: eax = error code, 0 = ok -; out: ecx = number of sectors that were read -fs_read64_app: -; Save ebx, set ebx to AppCache and let the common part do its work. - push ebx ebx - mov ebx, [ebp+PARTITION.Disk] - add ebx, DISK.AppCache - -; Common part of fs_read64_{app,sys}: -; read several sequential sectors using the given cache. -fs_read64_common: -; 1. Setup stack frame. - push esi edi ; save used registers to be stdcall - push 0 ; initialize .error_code - push ebx edx eax ecx ecx ; initialize stack variables -virtual at esp -.local_vars: -.num_sectors_orig dd ? -; Number of sectors that should be read. Used to generate output value of ecx. -.num_sectors dd ? -; Number of sectors that remain to be read. Decreases from .num_sectors_orig to 0. -.sector_lo dd ? ; low 32 bits of the current sector -.sector_hi dd ? ; high 32 bits of the current sector -.cache dd ? ; pointer to DISKCACHE -.error_code dd ? ; current status -.local_vars_size = $ - .local_vars -.saved_regs rd 2 -.buffer dd ? ; filled by fs_read64_{sys,app} -end virtual -; 2. Validate parameters against partition length: -; immediately return error if edx:eax are beyond partition end, -; decrease .num_sectors and .num_sectors_orig, if needed, -; so that the entire operation fits in the partition limits. - mov eax, dword [ebp+PARTITION.Length] - mov edx, dword [ebp+PARTITION.Length+4] - sub eax, [.sector_lo] - sbb edx, [.sector_hi] - jb .end_of_media - jnz .no_end_of_media - cmp ecx, eax - jbe .no_end_of_media -; If .num_sectors got decreased, set status to DISK_STATUS_END_OF_MEDIA; -; if all subsequent operations would be successful, this would become the final -; status, otherwise this would be rewritten by failed operation. - mov [.num_sectors], eax - mov [.num_sectors_orig], eax - mov [.error_code], DISK_STATUS_END_OF_MEDIA -.no_end_of_media: -; 3. If number of sectors to read is zero, either because zero-sectors operation -; was requested or because it got decreased to zero due to partition limits, -; just return the current status. - cmp [.num_sectors], 0 - jz .return -; 4. Shift sector from partition-relative to absolute. - mov eax, dword [ebp+PARTITION.FirstSector] - mov edx, dword [ebp+PARTITION.FirstSector+4] - add [.sector_lo], eax - adc [.sector_hi], edx -; 5. If the cache is disabled, pass the request directly to the driver. - cmp [ebx+DISKCACHE.pointer], 0 - jz .nocache -; 6. Look for sectors in the cache, sequentially from the beginning. -; Stop at the first sector that is not in the cache -; or when all sectors were read from the cache. -; 6a. Acquire the lock. - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.CacheLock - call mutex_lock -.lookup_in_cache_loop: -; 6b. For each sector, call the lookup function without adding to the cache. - mov eax, [.sector_lo] - mov edx, [.sector_hi] - call cache_lookup_read -; 6c. If it has failed, the sector is not in cache; -; release the lock and go to 7. - jc .not_found_in_cache -; The sector is found in cache. -; 6d. Copy data for the caller, advance [.buffer]. - mov esi, edi - mov edi, [.buffer] - mov eax, 1 - shl eax, cl - mov ecx, eax - shr ecx, 2 - rep movsd - mov [.buffer], edi -; 6e. Advance the sector. - add [.sector_lo], 1 - adc [.sector_hi], 0 -; 6f. Decrement number of sectors left. -; If all sectors were read, release the lock and return. - dec [.num_sectors] - jnz .lookup_in_cache_loop -; Release the lock acquired at 6a. - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.CacheLock - call mutex_unlock -.return: - mov eax, [.error_code] - mov ecx, [.num_sectors_orig] - sub ecx, [.num_sectors] -.nothing: - add esp, .local_vars_size - pop edi esi ebx ebx ; restore used registers to be stdcall - ret -.not_found_in_cache: -; Release the lock acquired at 6a. - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.CacheLock - call mutex_unlock -; The current sector is not present in the cache. -; Ask the driver to read all requested not-yet-read sectors, -; put results in the cache. -; Also, see the comment before the definition of CACHE_MAX_ALLOC_SIZE. -; 7. Allocate buffer for operations. -; Normally, create buffer that is sufficient for all remaining data. -; However, for extra-large requests make an upper limit: -; do not use more than half of the free memory -; or more than CACHE_MAX_ALLOC_SIZE bytes. - mov ecx, [ebx+DISKCACHE.sector_size_log] - mov ebx, [pg_data.pages_free] - shr ebx, 1 - jz .nomemory - cmp ebx, CACHE_MAX_ALLOC_SIZE shr 12 - jbe @f - mov ebx, CACHE_MAX_ALLOC_SIZE shr 12 -@@: - shl ebx, 12 - shr ebx, cl - jz .nomemory - cmp ebx, [.num_sectors] - jbe @f - mov ebx, [.num_sectors] -@@: - mov eax, ebx - shl eax, cl - stdcall kernel_alloc, eax -; If failed, return the appropriate error code. - test eax, eax - jz .nomemory - mov esi, eax -; Split the request to chunks that fit in the allocated buffer. -.read_loop: -; 8. Get iteration size: either size of allocated buffer in sectors -; or number of sectors left, select what is smaller. - cmp ebx, [.num_sectors] - jbe @f - mov ebx, [.num_sectors] -@@: -; 9. Create second portion of local variables. -; Note that variables here and above are esp-relative; -; it means that all addresses should be corrected when esp is changing. - push ebx esi esi - push ebx -; In particular, num_sectors is now [.num_sectors+.local_vars2_size]. -virtual at esp -.local_vars2: -.current_num_sectors dd ? ; number of sectors that were read -.current_buffer dd ? -; pointer inside .allocated_buffer that points -; to the beginning of not-processed data -.allocated_buffer dd ? ; saved in safe place -.iteration_size dd ? ; saved in safe place -.local_vars2_size = $ - .local_vars2 -end virtual -; 10. Call the driver, reading the next chunk. - push esp ; numsectors - push [.sector_hi+.local_vars2_size+4] ; startsector - push [.sector_lo+.local_vars2_size+8] ; startsector - push esi ; buffer - mov esi, [ebp+PARTITION.Disk] - mov al, DISKFUNC.read - call disk_call_driver -; If failed, save error code. - test eax, eax - jz @f - mov [.error_code+.local_vars2_size], eax -@@: -; 11. Copy data for the caller, advance .buffer. - cmp [.current_num_sectors], 0 - jz .copy_done - mov ebx, [.cache+.local_vars2_size] - mov eax, [.current_num_sectors] - mov ecx, [ebx+DISKCACHE.sector_size_log] - shl eax, cl - mov esi, [.allocated_buffer] - mov edi, [.buffer+.local_vars2_size] - mov ecx, eax - shr ecx, 2 - rep movsd - mov [.buffer+.local_vars2_size], edi -; 12. Copy data to the cache. -; 12a. Acquire the lock. - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.CacheLock - call mutex_lock -; 12b. Prepare for the loop: create a local variable that -; stores number of sectors to be copied. - push [.current_num_sectors] -.store_to_cache: -; 12c. For each sector, call the lookup function with adding to the cache, if not yet. - mov eax, [.sector_lo+.local_vars2_size+4] - mov edx, [.sector_hi+.local_vars2_size+4] - call cache_lookup_write - test eax, eax - jnz .cache_error -; 12d. If the sector was already present in the cache as modified, -; data that were read at step 10 for this sector are obsolete, -; so rewrite data for the caller from the cache. - cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED - jnz .not_modified - mov esi, edi - mov edi, [.buffer+.local_vars2_size+4] - mov eax, [esp] - shl eax, cl - sub edi, eax - mov eax, 1 - shl eax, cl - mov ecx, eax - shr ecx, 2 - rep movsd - add [.current_buffer+4], eax - jmp .sector_done -.not_modified: -; 12e. For each not-modified sector, -; copy data, mark the item as not-modified copy of the disk, -; advance .current_buffer and .sector_hi:.sector_lo to the next sector. - mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY - mov eax, 1 - shl eax, cl - mov esi, [.current_buffer+4] - mov ecx, eax - shr ecx, 2 - rep movsd - mov [.current_buffer+4], esi -.sector_done: - add [.sector_lo+.local_vars2_size+4], 1 - adc [.sector_hi+.local_vars2_size+4], 0 -; 12f. Continue the loop 12c-12e until all sectors are read. - dec dword [esp] - jnz .store_to_cache -.cache_error: -; 12g. Restore after the loop: pop the local variable. - pop ecx -; 12h. Release the lock. - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.CacheLock - call mutex_unlock -.copy_done: -; 13. Remove portion of local variables created at step 9. - pop ecx - pop esi esi ebx -; 14. Continue iterations while number of sectors read by the driver -; is equal to number of sectors requested and there are additional sectors. - cmp ecx, ebx - jnz @f - sub [.num_sectors], ebx - jnz .read_loop -@@: -; 15. Free the buffer allocated at step 7 and return. - stdcall kernel_free, esi - jmp .return - -; Special branches: -.nomemory: -; memory allocation failed at step 7: return the corresponding error - mov [.error_code], DISK_STATUS_NO_MEMORY - jmp .return -.nocache: -; step 5, after correcting number of sectors to fit in partition limits -; and advancing partition-relative sector to absolute, -; sees that cache is disabled: pass corrected request to the driver - lea eax, [.num_sectors] - push eax ; numsectors - push [.sector_hi+4] ; startsector - push [.sector_lo+8] ; startsector - push [.buffer+12] ; buffer - mov esi, [ebp+PARTITION.Disk] - mov al, DISKFUNC.read - call disk_call_driver - test eax, eax - jnz @f - mov eax, [.error_code] -@@: - mov ecx, [.num_sectors] - jmp .nothing -.end_of_media: -; requested sector is beyond the partition end: return the corresponding error - mov [.error_code], DISK_STATUS_END_OF_MEDIA - jmp .return - -; Write several sequential sectors using cache #1. -; in: edx:eax = start sector -; in: ecx = number of sectors to write -; in: ebx -> buffer -; in: ebp -> PARTITION -; out: eax = error code, 0 = ok -; out: ecx = number of sectors that were written -fs_write64_sys: -; Save ebx, set ebx to SysCache and let the common part do its work. - push ebx - mov ebx, [ebp+PARTITION.Disk] - add ebx, DISK.SysCache - jmp fs_write64_common - -; Write several sequential sectors using cache #2. -; in: edx:eax = start sector -; in: ecx = number of sectors to write -; in: ebx -> buffer -; in: ebp -> PARTITION -; out: eax = error code, 0 = ok -; out: ecx = number of sectors that were written -fs_write64_app: -; Save ebx, set ebx to AppCache and let the common part do its work. - push ebx - mov ebx, [ebp+PARTITION.Disk] - add ebx, DISK.AppCache - -; Common part of fs_write64_{app,sys}: -; write several sequential sectors using the given cache. -fs_write64_common: -; 1. Setup stack frame. - push esi edi ; save used registers to be stdcall - push 0 ; initialize .error_code - push edx eax ecx ecx ; initialize stack variables - push [.buffer-4] ; copy [.buffer] to [.cur_buffer] - ; -4 is due to esp-relative addressing -virtual at esp -.local_vars: -.cur_buffer dd ? ; pointer to data that are currently copying -.num_sectors_orig dd ? -; Number of sectors that should be written. Used to generate output value of ecx. -.num_sectors dd ? -; Number of sectors that remain to be written. -.sector_lo dd ? ; low 32 bits of the current sector -.sector_hi dd ? ; high 32 bits of the current sector -.error_code dd ? ; current status -.local_vars_size = $ - .local_vars -.saved_regs rd 2 -.buffer dd ? ; filled by fs_write64_{sys,app} -end virtual -; 2. Validate parameters against partition length: -; immediately return error if edx:eax are beyond partition end, -; decrease .num_sectors and .num_sectors_orig, if needed, -; so that the entire operation fits in the partition limits. - mov eax, dword [ebp+PARTITION.Length] - mov edx, dword [ebp+PARTITION.Length+4] - sub eax, [.sector_lo] - sbb edx, [.sector_hi] - jb .end_of_media - jnz .no_end_of_media - cmp ecx, eax - jbe .no_end_of_media -; If .num_sectors got decreased, set status to DISK_STATUS_END_OF_MEDIA; -; if all subsequent operations would be successful, this would become the final -; status, otherwise this would be rewritten by failed operation. - mov [.num_sectors], eax - mov [.num_sectors_orig], eax - mov [.error_code], DISK_STATUS_END_OF_MEDIA -.no_end_of_media: -; 3. If number of sectors to write is zero, either because zero-sectors operation -; was requested or because it got decreased to zero due to partition limits, -; just return the current status. - cmp [.num_sectors], 0 - jz .return -; 4. Shift sector from partition-relative to absolute. - mov eax, dword [ebp+PARTITION.FirstSector] - mov edx, dword [ebp+PARTITION.FirstSector+4] - add [.sector_lo], eax - adc [.sector_hi], edx -; 5. If the cache is disabled, pass the request directly to the driver. - cmp [ebx+DISKCACHE.pointer], 0 - jz .nocache -; 6. Store sectors in the cache, sequentially from the beginning. -; 6a. Acquire the lock. - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.CacheLock - call mutex_lock -.lookup_in_cache_loop: -; 6b. For each sector, call the lookup function with adding to the cache, if not yet. - mov eax, [.sector_lo] - mov edx, [.sector_hi] - call cache_lookup_write - test eax, eax - jnz .cache_error -; 6c. For each sector, copy data, mark the item as modified and not saved, -; advance .current_buffer to the next sector. - mov [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED - mov eax, 1 - shl eax, cl - mov esi, [.cur_buffer] - mov ecx, eax - shr ecx, 2 - rep movsd - mov [.cur_buffer], esi -; 6d. Remove the sector from the other cache. -; Normally it should not be there, but prefetching could put to the app cache -; data that normally should belong to the sys cache and vice versa. -; Note: this requires that both caches must be protected by the same lock. - mov eax, [.sector_lo] - mov edx, [.sector_hi] - push ebx - sub ebx, [ebp+PARTITION.Disk] - xor ebx, DISK.SysCache xor DISK.AppCache - add ebx, [ebp+PARTITION.Disk] - call cache_lookup_read - jc @f - mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY -@@: - pop ebx -; 6e. Advance .sector_hi:.sector_lo to the next sector. - add [.sector_lo], 1 - adc [.sector_hi], 0 -; 6f. Continue the loop at 6b-6e until all sectors are processed. - dec [.num_sectors] - jnz .lookup_in_cache_loop -.unlock_return: -; 6g. Release the lock and return. - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.CacheLock - call mutex_unlock -.return: - mov eax, [.error_code] - mov ecx, [.num_sectors_orig] - sub ecx, [.num_sectors] -.nothing: - add esp, .local_vars_size - pop edi esi ebx - ret - -; Special branches: -.cache_error: -; error at flushing the cache while adding sector to the cache: -; return the error from the lookup function - mov [.error_code], eax - jmp .unlock_return -.end_of_media: -; requested sector is beyond the partition end: return the corresponding error - mov eax, DISK_STATUS_END_OF_MEDIA - xor ecx, ecx - jmp .nothing -.nocache: -; step 5, after correcting number of sectors to fit in partition limits -; and advancing partition-relative sector to absolute, -; sees that cache is disabled: pass corrected request to the driver - lea eax, [.num_sectors] - push eax ; numsectors - push [.sector_hi+4] ; startsector - push [.sector_lo+8] ; startsector - push [.buffer+12] ; buffer - mov esi, [ebp+PARTITION.Disk] - mov al, DISKFUNC.write - call disk_call_driver - mov ecx, [.num_sectors] - jmp .nothing - -; Legacy. Use fs_read64_sys instead. -; This function is intended to replace the old 'hd_read' function when -; [hdd_appl_data] = 0, so its input/output parameters are the same, except -; that it can't use the global variables 'hd_error' and 'hdd_appl_data'. -; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure -; eax is relative to partition start -; out: eax = error code; 0 = ok -fs_read32_sys: -; Save ebx, set ebx to SysCache and let the common part do its work. - push ebx - mov ebx, [ebp+PARTITION.Disk] - add ebx, DISK.SysCache - jmp fs_read32_common - -; Legacy. Use fs_read64_app instead. -; This function is intended to replace the old 'hd_read' function when -; [hdd_appl_data] = 1, so its input/output parameters are the same, except -; that it can't use the global variables 'hd_error' and 'hdd_appl_data'. -; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure -; eax is relative to partition start -; out: eax = error code; 0 = ok -fs_read32_app: -; Save ebx, set ebx to AppCache and let the common part do its work. - push ebx - mov ebx, [ebp+PARTITION.Disk] - add ebx, DISK.AppCache - -; This label is the common part of fs_read32_sys and fs_read32_app. -fs_read32_common: -; 1. Check that the required sector is inside the partition. If no, return -; DISK_STATUS_END_OF_MEDIA. - cmp dword [ebp+PARTITION.Length+4], 0 - jnz @f - cmp dword [ebp+PARTITION.Length], eax - ja @f - mov eax, DISK_STATUS_END_OF_MEDIA - pop ebx - ret -@@: -; 2. Get the absolute sector on the disk. - push ecx edx esi edi - xor edx, edx - add eax, dword [ebp+PARTITION.FirstSector] - adc edx, dword [ebp+PARTITION.FirstSector+4] -; 3. If there is no cache for this disk, just pass the request to the driver. - cmp [ebx+DISKCACHE.pointer], 0 - jnz .scancache - push 1 - push esp ; numsectors - push edx ; startsector - push eax ; startsector - pushd [esp+32]; buffer - mov esi, [ebp+PARTITION.Disk] - mov al, DISKFUNC.read - call disk_call_driver - pop ecx - pop edi esi edx ecx - pop ebx - ret -.scancache: - push ebx edx eax -virtual at esp -.local_vars: -.sector_lo dd ? -.sector_hi dd ? -.cache dd ? -.local_vars_size = $ - .local_vars -.saved_regs rd 4 -.buffer dd ? -end virtual -; 4. Scan for the requested sector in the cache. -; If found, copy the data and return. -; 4a. Acquire the lock. - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.CacheLock - call mutex_lock -; 4b. Call the lookup function without adding to the cache. - mov eax, [.sector_lo] - mov edx, [.sector_hi] - call cache_lookup_read -; If not found, go to 5. - jc .not_found_in_cache -.found_in_cache: -; 4c. Copy the data. - mov esi, edi - mov edi, [.buffer] - mov eax, 1 - shl eax, cl - mov ecx, eax - shr ecx, 2 - rep movsd -; 4d. Release the lock and return success. - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.CacheLock - call mutex_unlock -.return: - xor eax, eax -.return_eax: - add esp, .local_vars_size - pop edi esi edx ecx - pop ebx - ret -.not_found_in_cache: -; 5. Decide whether we need to prefetch further sectors. -; If so, advance to 6. If not, go to 13. -; Assume that devices < 3MB are floppies which are slow -; (ramdisk does not have a cache, so we don't even get here for ramdisk). -; This is a dirty hack, but the entire function is somewhat hacky. Use fs_read64*. - mov ecx, [ebp+PARTITION.Disk] - cmp dword [ecx+DISK.MediaInfo.Capacity+4], 0 - jnz @f - cmp dword [ecx+DISK.MediaInfo.Capacity], 3 shl (20-9) - jb .floppy -@@: -; We want to prefetch CACHE_LEGACY_READ_SIZE sectors. -; 6. Release the lock acquired at step 4a. - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.CacheLock - call mutex_unlock -; 7. Allocate buffer for CACHE_LEGACY_READ_SIZE sectors. - mov eax, CACHE_LEGACY_READ_SIZE - mov ecx, [ebx+DISKCACHE.sector_size_log] - shl eax, cl - stdcall kernel_alloc, eax -; If failed, return the corresponding error code. - test eax, eax - jz .nomemory -; 8. Create second portion of local variables. - push eax eax - push CACHE_LEGACY_READ_SIZE -virtual at esp -.local_vars2: -.num_sectors dd ? ; number of sectors left -.current_buffer dd ? ; pointer to data that are currently copying -.allocated_buffer dd ? ; saved at safe place -.local_vars2_size = $ - .local_vars2 -end virtual -; 9. Call the driver to read CACHE_LEGACY_READ_SIZE sectors. - push esp ; numsectors - push [.sector_hi+.local_vars2_size+4] ; startsector - push [.sector_lo+.local_vars2_size+8] ; startsector - push eax ; buffer - mov esi, [ebp+PARTITION.Disk] - mov al, DISKFUNC.read - call disk_call_driver -; Note: we're ok if at least one sector is read, -; read error somewhere after that just limits data to be put in cache. - cmp [.num_sectors], 0 - jz .read_error -; 10. Copy data for the caller. - mov esi, [.allocated_buffer] - mov edi, [.buffer+.local_vars2_size] - mov ecx, [ebx+DISKCACHE.sector_size_log] - mov eax, 1 - shl eax, cl - mov ecx, eax - shr ecx, 2 - rep movsd -; 11. Store all sectors that were successfully read to the cache. -; 11a. Acquire the lock. - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.CacheLock - call mutex_lock -.store_to_cache: -; 11b. For each sector, call the lookup function with adding to the cache, if not yet. - mov eax, [.sector_lo+.local_vars2_size] - mov edx, [.sector_hi+.local_vars2_size] - call cache_lookup_write - test eax, eax - jnz .cache_error -; 11c. Ignore sectors marked as modified: for them the cache is more recent that disk data. - mov eax, 1 - shl eax, cl - cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED - jnz .not_modified - add [.current_buffer], eax - jmp .sector_done -.not_modified: -; 11d. For each sector, copy data, mark the item as not-modified copy of the disk, -; advance .current_buffer and .sector_hi:.sector_lo to the next sector. - mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY - mov esi, [.current_buffer] - mov ecx, eax - shr ecx, 2 - rep movsd - mov [.current_buffer], esi -.sector_done: - add [.sector_lo+.local_vars2_size], 1 - adc [.sector_hi+.local_vars2_size], 0 -; 11e. Continue the loop at 11b-11d until all sectors are processed. - dec [.num_sectors] - jnz .store_to_cache -.cache_error: -; 11f. Release the lock. - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.CacheLock - call mutex_unlock -.copy_done: -; 12. Remove portion of local variables created at step 8, -; free the buffer allocated at step 7 and return. - pop ecx ecx - stdcall kernel_free - jmp .return -.read_error: -; If no sectors were read, free the buffer allocated at step 7 -; and pass the error to the caller. - push eax - stdcall kernel_free, [.allocated_buffer+4] - pop eax - add esp, .local_vars2_size - jmp .return_eax -.nomemory: - mov eax, DISK_STATUS_NO_MEMORY - jmp .return_eax -.floppy: -; We don't want to prefetch anything, just read one sector. -; We are still holding the lock acquired at step 4a. -; 13. Call the lookup function adding sector to the cache. - call cache_lookup_write - test eax, eax - jnz .floppy_cache_error - push esi - -; 14. Call the driver to read one sector. - push 1 - push esp - push edx - push [.sector_lo+16] - push edi - mov esi, [ebp+PARTITION.Disk] - mov al, DISKFUNC.read - call disk_call_driver - pop ecx - dec ecx - jnz .floppy_read_error -; 15. Get the slot and pointer to the cache item, -; change the status to not-modified copy of the disk -; and go to 4c. - pop esi - mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY - mov ecx, [ebx+DISKCACHE.sector_size_log] - jmp .found_in_cache - -; On error at steps 13-14, release the lock -; and pass the error to the caller. -.floppy_read_error: - pop ecx -.floppy_cache_error: - mov ecx, [ebp+PARTITION.Disk] - add ecx, DISK.CacheLock - push eax - call mutex_unlock - pop eax - jmp .return_eax - -; This function is intended to replace the old 'hd_write' function when -; [hdd_appl_data] = 0, so its input/output parameters are the same, except -; that it can't use the global variables 'hd_error' and 'hdd_appl_data'. -; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure -; eax is relative to partition start -; out: eax = error code; 0 = ok -fs_write32_sys: -; Just call the advanced function. - push ecx edx - xor edx, edx - mov ecx, 1 - call fs_write64_sys - pop edx ecx - ret - -; This function is intended to replace the old 'hd_write' function when -; [hdd_appl_data] = 1, so its input/output parameters are the same, except -; that it can't use the global variables 'hd_error' and 'hdd_appl_data'. -; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure -; eax is relative to partition start -; out: eax = error code; 0 = ok -fs_write32_app: -; Just call the advanced function. - push ecx edx - xor edx, edx - mov ecx, 1 - call fs_write64_app - pop edx ecx - ret - -; Lookup for the given sector in the given cache. -; If the sector is not present, return error. -; The caller must acquire the cache lock. -; in: edx:eax = sector -; in: ebx -> DISKCACHE structure -; out: CF set if sector is not in cache -; out: ecx = sector_size_log -; out: esi -> sector:status -; out: edi -> sector data -proc cache_lookup_read - mov esi, [ebx+DISKCACHE.pointer] - add esi, sizeof.CACHE_ITEM - - mov edi, 1 - -.hdreadcache: - - cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY - je .nohdcache - - cmp [esi+CACHE_ITEM.SectorLo], eax - jne .nohdcache - cmp [esi+CACHE_ITEM.SectorHi], edx - jne .nohdcache - mov ecx, [ebx+DISKCACHE.sector_size_log] - shl edi, cl - add edi, [ebx+DISKCACHE.data] - clc - ret - -.nohdcache: - - add esi, sizeof.CACHE_ITEM - inc edi - cmp edi, [ebx+DISKCACHE.sad_size] - jbe .hdreadcache - stc - ret -endp - -; Lookup for the given sector in the given cache. -; If the sector is not present, allocate space for it, -; possibly flushing data. -; in: edx:eax = sector -; in: ebx -> DISKCACHE structure -; in: ebp -> PARTITION structure -; out: eax = error code -; out: esi -> sector:status -; out: edi -> sector data -proc cache_lookup_write - call cache_lookup_read - jnc .return0 - push edx eax -;----------------------------------------------------------- -; find empty or read slot, flush cache if next 12.5% is used by write -; output : ecx = cache slot -;----------------------------------------------------------- -; Note: the code is essentially inherited, so probably -; no analysis of efficiency were done. -; However, it works. -.search_again: - mov eax, [ebx+DISKCACHE.sad_size] - mov ecx, [ebx+DISKCACHE.search_start] - shr eax, 3 - lea esi, [ecx*sizeof.CACHE_ITEM/4] - shl esi, 2 - add esi, [ebx+DISKCACHE.pointer] -.search_for_empty: - inc ecx - add esi, sizeof.CACHE_ITEM - cmp ecx, [ebx+DISKCACHE.sad_size] - jbe .inside_cache - mov ecx, 1 - mov esi, [ebx+DISKCACHE.pointer] - add esi, sizeof.CACHE_ITEM -.inside_cache: - cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED - jb .found_slot ; it's empty or read - dec eax - jnz .search_for_empty - stdcall write_cache64, [ebp+PARTITION.Disk] ; no empty slots found, write all - test eax, eax - jne .found_slot_access_denied - jmp .search_again ; and start again -.found_slot: - mov [ebx+DISKCACHE.search_start], ecx - popd [esi+CACHE_ITEM.SectorLo] - popd [esi+CACHE_ITEM.SectorHi] - mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY - mov edi, ecx - mov ecx, [ebx+DISKCACHE.sector_size_log] - shl edi, cl - add edi, [ebx+DISKCACHE.data] -.return0: - xor eax, eax ; success - ret -.found_slot_access_denied: - add esp, 8 - ret -endp - -; Flush the given cache. -; The caller must acquire the cache lock. -; in: ebx -> DISKCACHE -; in: first argument in stdcall convention -> PARTITION -proc write_cache64 -; 1. Setup stack frame. - push esi edi ; save used registers to be stdcall - sub esp, .local_vars_size ; reserve space for local vars -virtual at esp -.local_vars: -.cache_end dd ? ; item past the end of the cache -.size_left dd ? ; items left to scan -.current_ptr dd ? ; pointer to the current item -; -; Write operations are coalesced in chains, -; one chain describes a sequential interval of sectors, -; they can be sequential or scattered in the cache. -.sequential dd ? -; boolean variable, 1 if the current chain is sequential in the cache, -; 0 if additional buffer is needed to perform the operation -.chain_start_pos dd ? ; data of chain start item -.chain_start_ptr dd ? ; pointer to chain start item -.chain_size dd ? ; chain size (thanks, C.O.) -.iteration_size dd ? -; If the chain size is too large, split the operation to several iterations. -; This is size in sectors for one iterations. -.iteration_buffer dd ? ; temporary buffer for non-sequential chains -.local_vars_size = $ - .local_vars - rd 2 ; saved registers - dd ? ; return address -.disk dd ? ; first argument -end virtual -; 1. If there is no cache for this disk, nothing to do, just return zero. - cmp [ebx+DISKCACHE.pointer], 0 - jz .return0 -; 2. Prepare for the loop: initialize current pointer and .size_left, -; calculate .cache_end. - mov ecx, [ebx+DISKCACHE.sad_size] - mov [.size_left], ecx - lea ecx, [ecx*sizeof.CACHE_ITEM/4] - shl ecx, 2 - mov esi, [ebx+DISKCACHE.pointer] - add esi, sizeof.CACHE_ITEM - add ecx, esi - mov [.cache_end], ecx -; 3. Main loop: go over all items, go to 5 for every modified item. -.look: - cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED - jz .begin_write -.look_next: - add esi, sizeof.CACHE_ITEM - dec [.size_left] - jnz .look -; 4. Return success. -.return0: - xor eax, eax -.return: - add esp, .local_vars_size - pop edi esi ; restore used registers to be stdcall - ret 4 ; return popping one argument -.begin_write: -; We have found a modified item. -; 5. Prepare for chain finding: save the current item, initialize chain variables. - mov [.current_ptr], esi -; Initialize chain as sequential zero-length starting at the current item. - mov [.chain_start_ptr], esi - mov eax, [ebx+DISKCACHE.sad_size] - sub eax, [.size_left] - inc eax - mov ecx, [ebx+DISKCACHE.sector_size_log] - shl eax, cl - add eax, [ebx+DISKCACHE.data] - mov [.chain_start_pos], eax - mov [.chain_size], 0 - mov [.sequential], 1 -; 6. Expand the chain backward. -; Note: the main loop in step 2 looks for items sequentially, -; so the previous item is not modified. If the previous sector -; is present in the cache, it automatically makes the chain scattered. -; 6a. Calculate sector number: one before the sector for the current item. - mov eax, [esi+CACHE_ITEM.SectorLo] - mov edx, [esi+CACHE_ITEM.SectorHi] - sub eax, 1 - sbb edx, 0 -.find_chain_start: -; 6b. For each sector where the previous item does not expand the chain, -; call the lookup function without adding to the cache. - call cache_lookup_read -; 6c. If the sector is not found in cache or is not modified, stop expanding -; and advance to step 7. - jc .found_chain_start - cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED - jnz .found_chain_start -; 6d. We have found a new block that expands the chain backwards. -; It makes the chain non-sequential. -; Normally, sectors come in sequential blocks, so try to look at previous items -; before returning to 6b; if there is a sequential block indeed, this saves some -; time instead of many full-fledged lookups. - mov [.sequential], 0 - mov [.chain_start_pos], edi -.look_backward: -; 6e. For each sector, update chain start pos/ptr, decrement sector number, -; look at the previous item. - mov [.chain_start_ptr], esi - inc [.chain_size] - sub eax, 1 - sbb edx, 0 - sub esi, sizeof.CACHE_ITEM -; If the previous item exists... - cmp esi, [ebx+DISKCACHE.pointer] - jbe .find_chain_start -; ...describes the correct sector... - cmp [esi+CACHE_ITEM.SectorLo], eax - jnz .find_chain_start - cmp [esi+CACHE_ITEM.SectorHi], edx - jnz .find_chain_start -; ...and is modified... - cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED - jnz .found_chain_start -; ...expand the chain one sector backwards and continue the loop at 6e. -; Otherwise, advance to step 7 if the previous item describes the correct sector -; but is not modified, and return to step 6b otherwise. - mov edi, 1 - shl edi, cl - sub [.chain_start_pos], edi - jmp .look_backward -.found_chain_start: -; 7. Expand the chain forward. -; 7a. Prepare for the loop at 7b: -; set esi = pointer to current item, edx:eax = current sector. - mov esi, [.current_ptr] - mov eax, [esi+CACHE_ITEM.SectorLo] - mov edx, [esi+CACHE_ITEM.SectorHi] -.look_forward: -; 7b. First, look at the next item. If it describes the next sector: -; if it is modified, expand the chain with that sector and continue this step, -; if it is not modified, the chain is completed, so advance to step 8. - inc [.chain_size] - add eax, 1 - adc edx, 0 - add esi, sizeof.CACHE_ITEM - cmp esi, [.cache_end] - jae .find_chain_end - cmp [esi+CACHE_ITEM.SectorLo], eax - jnz .find_chain_end - cmp [esi+CACHE_ITEM.SectorHi], edx - jnz .find_chain_end - cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED - jnz .found_chain_end - jmp .look_forward -.find_chain_end: -; 7c. Otherwise, call the lookup function. - call cache_lookup_read -; 7d. If the next sector is present in the cache and is modified, -; mark the chain as non-sequential and continue to step 7b. - jc .found_chain_end - cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED - jnz .found_chain_end - mov [.sequential], 0 - jmp .look_forward -.found_chain_end: -; 8. Decide whether the chain is sequential or scattered. -; Advance to step 9 for sequential chains, go to step 10 for scattered chains. - cmp [.sequential], 0 - jz .write_non_sequential -.write_sequential: -; 9. Write a sequential chain to disk. -; 9a. Pass the entire chain to the driver. - mov eax, [.chain_start_ptr] - lea ecx, [.chain_size] - push ecx ; numsectors - pushd [eax+CACHE_ITEM.SectorHi] ; startsector - pushd [eax+CACHE_ITEM.SectorLo] ; startsector - push [.chain_start_pos+12] ; buffer - mov esi, [ebp+PARTITION.Disk] - mov al, DISKFUNC.write - call disk_call_driver -; 9b. If failed, pass the error code to the driver. - test eax, eax - jnz .return -; 9c. If succeeded, mark all sectors in the chain as not-modified, -; advance current item and number of items left to skip the chain. - mov esi, [.current_ptr] - mov eax, [.chain_size] - sub [.size_left], eax -@@: - mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY - add esi, sizeof.CACHE_ITEM - dec eax - jnz @b -; 9d. Continue the main loop at step 2 if there are more sectors. -; Return success otherwise. - cmp [.size_left], 0 - jnz .look - jmp .return0 -.write_non_sequential: -; Write a non-sequential chain to the disk. -; 10. Allocate a temporary buffer. -; Use [.chain_size] sectors, but -; not greater than CACHE_MAX_ALLOC_SIZE bytes -; and not greater than half of free memory. - mov eax, [pg_data.pages_free] - shr eax, 1 - jz .nomemory - cmp eax, CACHE_MAX_ALLOC_SIZE shr 12 - jbe @f - mov eax, CACHE_MAX_ALLOC_SIZE shr 12 -@@: - shl eax, 12 - shr eax, cl - jz .nomemory - cmp eax, [.chain_size] - jbe @f - mov eax, [.chain_size] -@@: - mov [.iteration_size], eax - shl eax, cl - stdcall kernel_alloc, eax - test eax, eax - jz .nomemory - mov [.iteration_buffer], eax -.write_non_sequential_iteration: -; 11. Split the chain so that each iteration fits in the allocated buffer. -; Iteration size is the minimum of chain size and allocated size. - mov eax, [.chain_size] - cmp eax, [.iteration_size] - jae @f - mov [.iteration_size], eax -@@: -; 12. Prepare arguments for the driver. - mov esi, [.chain_start_ptr] - mov edi, [.iteration_buffer] - push [.iteration_size] - push esp ; numsectors - push [esi+CACHE_ITEM.SectorHi] ; startsector - push [esi+CACHE_ITEM.SectorLo] ; startsector - push edi ; buffer -; 13. Copy data from the cache to the temporary buffer, -; advancing chain_start pos/ptr and marking sectors as not-modified. -; 13a. Prepare for the loop: push number of sectors to process. - push [.iteration_size+20] ; temporary variable -.copy_loop: -; 13b. For each sector, copy the data. -; Note that edi is advanced automatically. - mov esi, [.chain_start_pos+24] - mov ecx, [ebx+DISKCACHE.sector_size_log] - mov eax, 1 - shl eax, cl - mov ecx, eax - shr ecx, 2 - rep movsd - mov ecx, eax ; keep for 13e -; 13c. Mark the item as not-modified. - mov esi, [.chain_start_ptr+24] - mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY -; 13d. Check whether the next sector continues the chain. -; If so, advance to 13e. Otherwise, go to 13f. - mov eax, [esi+CACHE_ITEM.SectorLo] - mov edx, [esi+CACHE_ITEM.SectorHi] - add esi, sizeof.CACHE_ITEM - add eax, 1 - adc edx, 0 - cmp esi, [.cache_end+24] - jae .no_forward - cmp [esi+CACHE_ITEM.SectorLo], eax - jnz .no_forward - cmp [esi+CACHE_ITEM.SectorHi], edx - jnz .no_forward -; 13e. Increment position/pointer to the chain and -; continue the loop. - add [.chain_start_pos+24], ecx - mov [.chain_start_ptr+24], esi - dec dword [esp] - jnz .copy_loop - jmp .copy_done -.no_forward: -; 13f. Call the lookup function without adding to the cache. -; Update position/pointer with returned value. -; Note: for the last sector in the chain, edi/esi may contain -; garbage; we are not going to use them in this case. - push edi - call cache_lookup_read - mov [.chain_start_pos+28], edi - mov [.chain_start_ptr+28], esi - pop edi - dec dword [esp] - jnz .copy_loop -.copy_done: -; 13g. Restore the stack after 13a. - pop ecx -; 14. Call the driver. - mov esi, [ebp+PARTITION.Disk] - mov al, DISKFUNC.write - call disk_call_driver - pop ecx ; numsectors -; 15. If the driver has returned an error, free the buffer allocated at step 10 -; and pass the error to the caller. -; Otherwise, remove the processed part from the chain and continue iterations -; starting in step 11 if there are more data to process. - test eax, eax - jnz .nonsequential_error - sub [.chain_size], ecx - jnz .write_non_sequential_iteration -; 16. The chain is written. Free the temporary buffer -; and continue the loop at step 2. - stdcall kernel_free, [.iteration_buffer] - mov esi, [.current_ptr] - jmp .look_next -.nonsequential_error: - push eax - stdcall kernel_free, [.iteration_buffer+4] - pop eax - jmp .return -.nomemory: - mov eax, DISK_STATUS_NO_MEMORY - jmp .return -endp - -; This internal function is called from disk_add to initialize the caching for -; a new DISK. -; The algorithm is inherited from getcache.inc: take 1/32 part of the available -; physical memory, round down to 8 pages, limit by 128K from below and by 1M -; from above. Reserve 1/8 part of the cache for system data and 7/8 for app -; data. -; After the size is calculated, but before the cache is allocated, the device -; driver can adjust the size. In particular, setting size to zero disables -; caching: there is no sense in a cache for a ramdisk. In fact, such action -; is most useful example of a non-trivial adjustment. -; esi = pointer to DISK structure -disk_init_cache: -; 1. Verify sector size. The code requires it to be a power of 2 not less than 4. -; In the name of sanity check that sector size is not too small or too large. - bsf ecx, [esi+DISK.MediaInfo.SectorSize] - jz .invalid_sector_size - mov eax, 1 - shl eax, cl - cmp eax, [esi+DISK.MediaInfo.SectorSize] - jnz .invalid_sector_size - cmp ecx, 6 - jb .invalid_sector_size - cmp ecx, 14 - jbe .normal_sector_size -.invalid_sector_size: - DEBUGF 1,'K : sector size %x is invalid\n',[esi+DISK.MediaInfo.SectorSize] - xor eax, eax - ret -.normal_sector_size: - mov [esi+DISK.SysCache.sector_size_log], ecx - mov [esi+DISK.AppCache.sector_size_log], ecx -; 2. Calculate the suggested cache size. -; 2a. Get the size of free physical memory in pages. - mov eax, [pg_data.pages_free] -; 2b. Use the value to calculate the size. - shl eax, 12 - 5 ; 1/32 of it in bytes - and eax, -8*4096 ; round down to the multiple of 8 pages -; 2c. Force lower and upper limits. - cmp eax, 1024*1024 - jb @f - mov eax, 1024*1024 -@@: - cmp eax, 128*1024 - ja @f - mov eax, 128*1024 -@@: -; 2d. Give a chance to the driver to adjust the size. - push eax - mov al, DISKFUNC.adjust_cache_size - call disk_call_driver -; Cache size calculated. - mov [esi+DISK.cache_size], eax - test eax, eax - jz .nocache -; 3. Allocate memory for the cache. -; 3a. Call the allocator. - stdcall kernel_alloc, eax - test eax, eax - jnz @f -; 3b. If it failed, say a message and return with eax = 0. - dbgstr 'no memory for disk cache' - jmp .nothing -@@: -; 4. Fill two DISKCACHE structures. - mov [esi+DISK.SysCache.pointer], eax - lea ecx, [esi+DISK.CacheLock] - call mutex_init -; The following code is inherited from getcache.inc. - mov edx, [esi+DISK.SysCache.pointer] - and [esi+DISK.SysCache.search_start], 0 - and [esi+DISK.AppCache.search_start], 0 - mov eax, [esi+DISK.cache_size] - shr eax, 3 - mov [esi+DISK.SysCache.data_size], eax - add edx, eax - imul eax, 7 - mov [esi+DISK.AppCache.data_size], eax - mov [esi+DISK.AppCache.pointer], edx - - mov eax, [esi+DISK.SysCache.data_size] - call calculate_cache_slots - add eax, [esi+DISK.SysCache.pointer] - mov [esi+DISK.SysCache.data], eax - mov [esi+DISK.SysCache.sad_size], ecx - - push edi - mov edi, [esi+DISK.SysCache.pointer] - lea ecx, [(ecx+1)*3] - xor eax, eax - rep stosd - pop edi - - mov eax, [esi+DISK.AppCache.data_size] - call calculate_cache_slots - add eax, [esi+DISK.AppCache.pointer] - mov [esi+DISK.AppCache.data], eax - mov [esi+DISK.AppCache.sad_size], ecx - - push edi - mov edi, [esi+DISK.AppCache.pointer] - lea ecx, [(ecx+1)*3] - xor eax, eax - rep stosd - pop edi - -; 5. Return with nonzero al. - mov al, 1 -; 6. Return. -.nothing: - ret -; No caching is required for this driver. Zero cache pointers and return with -; nonzero al. -.nocache: - mov [esi+DISK.SysCache.pointer], eax - mov [esi+DISK.AppCache.pointer], eax - mov al, 1 - ret - -calculate_cache_slots: - push eax - mov ecx, [esi+DISK.MediaInfo.SectorSize] - add ecx, sizeof.CACHE_ITEM - xor edx, edx - div ecx - mov ecx, eax - imul eax, [esi+DISK.MediaInfo.SectorSize] - sub [esp], eax - pop eax - dec ecx - ret - - -; This internal function is called from disk_media_dereference to free the -; allocated cache, if there is one. -; esi = pointer to DISK structure -disk_free_cache: -; The algorithm is straightforward. - mov eax, [esi+DISK.SysCache.pointer] - test eax, eax - jz .nothing - stdcall kernel_free, eax -.nothing: - ret - -; This function flushes all modified data from both caches for the given DISK. -; esi = pointer to DISK -disk_sync: -; The algorithm is straightforward. - cmp [esi+DISK.SysCache.pointer], 0 - jz .nothing - lea ecx, [esi+DISK.CacheLock] - call mutex_lock - push ebx - push esi ; for second write_cache64 - push esi ; for first write_cache64 - lea ebx, [esi+DISK.SysCache] - call write_cache64 - add ebx, DISK.AppCache - DISK.SysCache - call write_cache64 - pop ebx - lea ecx, [esi+DISK.CacheLock] - call mutex_unlock -.nothing: - mov al, DISKFUNC.flush - call disk_call_driver - ret diff --git a/kernel/branches/Kolibri-F/blkdev/fdc.inc b/kernel/branches/Kolibri-F/blkdev/fdc.inc deleted file mode 100644 index 1f377ab5d..000000000 --- a/kernel/branches/Kolibri-F/blkdev/fdc.inc +++ /dev/null @@ -1,68 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; -;; Distributed under terms of the GNU General Public License ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -uglobal - dmasize db 0x0 - dmamode db 0x0 -endg - -fdc_init: ;start with clean tracks. - mov edi, OS_BASE+0xD201 - mov al, 0 - mov ecx, 160 - rep stosb - ret - -save_image: - cmp [ramdisk_actual_size], FLOPPY_CAPACITY - jnz .fail - pusha - mov ecx, floppy_mutex - call mutex_lock - mov [flp_number], bl - call floppy_read_bootsector - cmp [FDC_Status], 0 - jne .unnecessary_save_image - mov [FDD_Track], 0; Цилиндр - mov [FDD_Head], 0; Сторона - mov [FDD_Sector], 1; Сектор - mov esi, RAMDISK - call SeekTrack -.save_image_1: - call take_data_from_application_1 - call WriteSectWithRetr -; call WriteSector - cmp [FDC_Status], 0 - jne .unnecessary_save_image - inc [FDD_Sector] - cmp [FDD_Sector], 19 - jne .save_image_1 - mov [FDD_Sector], 1 - inc [FDD_Head] - cmp [FDD_Head], 2 - jne .save_image_1 - mov [FDD_Head], 0 - inc [FDD_Track] - call SeekTrack - cmp [FDD_Track], 80 - jne .save_image_1 -.unnecessary_save_image: - cmp [FDC_Status], 0 - pushf - mov ecx, floppy_mutex - call mutex_unlock - popf - popa - jnz .fail - xor eax, eax - ret -.fail: - movi eax, 1 - ret diff --git a/kernel/branches/Kolibri-F/blkdev/flp_drv.inc b/kernel/branches/Kolibri-F/blkdev/flp_drv.inc deleted file mode 100644 index 4b9d534b3..000000000 --- a/kernel/branches/Kolibri-F/blkdev/flp_drv.inc +++ /dev/null @@ -1,960 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -;********************************************************** -; Direct work with floppy disk drive -;********************************************************** -; Source code author - Kulakov Vladimir Gennadievich. -; Adaptation and improvement - Mario79. - -;give_back_application_data: ; give back to application -; mov edi,[TASK_BASE] -; mov edi,[edi+TASKDATA.mem_start] -; add edi,ecx -give_back_application_data_1: - mov esi, FDD_BUFF;FDD_DataBuffer ;0x40000 - mov ecx, 128 - cld - rep movsd - ret - -;take_data_from_application: ; take from application -; mov esi,[TASK_BASE] -; mov esi,[esi+TASKDATA.mem_start] -; add esi,ecx -take_data_from_application_1: - mov edi, FDD_BUFF;FDD_DataBuffer ;0x40000 - mov ecx, 128 - cld - rep movsd - ret - -; Controller operations result codes (FDC_Status) -FDC_Normal = 0 ; normal finish -FDC_TimeOut = 1 ; time out error -FDC_DiskNotFound = 2 ; no disk in drive -FDC_TrackNotFound = 3 ; track not found -FDC_SectorNotFound = 4 ; sector not found - -; Maximum values of the sector coordinates (specified -; values correspond to the parameters of the standard -; 3-inch 1.44 MB floppy disk) -MAX_Track = 79 -MAX_Head = 1 -MAX_Sector = 18 - -uglobal -; Timer tick counter -TickCounter dd ? -; Operation completion code with the floppy disk drive controller -FDC_Status DB ? -; Interrupt flag from floppy disk drive -FDD_IntFlag DB ? -; The moment of the beginning of the last operation with FDD -FDD_Time DD ? -; Drive number -FDD_Type db 0 -; Sector coordinates -FDD_Track DB ? -FDD_Head DB ? -FDD_Sector DB ? - -; Operation result block -FDC_ST0 DB ? -FDC_ST1 DB ? -FDC_ST2 DB ? -FDC_C DB ? -FDC_H DB ? -FDC_R DB ? -FDC_N DB ? -; Read operation repetition counter -ReadRepCounter DB ? -; Recalibration operation repetition counter -RecalRepCounter DB ? -endg -; Memory area for storing the readed sector -;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?) -fdd_motor_status db 0 -timer_fdd_motor dd 0 - -;************************************** -;* INITIALIZATION OF DMA MODE FOR FDD * -;************************************** -Init_FDC_DMA: - pushad - mov al, 0 - out 0x0c, al; reset the flip-flop to a known state. - mov al, 6 ; mask channel 2 so we can reprogram it. - out 0x0a, al - mov al, [dmamode]; 0x46 -> Read from floppy - 0x4A Write to floppy - out 0x0b, al - mov al, 0 - out 0x0c, al; reset the flip-flop to a known state. - mov eax, 0xD000 - out 0x04, al; set the channel 2 starting address to 0 - shr eax, 8 - out 0x04, al - shr eax, 8 - out 0x81, al - mov al, 0 - out 0x0c, al; reset flip-flop - mov al, 0xff;set count (actual size -1) - out 0x5, al - mov al, 0x1;[dmasize] ;(0x1ff = 511 / 0x23ff =9215) - out 0x5, al - mov al, 2 - out 0xa, al - popad - ret - -;*********************************** -;* WRITE BYTE TO FDC DATA PORT * -;* Parameters: * -;* AL - byte to write. * -;*********************************** -FDCDataOutput: -; DEBUGF 1,'K : FDCDataOutput(%x)',al -; pusha - push eax ecx edx - mov AH, AL ; remember byte to AH -; Reset controller state variable - mov [FDC_Status], FDC_Normal -; Check the readiness of the controller to receive data - mov DX, 3F4h ; (FDC state port) - mov ecx, 0x10000 ; set timeout counter -@@TestRS: - in AL, DX ; read the RS register - and AL, 0C0h ; get digits 6 and 7 - cmp AL, 80h ; check digits 6 and 7 - je @@OutByteToFDC - loop @@TestRS -; Time out error -; DEBUGF 1,' timeout\n' - mov [FDC_Status], FDC_TimeOut - jmp @@End_5 -; Write byte to data port -@@OutByteToFDC: - inc DX - mov AL, AH - out DX, AL -; DEBUGF 1,' ok\n' -@@End_5: -; popa - pop edx ecx eax - ret - -;****************************************** -;* READ BYTE FROM FDC DATA PORT * -;* Procedure doesnt have input params. * -;* Output : * -;* AL - byte read. * -;****************************************** -FDCDataInput: - push ECX - push DX -; Reset controller state variable - mov [FDC_Status], FDC_Normal -; Check the readiness of the controller to receive data - mov DX, 3F4h ;(FDC state port) - mov ecx, 0x10000 ; set timeout counter -@@TestRS_1: - in AL, DX ; read the RS register - and AL, 0C0h ; get digits 6 and 7 - cmp AL, 0C0h ; check digits 6 and 7 - je @@GetByteFromFDC - loop @@TestRS_1 -; Time out error -; DEBUGF 1,'K : FDCDataInput: timeout\n' - mov [FDC_Status], FDC_TimeOut - jmp @@End_6 -; Get byte from data port -@@GetByteFromFDC: - inc DX - in AL, DX -; DEBUGF 1,'K : FDCDataInput: %x\n',al -@@End_6: - pop DX - pop ECX - ret - -;********************************************* -;* FDC INTERRUPT HANDLER * -;********************************************* -FDCInterrupt: -; dbgstr 'FDCInterrupt' -; Set the interrupt flag - mov [FDD_IntFlag], 1 - mov al, 1 - ret - -;******************************************* -;* WAIT FOR INTERRUPT FROM FDC * -;******************************************* -WaitFDCInterrupt: - pusha -; Reset operation status byte - mov [FDC_Status], FDC_Normal -; Zero out the tick counter - mov eax, [timer_ticks] - mov [TickCounter], eax -; Wait for the floppy disk interrupt flag to be set -@@TestRS_2: - call change_task - cmp [FDD_IntFlag], 0 - jnz @@End_7 ; interrupt occured - mov eax, [timer_ticks] - sub eax, [TickCounter] - cmp eax, 200;50 ;25 ;5 ; wait 5 ticks - jb @@TestRS_2 -; jl @@TestRS_2 -; Time out error -; dbgstr 'WaitFDCInterrupt: timeout' - mov [FDC_Status], FDC_TimeOut -@@End_7: - popa - ret - -;*********************************** -;* Turn on the motor of drive "A:" * -;*********************************** -FDDMotorON: -; dbgstr 'FDDMotorON' - pusha -; cmp [fdd_motor_status],1 -; je fdd_motor_on - mov al, [flp_number] - cmp [fdd_motor_status], al - je fdd_motor_on -; Reset the FDD controller - mov DX, 3F2h ; motor control port - mov AL, 0 - out DX, AL -; Select and turn on the drive motor - cmp [flp_number], 1 - jne FDDMotorON_B -; call FDDMotorOFF_B - mov AL, 1Ch ; Floppy A - jmp FDDMotorON_1 -FDDMotorON_B: -; call FDDMotorOFF_A - mov AL, 2Dh ; Floppy B -FDDMotorON_1: - out DX, AL -; Zero out the tick counter - mov eax, [timer_ticks] - mov [TickCounter], eax -; wait 0.5 s -@@dT: - call change_task - mov eax, [timer_ticks] - sub eax, [TickCounter] - cmp eax, 50 ;10 - jb @@dT -; Read results of RESET command - push 4 -; DEBUGF 1,'K : floppy reset results:' -@@: - mov al, 8 - call FDCDataOutput - call FDCDataInput -; DEBUGF 1,' %x',al - call FDCDataInput -; DEBUGF 1,' %x',al - dec dword [esp] - jnz @b -; DEBUGF 1,'\n' - pop eax - cmp [flp_number], 1 - jne fdd_motor_on_B - mov [fdd_motor_status], 1 - jmp fdd_motor_on -fdd_motor_on_B: - mov [fdd_motor_status], 2 -fdd_motor_on: - call save_timer_fdd_motor - popa - ret - -;***************************************** -;* SAVING TIME STAMP * -;***************************************** -save_timer_fdd_motor: - mov eax, [timer_ticks] - mov [timer_fdd_motor], eax - ret - -;***************************************** -;* CHECK THE MOTOR SHUTDOWN DELAY * -;***************************************** -proc check_fdd_motor_status_has_work? - cmp [fdd_motor_status], 0 - jz .no - mov eax, [timer_ticks] - sub eax, [timer_fdd_motor] - cmp eax, 500 - jb .no -.yes: - xor eax, eax - inc eax - ret -.no: - xor eax, eax - ret -endp - -align 4 -check_fdd_motor_status: - cmp [fdd_motor_status], 0 - je end_check_fdd_motor_status_1 - mov eax, [timer_ticks] - sub eax, [timer_fdd_motor] - cmp eax, 500 - jb end_check_fdd_motor_status - call FDDMotorOFF - mov [fdd_motor_status], 0 -end_check_fdd_motor_status_1: -end_check_fdd_motor_status: - ret - -;********************************** -;* TURN OFF MOTOR OF DRIVE * -;********************************** -FDDMotorOFF: -; dbgstr 'FDDMotorOFF' - push AX - push DX - cmp [flp_number], 1 - jne FDDMotorOFF_1 - call FDDMotorOFF_A - jmp FDDMotorOFF_2 -FDDMotorOFF_1: - call FDDMotorOFF_B -FDDMotorOFF_2: - pop DX - pop AX - ; clearing caching flags due to information obsolescence - or [floppy_media_flags+0], FLOPPY_MEDIA_NEED_RESCAN - or [floppy_media_flags+1], FLOPPY_MEDIA_NEED_RESCAN - ret - -FDDMotorOFF_A: - mov DX, 3F2h ; motor control port - mov AL, 0Ch ; Floppy A - out DX, AL - ret - -FDDMotorOFF_B: - mov DX, 3F2h ; motor control port - mov AL, 5h ; Floppy B - out DX, AL - ret - -;******************************* -;* RECALIBRATE DRIVE "A:" * -;******************************* -RecalibrateFDD: -; dbgstr 'RecalibrateFDD' - pusha - call save_timer_fdd_motor -; Clear the interrupt flag - mov [FDD_IntFlag], 0 -; Send the "Recalibration" command - mov AL, 07h - call FDCDataOutput - mov AL, [flp_number] - dec AL - call FDCDataOutput -; Wait for the operation to complete - call WaitFDCInterrupt - cmp [FDC_Status], 0 - jne .fail -; Read results of RECALIBRATE command -; DEBUGF 1,'K : floppy recalibrate results:' - mov al, 8 - call FDCDataOutput - call FDCDataInput - push eax -; DEBUGF 1,' %x',al - call FDCDataInput -; DEBUGF 1,' %x',al -; DEBUGF 1,'\n' - pop eax - test al, 0xC0 - jz @f - mov [FDC_Status], FDC_DiskNotFound -@@: -.fail: - call save_timer_fdd_motor - popa - ret - -;***************************************************** -;* TRACK SEARCH * -;* Parameters are passed through global variables: * -;* FDD_Track - track number (0-79); * -;* FDD_Head - head number (0-1). * -;* Result of operation is written to FDC_Status. * -;***************************************************** -SeekTrack: -; dbgstr 'SeekTrack' - pusha - call save_timer_fdd_motor -; Clear the interrupt flag - mov [FDD_IntFlag], 0 -; Send "Search" command - mov AL, 0Fh - call FDCDataOutput - ; Send head / drive number byte - mov AL, [FDD_Head] - shl AL, 2 - call FDCDataOutput - ; Send track number byte - mov AL, [FDD_Track] - call FDCDataOutput -; Wait for the operation to complete - call WaitFDCInterrupt - cmp [FDC_Status], FDC_Normal - jne @@Exit -; Save search result - mov AL, 08h - call FDCDataOutput - call FDCDataInput - mov [FDC_ST0], AL - call FDCDataInput - mov [FDC_C], AL -; Check search result - ; Is search finished? - test [FDC_ST0], 100000b - je @@Err - ; Is the specified track found? - mov AL, [FDC_C] - cmp AL, [FDD_Track] - jne @@Err - ; Does the head number match the specified one? -; The H bit (Head Address) in ST0 will always return a "0" (c) 82077AA datasheet, -; description of SEEK command. So we can not verify the proper head. -; mov AL, [FDC_ST0] -; and AL, 100b -; shr AL, 2 -; cmp AL, [FDD_Head] -; jne @@Err - ; Operation completed successfully -; dbgstr 'SeekTrack: FDC_Normal' - mov [FDC_Status], FDC_Normal - jmp @@Exit -@@Err: ; Track not found -; dbgstr 'SeekTrack: FDC_TrackNotFound' - mov [FDC_Status], FDC_TrackNotFound -@@Exit: - call save_timer_fdd_motor - popa - ret - -;******************************************************* -;* READING A DATA SECTOR * -;* Parameters are passed through global variables: * -;* FDD_Track - track number (0-79); * -;* FDD_Head - head number (0-1); * -;* FDD_Sector - sector number (1-18). * -;* Result of operation is written to FDC_Status. * -;* If the read operation is successful, the contents * -;* of the sector will be written to FDD_DataBuffer. * -;******************************************************* -ReadSector: -; dbgstr 'ReadSector' - pushad - call save_timer_fdd_motor -; Clear the interrupt flag - mov [FDD_IntFlag], 0 -; Set transmit speed to 500 Kb / s - mov AX, 0 - mov DX, 03F7h - out DX, AL -; Initialize the DMA channel - mov [dmamode], 0x46 - call Init_FDC_DMA -; Send "Data read" command - mov AL, 0E6h ; reading in multi-track mode - call FDCDataOutput - mov AL, [FDD_Head] - shl AL, 2 - or AL, [flp_number] - dec AL - call FDCDataOutput - mov AL, [FDD_Track] - call FDCDataOutput - mov AL, [FDD_Head] - call FDCDataOutput - mov AL, [FDD_Sector] - call FDCDataOutput - mov AL, 2 ; sector size code (512 byte) - call FDCDataOutput - mov AL, 18 ;+1; 3Fh ;number of sectors per track - call FDCDataOutput - mov AL, 1Bh ; GPL value - call FDCDataOutput - mov AL, 0FFh; DTL value - call FDCDataOutput -; Waiting for an interrupt at the end of the operation - call WaitFDCInterrupt - cmp [FDC_Status], FDC_Normal - jne @@Exit_1 -; Read the operation completion status - call GetStatusInfo - test [FDC_ST0], 11011000b - jnz @@Err_1 -; dbgstr 'ReadSector: FDC_Normal' - mov [FDC_Status], FDC_Normal - jmp @@Exit_1 -@@Err_1: -; dbgstr 'ReadSector: FDC_SectorNotFound' - mov [FDC_Status], FDC_SectorNotFound -@@Exit_1: - call save_timer_fdd_motor - popad - ret - -;******************************************************* -;* READ SECTOR (WITH RETRY OF OPERATION ON FAILURE) * -;* Parameters are passed through global variables: * -;* FDD_Track - track number (0-79); * -;* FDD_Head - head number (0-1); * -;* FDD_Sector - sector number (1-18). * -;* Result of operation is written to FDC_Status. * -;* If the read operation is successful, the contents * -;* of the sector will be written to FDD_DataBuffer. * -;******************************************************* -ReadSectWithRetr: - pusha -; Reset the recalibration repetition counter - mov [RecalRepCounter], 0 -@@TryAgain: -; Reset the read operation retry counter - mov [ReadRepCounter], 0 -@@ReadSector_1: - call ReadSector - cmp [FDC_Status], 0 - je @@Exit_2 - cmp [FDC_Status], 1 - je @@Err_3 - ; Three times repeat reading - inc [ReadRepCounter] - cmp [ReadRepCounter], 3 - jb @@ReadSector_1 - ; Three times repeat recalibration - call RecalibrateFDD - call SeekTrack - inc [RecalRepCounter] - cmp [RecalRepCounter], 3 - jb @@TryAgain -@@Exit_2: - popa - ret -@@Err_3: - popa - ret - -;******************************************************* -;* WRITE DATA SECTOR * -;* Parameters are passed through global variables: * -;* FDD_Track - track number (0-79); * -;* FDD_Head - head number (0-1); * -;* FDD_Sector - sector number (1-18). * -;* Result of operation is written to FDC_Status. * -;* If the write operation is successful, the contents * -;* of FDD_DataBuffer will be written to the sector * -;******************************************************* -WriteSector: -; dbgstr 'WriteSector' - pushad - call save_timer_fdd_motor -; Clear the interrupt flag - mov [FDD_IntFlag], 0 -; Set transmit speed to 500 Kb / s - mov AX, 0 - mov DX, 03F7h - out DX, AL -; Initialize the DMA channel - mov [dmamode], 0x4A - call Init_FDC_DMA -; Send "Write data" command - mov AL, 0xC5 ;0x45 ; write in multi-track mode - call FDCDataOutput - mov AL, [FDD_Head] - shl AL, 2 - or AL, [flp_number] - dec AL - call FDCDataOutput - mov AL, [FDD_Track] - call FDCDataOutput - mov AL, [FDD_Head] - call FDCDataOutput - mov AL, [FDD_Sector] - call FDCDataOutput - mov AL, 2 ; sector size code (512 bytes) - call FDCDataOutput - mov AL, 18; 3Fh ; sectors per track - call FDCDataOutput - mov AL, 1Bh ; GPL value - call FDCDataOutput - mov AL, 0FFh; DTL value - call FDCDataOutput -; Waiting for an interrupt at the end of the operation - call WaitFDCInterrupt - cmp [FDC_Status], FDC_Normal - jne @@Exit_3 -; Reading the completion status of the operation - call GetStatusInfo - test [FDC_ST0], 11000000b ;11011000b - jnz @@Err_2 - mov [FDC_Status], FDC_Normal - jmp @@Exit_3 -@@Err_2: - mov [FDC_Status], FDC_SectorNotFound -@@Exit_3: - call save_timer_fdd_motor - popad - ret - -;******************************************************* -;* WRITE SECTOR (WITH REPEAT ON FAILURE) * -;* Parameters are passed through global variables: * -;* FDD_Track - track number (0-79); * -;* FDD_Head - head number (0-1); * -;* FDD_Sector - sector number (1-18). * -;* Result of operation is written to FDC_Status. * -;* If the write operation is successful, the contents * -;* of FDD_DataBuffer will be written to the sector * -;******************************************************* -WriteSectWithRetr: - pusha -; Reset the recalibration repetition counter - mov [RecalRepCounter], 0 -@@TryAgain_1: -; Reset the read operation retry counter - mov [ReadRepCounter], 0 -@@WriteSector_1: - call WriteSector - cmp [FDC_Status], 0 - je @@Exit_4 - cmp [FDC_Status], 1 - je @@Err_4 - ; Three times repeat writing - inc [ReadRepCounter] - cmp [ReadRepCounter], 3 - jb @@WriteSector_1 - ; Three times repeat recalibration - call RecalibrateFDD - call SeekTrack - inc [RecalRepCounter] - cmp [RecalRepCounter], 3 - jb @@TryAgain_1 -@@Exit_4: - popa - ret -@@Err_4: - popa - ret - -;********************************************* -;* GET INFORMATION ABOUT THE RESULT OF THE OPERATION -;********************************************* -GetStatusInfo: - push AX - call FDCDataInput - mov [FDC_ST0], AL - call FDCDataInput - mov [FDC_ST1], AL - call FDCDataInput - mov [FDC_ST2], AL - call FDCDataInput - mov [FDC_C], AL - call FDCDataInput - mov [FDC_H], AL - call FDCDataInput - mov [FDC_R], AL - call FDCDataInput - mov [FDC_N], AL - pop AX - ret - -; Interface for disk subsystem. -; Assume fixed capacity for 1.44M. -FLOPPY_CAPACITY = 2880 ; in sectors - -iglobal -align 4 -floppy_functions: - dd .size - dd 0 ; no close() function - dd 0 ; no closemedia() function - dd floppy_querymedia - dd floppy_read - dd floppy_write - dd 0 ; no flush() function - dd 0 ; no adjust_cache_size() function -.size = $ - floppy_functions -endg - -uglobal -floppy_media_flags rb 2 -n_sector dd 0 ; temporary save for sector value -flp_number db 0 ; 1- Floppy A, 2-Floppy B -old_track db 0 ; old value track -flp_label rb 15*2 ; Label and ID of inserted floppy disk -align 4 -; Hardware does not allow to work with two floppies in parallel, -; so there is one mutex guarding access to any floppy. -floppy_mutex MUTEX -endg -; Meaning of bits in floppy_media_flags -FLOPPY_MEDIA_PRESENT = 1 ; media was present when last asked -FLOPPY_MEDIA_NEED_RESCAN = 2 ; media was possibly changed, need to rescan -FLOPPY_MEDIA_LABEL_CHANGED = 4 ; temporary state - -iglobal -floppy1_name db 'fd',0 -floppy2_name db 'fd2',0 -endg - -; This function is called in boot process. -; It creates filesystems /fd and/or /fd2, if the system has one/two floppy drives. -proc floppy_init - mov ecx, floppy_mutex - call mutex_init -; First floppy is present if [DRIVE_DATA] and 0xF0 is nonzero. - test byte [DRIVE_DATA], 0xF0 - jz .no1 - stdcall disk_add, floppy_functions, floppy1_name, 1, DISK_NO_INSERT_NOTIFICATION -.no1: -; Second floppy is present if [DRIVE_DATA] and 0x0F is nonzero. - test byte [DRIVE_DATA], 0x0F - jz .no2 - stdcall disk_add, floppy_functions, floppy2_name, 2, DISK_NO_INSERT_NOTIFICATION -.no2: - ret -endp - -; Returns information about disk media. -; Floppy drives do not support insert notifications, -; DISK_NO_INSERT_NOTIFICATION is set, -; the disk subsystem calls this function before each filesystem operation. -; If the media has changed, return error for the first call as signal -; to finalize work with old media and the true geometry for the second call. -; Assume that media is (possibly) changed anytime when motor is off. -proc floppy_querymedia - virtual at esp+4 - .userdata dd ? - .info dd ? - end virtual -; 1. Acquire the global lock. - mov ecx, floppy_mutex - call mutex_lock - mov edx, [.userdata] ; 1 for /fd, 2 for /fd2 -; 2. If the media was reported and has been changed, forget it and report an error. - mov al, [floppy_media_flags+edx-1] - and al, FLOPPY_MEDIA_PRESENT + FLOPPY_MEDIA_NEED_RESCAN - cmp al, FLOPPY_MEDIA_PRESENT + FLOPPY_MEDIA_NEED_RESCAN - jnz .not_reported -.no_media: - mov [floppy_media_flags+edx-1], 0 -.return_no_media: - mov ecx, floppy_mutex - call mutex_unlock - mov eax, DISK_STATUS_NO_MEDIA - retn 8 -.not_reported: -; 3. If we are in the temporary state LABEL_CHANGED, this is the second call -; after intermediate DISK_STATUS_NO_MEDIA due to media change; -; clear the flag and return the current geometry without rereading the bootsector. - cmp [floppy_media_flags+edx-1], FLOPPY_MEDIA_LABEL_CHANGED - jz .report_geometry -; 4. Try to read the bootsector. - mov [flp_number], dl - mov [FDC_Status], 0 - call floppy_read_bootsector -; 5. If reading bootsector failed, assume that media is not present. - mov edx, [.userdata] - cmp [FDC_Status], 0 - jnz .no_media -; 6. Check whether the previous status is "present". If not, go to 10. - push esi edi - imul edi, edx, 15 - add edi, flp_label-15 - mov esi, FDD_BUFF+39 - mov ecx, 15 - test [floppy_media_flags+edx-1], FLOPPY_MEDIA_PRESENT - jz .set_label -; 7. Compare the old label with the current one. - rep cmpsb -; 8. If the label has not changed, go to 11. - jz .ok -; 9. If the label has changed, store it, enter temporary state LABEL_CHANGED -; and report DISK_STATUS_NO_MEDIA. -; dbgstr 'floppy label changed' - add esi, ecx - add edi, ecx - mov ecx, 15 - sub esi, ecx - sub edi, ecx - rep movsb - mov [floppy_media_flags+edx-1], FLOPPY_MEDIA_LABEL_CHANGED - pop edi esi - jmp .return_no_media -.set_label: -; 10. The previous state was "not present". Copy the label. - rep movsb -.ok: - pop edi esi -.report_geometry: -; 11. Fill DISKMEDIAINFO structure. - mov ecx, [.info] - and [ecx+DISKMEDIAINFO.Flags], 0 - mov [ecx+DISKMEDIAINFO.SectorSize], 512 - mov dword [ecx+DISKMEDIAINFO.Capacity], FLOPPY_CAPACITY - and dword [ecx+DISKMEDIAINFO.Capacity+4], 0 -; 12. Update state: media is present, data are actual. - mov [floppy_media_flags+edx-1], FLOPPY_MEDIA_PRESENT -; 13. Release the global lock and return successful status. - mov ecx, floppy_mutex - call mutex_unlock - xor eax, eax - retn 8 -endp - -proc floppy_read_bootsector - pushad - mov [FDD_Track], 0 ; Cylinder - mov [FDD_Head], 0 ; Head - mov [FDD_Sector], 1 ; Sector - call FDDMotorON - call RecalibrateFDD - cmp [FDC_Status], 0 - jne .nothing - call SeekTrack - cmp [FDC_Status], 0 - jne .nothing - call ReadSectWithRetr -.nothing: - popad - ret -endp - -read_chs_sector: - call calculate_chs - call ReadSectWithRetr - ret - -save_chs_sector: - call calculate_chs - call WriteSectWithRetr - ret - -calculate_chs: - mov bl, [FDD_Track] - mov [old_track], bl - mov ebx, 18 - xor edx, edx - div ebx - inc edx - mov [FDD_Sector], dl - mov edx, eax - shr eax, 1 - and edx, 1 - mov [FDD_Track], al - mov [FDD_Head], dl - mov dl, [old_track] - cmp dl, [FDD_Track] - je no_seek_track_1 - call SeekTrack -no_seek_track_1: - ret - -; Writes one or more sectors to the device. -proc floppy_write - mov dl, 1 - jmp floppy_read_write -endp - -; Reads one or more sectors from the device. -proc floppy_read - mov dl, 0 -endp - -; Common part of floppy_read and floppy_write. -proc floppy_read_write userdata:dword, buffer:dword, start_sector:qword, numsectors_ptr:dword -virtual at ebp-8 -.sectors_todo dd ? -.operation db ? -end virtual - push edx ; save operation code to [.operation] -; 1. Get number of sectors to read/write -; and zero number of sectors that were actually read/written. - mov eax, [numsectors_ptr] - push dword [eax] ; initialize [.sectors_todo] - and dword [eax], 0 - push ebx esi edi ; save used registers to be stdcall -; 2. Acquire the global lock. - mov ecx, floppy_mutex - call mutex_lock -; 3. Set floppy number for this operation. - mov edx, [userdata] - mov [flp_number], dl -; 4. Read/write sector-by-sector. -.operation_loop: -; 4a. Check that the sector is inside the media. - cmp dword [start_sector+4], 0 - jnz .end_of_media - mov eax, dword [start_sector] - cmp eax, FLOPPY_CAPACITY - jae .end_of_media -; 4b. For read operation, call read_chs_sector and then move data from FDD_BUFF to [buffer]. -; For write operation, move data from [buffer] to FDD_BUFF and then call save_chs_sector. - cmp [.operation], 0 - jz .read - mov esi, [buffer] - mov edi, FDD_BUFF - mov ecx, 512/4 - rep movsd - mov [buffer], esi - call save_chs_sector - jmp @f -.read: - call read_chs_sector - mov esi, FDD_BUFF - mov edi, [buffer] - mov ecx, 512/4 - rep movsd - mov [buffer], edi -@@: -; 4c. If there was an error, propagate it to the caller. - cmp [FDC_Status], 0 - jnz .fail -; 4d. Otherwise, increment number of sectors processed and continue the loop. - mov eax, [numsectors_ptr] - inc dword [eax] - inc dword [start_sector] - dec [.sectors_todo] - jnz .operation_loop -; 5. Release the global lock and return with the correct status. - push 0 -.return: - mov ecx, floppy_mutex - call mutex_unlock - pop eax - pop edi esi ebx ; restore used registers to be stdcall - ret ; this translates to leave/retn N and purges local variables -.fail: - push -1 - jmp .return -.end_of_media: - push DISK_STATUS_END_OF_MEDIA - jmp .return -endp diff --git a/kernel/branches/Kolibri-F/blkdev/hd_drv.inc b/kernel/branches/Kolibri-F/blkdev/hd_drv.inc deleted file mode 100644 index 73c4b56c5..000000000 --- a/kernel/branches/Kolibri-F/blkdev/hd_drv.inc +++ /dev/null @@ -1,568 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; HDD driver - -struct HD_DATA -hdpos dw ? -hdid dw ? -hdbase dw ? -hd48 dw ? -sectors dq ? -ends -;----------------------------------------------------------------- -iglobal -align 4 -ide_callbacks: - dd ide_callbacks.end - ide_callbacks - dd 0 ; no close function - dd 0 ; no closemedia function - dd ide_querymedia - dd ide_read - dd ide_write - dd 0 ; no flush function - dd 0 ; use default cache size -.end: - -hd0_data HD_DATA 1, 0 -hd1_data HD_DATA 2, 16 -hd2_data HD_DATA 3, 0 -hd3_data HD_DATA 4, 16 -hd4_data HD_DATA 5, 0 -hd5_data HD_DATA 6, 16 -hd6_data HD_DATA 7, 0 -hd7_data HD_DATA 8, 16 -hd8_data HD_DATA 9, 0 -hd9_data HD_DATA 10, 16 -hd10_data HD_DATA 11, 0 -hd11_data HD_DATA 12, 16 - -ide_mutex_table: - dd ide_channel1_mutex - dd ide_channel2_mutex - dd ide_channel3_mutex - dd ide_channel4_mutex - dd ide_channel5_mutex - dd ide_channel6_mutex -endg -;----------------------------------------------------------------- -uglobal -ide_mutex MUTEX -ide_channel1_mutex MUTEX -ide_channel2_mutex MUTEX -ide_channel3_mutex MUTEX -ide_channel4_mutex MUTEX -ide_channel5_mutex MUTEX -ide_channel6_mutex MUTEX -blockSize: -rb 4 -sector: -rb 6 -allow_dma_access db ? -IDE_common_irq_param db ? -eventPointer dd ? -eventID dd ? -endg -;----------------------------------------------------------------- -ide_read: - mov al, 25h ; READ DMA EXT - jmp ide_read_write - -ide_write: - mov al, 35h ; WRITE DMA EXT -proc ide_read_write stdcall uses esi edi ebx, \ - hd_data, buffer, startsector:qword, numsectors - ; hd_data = pointer to hd*_data - ; buffer = pointer to buffer with/for data - ; startsector = 64-bit start sector - ; numsectors = pointer to number of sectors on input, - ; must be filled with number of sectors really read/written -locals -sectors_todo dd ? -channel_lock dd ? -endl - mov bl, al -; get number of requested sectors and say that no sectors were read yet - mov ecx, [numsectors] - mov eax, [ecx] - mov dword [ecx], 0 - mov [sectors_todo], eax -; acquire the global lock - mov ecx, ide_mutex - call mutex_lock - mov ecx, [hd_data] - movzx ecx, [ecx+HD_DATA.hdpos] - dec ecx - shr ecx, 1 - shl ecx, 2 - mov ecx, [ecx + ide_mutex_table] - mov [channel_lock], ecx - call mutex_lock -; prepare worker procedures variables - mov esi, [buffer] - mov edi, esi - mov ecx, [hd_data] - movzx eax, [ecx+HD_DATA.hdbase] - mov [hdbase], eax - mov ax, [ecx+HD_DATA.hdid] - mov [hdid], eax - mov eax, dword [startsector] - mov [sector], eax - cmp [ecx+HD_DATA.hd48], 0 - jz .LBA28 - mov ax, word [startsector+4] - mov [sector+4], ax - movzx ecx, [ecx+HD_DATA.hdpos] - mov [hdpos], ecx - dec ecx - shr ecx, 2 - imul ecx, sizeof.IDE_DATA - add ecx, IDE_controller_1 - mov [IDE_controller_pointer], ecx - mov eax, [hdpos] - dec eax - and eax, 11b - shr eax, 1 - add eax, ecx - cmp [eax+IDE_DATA.dma_hdd_channel_1], 1 - jz .next - dec ebx ; READ/WRITE SECTOR(S) EXT -; LBA48 supports max 10000h sectors per time -; loop until all sectors will be processed -.next: - mov ecx, 8000h - cmp ecx, [sectors_todo] - jbe @f - mov ecx, [sectors_todo] -@@: - mov [blockSize], ecx - push ecx - call IDE_transfer - pop ecx - jc .out - mov eax, [numsectors] - add [eax], ecx - sub [sectors_todo], ecx - jz .out - add [sector], ecx - adc word [sector+4], 0 - jmp .next - -.LBA28: - add eax, [sectors_todo] - add eax, 0xF0000000 - jc .out - sub bl, 5 ; READ/WRITE SECTOR(S) -; LBA28 supports max 256 sectors per time -; loop until all sectors will be processed -.next28: - mov ecx, 256 - cmp ecx, [sectors_todo] - jbe @f - mov ecx, [sectors_todo] -@@: - mov [blockSize], ecx - push ecx - call IDE_transfer.LBA28 - pop ecx - jc .out - mov eax, [numsectors] - add [eax], ecx - sub [sectors_todo], ecx - jz .out - add [sector], ecx - jmp .next28 - -; loop is done, either due to error or because everything is done -; release the global lock and return the corresponding status -.out: - sbb eax, eax - push eax - mov ecx, [channel_lock] - call mutex_unlock - mov ecx, ide_mutex - call mutex_unlock - pop eax - ret -endp -;----------------------------------------------------------------- -proc ide_querymedia stdcall, hd_data, mediainfo - mov eax, [mediainfo] - mov edx, [hd_data] - mov [eax+DISKMEDIAINFO.Flags], 0 - mov [eax+DISKMEDIAINFO.SectorSize], 512 - mov ecx, dword[edx+HD_DATA.sectors] - mov dword[eax+DISKMEDIAINFO.Capacity], ecx - mov ecx, dword[edx+HD_DATA.sectors+4] - mov dword[eax+DISKMEDIAINFO.Capacity+4], ecx - xor eax, eax - ret -endp -;----------------------------------------------------------------- -; input: esi -> buffer, bl = command, [sector], [blockSize] -; output: esi -> next block in buffer -; for pio read esi equal edi -IDE_transfer: - mov edx, [hdbase] - add edx, 6 - mov al, byte [hdid] - add al, 224 - out dx, al ; select the desired drive - call save_hd_wait_timeout - inc edx -@@: - call check_hd_wait_timeout - jc .hd_error - in al, dx - test al, 128 ; ready for command? - jnz @b - pushfd ; fill the ports - cli - mov edx, [hdbase] - inc edx - inc edx - mov al, [blockSize+1] - out dx, al ; Sector count (15:8) - inc edx - mov eax, [sector+3] - out dx, al ; LBA (31:24) - inc edx - shr eax, 8 - out dx, al ; LBA (39:32) - inc edx - shr eax, 8 - out dx, al ; LBA (47:40) - sub edx, 3 - mov al, [blockSize] - out dx, al ; Sector count (7:0) - inc edx - mov eax, [sector] - out dx, al ; LBA (7:0) - inc edx - shr eax, 8 - out dx, al ; LBA (15:8) - inc edx - shr eax, 8 - out dx, al ; LBA (23:16) - inc edx - mov al, byte [hdid] - add al, 224 - out dx, al - test bl, 1 - jz .PIO -; DMA - mov dword [esp], 0x1000 - call kernel_alloc - mov edi, eax - push eax - shl dword [blockSize], 9 - mov eax, esi - add eax, [blockSize] - push eax -; check buffer pages physical addresses and fill the scatter-gather list -; buffer may be not aligned and may have size not divisible by page size -; [edi] = block physical address, [edi+4] = block size in bytes -; block addresses can not cross 10000h borders - mov ecx, esi - and ecx, 0xFFF - jz .aligned - mov eax, esi - call get_pg_addr - add eax, ecx - neg ecx - add ecx, 0x1000 - mov [edi], eax - cmp ecx, [blockSize] - jnc .end - mov [edi+4], ecx - add esi, 0x1000 - add edi, 8 - sub [blockSize], ecx -.aligned: - mov eax, esi - call get_pg_addr - mov ecx, eax - mov [edi], eax - and ecx, 0xFFFF - neg ecx - add ecx, 0x10000 - cmp [blockSize], ecx - jnc @f - mov ecx, [blockSize] - and ecx, 0xF000 - jz .end -@@: - push ecx -@@: - add esi, 0x1000 - add eax, 0x1000 - sub ecx, 0x1000 - jz @f - mov edx, eax - mov eax, esi - call get_pg_addr - cmp eax, edx - jz @b -@@: - pop edx - sub edx, ecx - mov [edi+4], edx - add edi, 8 - sub [blockSize], edx - jnz .aligned - sub edi, 8 - jmp @f - -.end: - mov ecx, [blockSize] - mov [edi+4], ecx -@@: - mov byte [edi+7], 80h ; list end - pop esi - pop edi -; select controller Primary or Secondary - mov ecx, [IDE_controller_pointer] - mov dx, [ecx+IDE_DATA.RegsBaseAddres] - mov eax, [hdpos] - dec eax - test eax, 10b - jz @f - add edx, 8 -@@: - add edx, 2 ; Bus Master IDE Status register - mov al, 6 - out dx, al ; clear Error bit and Interrupt bit - - add edx, 2 ; Bus Master IDE PRD Table Address - mov eax, edi - call get_pg_addr - out dx, eax ; send scatter-gather list physical address - - push edx - mov edx, [hdbase] - add edx, 7 ; ATACommand - mov al, bl - out dx, al ; Start hard drive - pop edx - - sub edx, 4 ; Bus Master IDE Command register - mov al, 1 ; set direction - cmp bl, 35h ; write - jz @f - add al, 8 ; read -@@: - out dx, al ; Start Bus Master - mov [IDE_common_irq_param], 14 - mov eax, [hdpos] - dec eax - test eax, 10b - jz @f - inc [IDE_common_irq_param] -@@: - push edi esi ebx - xor ecx, ecx - xor esi, esi - call create_event - mov [eventPointer], eax - mov [eventID], edx - sti - mov ebx, edx - mov ecx, 300 - call wait_event_timeout - test eax, eax - jnz @f - dbgstr 'IDE DMA IRQ timeout' - mov [IDE_common_irq_param], 0 - mov eax, [eventPointer] - mov ebx, [eventID] - call destroy_event - mov [eventPointer], 0 -@@: - pop ebx esi - call kernel_free - cmp [eventPointer], 0 - jz .hd_error - ret - -.LBA28: - mov edx, [hdbase] - add edx, 6 - mov al, byte [hdid] - add al, 224 - out dx, al ; select the desired drive - call save_hd_wait_timeout - inc edx -@@: - call check_hd_wait_timeout - jc .hd_error - in al, dx - test al, 128 ; ready for command? - jnz @b - pushfd ; fill the ports - cli - mov edx, [hdbase] - inc edx - inc edx - mov al, [blockSize] - out dx, al ; Sector count (7:0) - inc edx - mov eax, [sector] - out dx, al ; LBA (7:0) - inc edx - shr eax, 8 - out dx, al ; LBA (15:8) - inc edx - shr eax, 8 - out dx, al ; LBA (23:16) - inc edx - shr eax, 8 - add al, byte [hdid] - add al, 224 - out dx, al ; LBA (27:24) -.PIO: - inc edx ; ATACommand - mov al, bl - out dx, al ; Start hard drive - popfd -.sectorTransfer: - call save_hd_wait_timeout - in al, dx - in al, dx - in al, dx - in al, dx -@@: - call check_hd_wait_timeout - jc .hd_error - in al, dx - test al, 8 ; ready for transfer? - jz @b - cmp [hd_setup], 1 ; do not mark error for setup request - jz @f - test al, 1 ; previous command ended up with an error - jnz .pio_error -@@: - pushfd - cli - cld - mov ecx, 256 - mov edx, [hdbase] - cmp bl, 30h - jnc .write - rep insw - jmp @f - -.write: - rep outsw -@@: - popfd - add edx, 7 - dec dword [blockSize] - jnz .sectorTransfer - ret - -.pio_error: - dbgstr 'IDE PIO transfer error' -.hd_error: - cmp bl, 30h - jnc hd_write_error -;----------------------------------------------------------------- -hd_read_error: - dbgstr 'HD read error' - stc - ret -;----------------------------------------------------------------- -hd_write_error: - dbgstr 'HD write error' - stc - ret -;----------------------------------------------------------------- -save_hd_wait_timeout: - mov eax, [timer_ticks] - add eax, 300 ; 3 sec timeout - mov [hd_wait_timeout], eax - ret -;----------------------------------------------------------------- -check_hd_wait_timeout: - mov eax, [timer_ticks] - cmp [hd_wait_timeout], eax - jc @f - ret - -@@: - dbgstr 'IDE device timeout' - stc - ret -;----------------------------------------------------------------- -align 4 -IDE_irq_14_handler: -IDE_irq_15_handler: -IDE_common_irq_handler: -; Most of the time, we are here because we have requested -; a DMA transfer for the corresponding drive. -; However, -; a) we can be here because IDE IRQ is shared with some other device, -; that device has actually raised IRQ, -; it has nothing to do with IDE; -; b) we can be here because IDE controller just does not want -; to be silent and reacts to something even though -; we have, in theory, disabled IRQs. -; If the interrupt corresponds to our current request, -; remove the interrupt request and raise the event for the waiting code. -; In the case a), just return zero - not our interrupt. -; In the case b), remove the interrupt request and hope for the best. -; DEBUGF 1, 'K : IDE_irq_handler %x\n', [IDE_common_irq_param]:2 - mov ecx, [esp+4] - mov dx, [ecx+IDE_DATA.RegsBaseAddres] - add edx, 2 ; Bus Master IDE Status register - in al, dx - test al, 4 - jnz .interrupt_from_primary - add edx, 8 - in al, dx - test al, 4 - jnz .interrupt_from_secondary - xor eax, eax ; not our interrupt - ret - -.interrupt_from_primary: - out dx, al ; clear Interrupt bit - sub edx, 2 - xor eax, eax - out dx, al ; clear Bus Master IDE Command register - mov dx, [ecx+IDE_DATA.BAR0_val] - add edx, 7 - in al, dx ; read status register - cmp [IDE_common_irq_param], 14 - jz .raise -.exit_our: - mov al, 1 - ret - -.interrupt_from_secondary: - out dx, al ; clear Interrupt bit - sub edx, 2 - xor eax, eax - out dx, al ; clear Bus Master IDE Command register - mov dx, [ecx+IDE_DATA.BAR2_val] - add edx, 7 - in al, dx ; read status register - cmp [IDE_common_irq_param], 15 - jnz .exit_our -.raise: - cmp ecx, [IDE_controller_pointer] - jnz .exit_our - pushad - mov eax, [eventPointer] - mov ebx, [eventID] - xor edx, edx - xor esi, esi - call raise_event - popad - mov al, 1 ; remove the interrupt request - ret diff --git a/kernel/branches/Kolibri-F/blkdev/ide_cache.inc b/kernel/branches/Kolibri-F/blkdev/ide_cache.inc deleted file mode 100644 index b030fee6c..000000000 --- a/kernel/branches/Kolibri-F/blkdev/ide_cache.inc +++ /dev/null @@ -1,202 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;************************************************************************** -; -; [cache_ide[X]_pointer] -; or [cache_ide[X]_data_pointer] first entry in cache list -; -; +0 - lba sector -; +4 - state of cache sector -; 0 = empty -; 1 = used for read ( same as in hd ) -; 2 = used for write ( differs from hd ) -; -; [cache_ide[X]_system_data] -; or [cache_ide[x]_appl_data] - cache entries -; -;************************************************************************** - -$Revision$ - -align 4 -find_empty_slot_CD_cache: -;----------------------------------------------------------- -; find empty or read slot, flush cache if next 10% is used by write -; output : edi = cache slot -;----------------------------------------------------------- -.search_again: - call cd_calculate_cache_3 -.search_for_empty: - inc edi - call cd_calculate_cache_4 - jbe .inside_cache - mov edi, 1 -.inside_cache: - call cd_calculate_cache_5 - ret -;-------------------------------------------------------------------- -clear_CD_cache: - DEBUGF 1, 'K : clear_CD_cache\n' - pusha - - mov esi, [cdpos] - dec esi - imul esi, sizeof.IDE_CACHE - add esi, cache_ide0 - - xor eax, eax - - mov [esi+IDE_CACHE.search_start], eax - mov ecx, [esi+IDE_CACHE.system_sad_size] - mov edi, [esi+IDE_CACHE.pointer] - call .clear - - mov [esi+IDE_CACHE.appl_search_start], eax - mov ecx, [esi+IDE_CACHE.appl_sad_size] - mov edi, [esi+IDE_CACHE.data_pointer] - call .clear - - popa - ret -;-------------------------------------- -.clear: - shl ecx, 1 - cld - rep stosd - ret -;-------------------------------------------------------------------- -align 4 -cd_calculate_cache: -; 1 - IDE0 ... 12 - IDE11 - push eax - - mov eax, [cdpos] - dec eax - imul eax, sizeof.IDE_CACHE - add eax, cache_ide0 - - cmp [cd_appl_data], 0 - jne @f - - mov ecx, [eax+IDE_CACHE.system_sad_size] - mov esi, [eax+IDE_CACHE.pointer] - pop eax - ret -;-------------------------------------- -@@: - mov ecx, [eax+IDE_CACHE.appl_sad_size] - mov esi, [eax+IDE_CACHE.data_pointer] - pop eax - ret -;-------------------------------------------------------------------- -align 4 -cd_calculate_cache_1: -; 1 - IDE0 ... 12 - IDE11 - push eax - - mov eax, [cdpos] - dec eax - imul eax, sizeof.IDE_CACHE - add eax, cache_ide0 - - cmp [cd_appl_data], 0 - jne @f - - mov esi, [eax+IDE_CACHE.pointer] - pop eax - ret -;-------------------------------------- -@@: - mov esi, [eax+IDE_CACHE.data_pointer] - pop eax - ret -;-------------------------------------------------------------------- -align 4 -cd_calculate_cache_2: -; 1 - IDE0 ... 12 - IDE11 - mov eax, [cdpos] - dec eax - imul eax, sizeof.IDE_CACHE - add eax, cache_ide0 - - cmp [cd_appl_data], 0 - jne @f - - mov eax, [eax+IDE_CACHE.system_data] - ret -;-------------------------------------- -@@: - mov eax, [eax+IDE_CACHE.appl_data] - ret -;-------------------------------------------------------------------- -align 4 -cd_calculate_cache_3: -; 1 - IDE0 ... 12 - IDE11 - push eax - - mov eax, [cdpos] - dec eax - imul eax, sizeof.IDE_CACHE - add eax, cache_ide0 - - cmp [cd_appl_data], 0 - jne @f - - mov edi, [eax+IDE_CACHE.search_start] - pop eax - ret -;-------------------------------------- -@@: - mov edi, [eax+IDE_CACHE.appl_search_start] - pop eax - ret -;-------------------------------------------------------------------- -align 4 -cd_calculate_cache_4: -; 1 - IDE0 ... 12 - IDE11 - push eax - - mov eax, [cdpos] - dec eax - imul eax, sizeof.IDE_CACHE - add eax, cache_ide0 - - cmp [cd_appl_data], 0 - jne @f - - cmp edi, [eax+IDE_CACHE.system_sad_size] - pop eax - ret -;-------------------------------------- -@@: - cmp edi, [eax+IDE_CACHE.appl_sad_size] - pop eax - ret -;-------------------------------------------------------------------- -align 4 -cd_calculate_cache_5: -; 1 - IDE0 ... 12 - IDE11 - push eax - - mov eax, [cdpos] - dec eax - imul eax, sizeof.IDE_CACHE - add eax, cache_ide0 - - cmp [cd_appl_data], 0 - jne @f - - mov [eax+IDE_CACHE.search_start], edi - pop eax - ret -;-------------------------------------- -@@: - mov [eax+IDE_CACHE.appl_search_start], edi - pop eax - ret -;-------------------------------------------------------------------- diff --git a/kernel/branches/Kolibri-F/blkdev/rd.inc b/kernel/branches/Kolibri-F/blkdev/rd.inc deleted file mode 100644 index 8ae2bccc2..000000000 --- a/kernel/branches/Kolibri-F/blkdev/rd.inc +++ /dev/null @@ -1,192 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;; RAMDISK functions ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -iglobal -align 4 -ramdisk_functions: - dd .size - dd 0 ; no close() function - dd 0 ; no closemedia() function - dd ramdisk_querymedia - dd ramdisk_read - dd ramdisk_write - dd 0 ; no flush() function - dd ramdisk_adjust_cache_size -.size = $ - ramdisk_functions -endg - -iglobal -align 4 -ramdisk_actual_size dd RAMDISK_CAPACITY -endg - -; This function is called early in boot process. -; It creates filesystem /rd/1 based on raw image data loaded by somebody before -; to memory named as RAMDISK with max size RAMDISK_CAPACITY, may be less. -proc ramdisk_init -iglobal -ramdisk_name db 'rd',0 -endg - push ebx esi ; save used registers to be stdcall -; 1. Register the device and the (always inserted) media in the disk subsystem. - stdcall disk_add, ramdisk_functions, ramdisk_name, 0, 0 - test eax, eax - jz .fail - mov ebx, eax - stdcall disk_media_changed, eax, 1 -; 2. We don't know actual size of loaded image, -; so try to calculate it using partition structure, -; assuming that file systems fill the real size based on contents of the partition. -; 2a. Prepare for loop over partitions. - xor eax, eax - xor ecx, ecx - xor edx, edx -; 2b. Check that at least one partition was recognized. - cmp [ebx+DISK.NumPartitions], ecx - jz .fail -; 2c. Loop over partitions. -.partitions: -; For every partition, set edx to maximum between edx and end of partition. - mov esi, [ebx+DISK.Partitions] - mov esi, [esi+ecx*4] - mov eax, dword [esi+PARTITION.FirstSector] - add eax, dword [esi+PARTITION.Length] - cmp eax, edx - jb @f - mov edx, eax -@@: - inc ecx - cmp ecx, [ebx+DISK.NumPartitions] - jb .partitions -; 3. Reclaim unused memory, if any. - mov [ramdisk_actual_size], edx - add edx, 7 ; aligning up - shr edx, 3 ; 512-byte sectors -> 4096-byte pages - mov esi, RAMDISK_CAPACITY / 8 ; aligning down - sub esi, edx - jbe .no_reclaim - shl edx, 12 - add edx, RAMDISK - OS_BASE -@@: - mov eax, edx - call free_page - add edx, 0x1000 - dec esi - jnz @b -.no_reclaim: - mov eax, ebx - pop esi ebx ; restore used registers to be stdcall - ret -.fail: - dbgstr 'Failed to initialize ramdisk' - pop esi ebx ; restore used registers to be stdcall - ret -endp - -; Returns information about disk media. -proc ramdisk_querymedia - virtual at esp+4 - .userdata dd ? - .info dd ? - end virtual -; Media is always present, sector size is always 512 bytes. - mov edx, [.userdata] - mov ecx, [.info] - mov [ecx+DISKMEDIAINFO.Flags], 0 - mov [ecx+DISKMEDIAINFO.SectorSize], 512 - mov eax, [ramdisk_actual_size] - mov dword [ecx+DISKMEDIAINFO.Capacity], eax - mov dword [ecx+DISKMEDIAINFO.Capacity+4], 0 -; Return zero as an indicator of success. - xor eax, eax - retn 8 -endp - -; Common procedure for reading and writing. -; operation = 0 for reading, operation = 1 for writing. -; Arguments of ramdisk_read and ramdisk_write are the same. -macro ramdisk_read_write operation -{ - push esi edi ; save used registers to be stdcall - mov esi, [userdata] - mov edi, [numsectors_ptr] -; 1. Determine number of sectors to be transferred. -; This is either the requested number of sectors or number of sectors -; up to the disk boundary, depending of what is less. - xor ecx, ecx -; 1a. Test whether [start_sector] is less than RAMDISK_CAPACITY. -; If so, calculate number of sectors between [start_sector] and RAMDISK_CAPACITY. -; Otherwise, the actual number of sectors is zero. - cmp dword [start_sector+4], ecx - jnz .got_number - mov eax, [ramdisk_actual_size] - sub eax, dword [start_sector] - jbe .got_number -; 1b. Get the requested number of sectors. - mov ecx, [edi] -; 1c. If it is greater than number of sectors calculated in 1a, use the value -; from 1a. - cmp ecx, eax - jb .got_number - mov ecx, eax -.got_number: -; 2. Compare the actual number of sectors with requested. If they are -; equal, set eax (it will be the returned value) to zero. Otherwise, -; use DISK_STATUS_END_OF_MEDIA. - xor eax, eax - cmp ecx, [edi] - jz @f - mov al, DISK_STATUS_END_OF_MEDIA -@@: -; 3. Store the actual number of sectors. - mov [edi], ecx -; 4. Calculate source and destination addresses. -if operation = 0 ; reading? - mov esi, dword [start_sector] - shl esi, 9 - add esi, RAMDISK - mov edi, [buffer] -else ; writing? - mov edi, dword [start_sector] - shl edi, 9 - add edi, RAMDISK - mov esi, [buffer] -end if -; 5. Calculate number of dwords to be transferred. - shl ecx, 9-2 -; 6. Copy data. - rep movsd -; 7. Return. The value in eax was calculated in step 2. - pop edi esi ; restore used registers to be stdcall -} - -; Reads one or more sectors from the device. -proc ramdisk_read userdata:dword, buffer:dword, start_sector:qword, numsectors_ptr:dword - ramdisk_read_write 0 - ret -endp - -; Writes one or more sectors to the device. -proc ramdisk_write userdata:dword, buffer:dword, start_sector:qword, numsectors_ptr:dword - ramdisk_read_write 1 - ret -endp - -; The kernel calls this function when initializing cache subsystem for -; the media. This call allows the driver to adjust the cache size. -proc ramdisk_adjust_cache_size - virtual at esp+4 - .userdata dd ? - .suggested_size dd ? - end virtual -; Since ramdisk does not need cache, just return 0. - xor eax, eax - retn 8 -endp diff --git a/kernel/branches/Kolibri-F/blkdev/rdsave.inc b/kernel/branches/Kolibri-F/blkdev/rdsave.inc deleted file mode 100644 index b7a722b28..000000000 --- a/kernel/branches/Kolibri-F/blkdev/rdsave.inc +++ /dev/null @@ -1,33 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -iglobal -saverd_fileinfo: - dd 2 ; subfunction: write - dd 0 ; (reserved) - dd 0 ; (reserved) -.size: - dd 0 - dd RAMDISK - db 0 -.name: - dd ? -endg -sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only) - mov ebx, saverd_fileinfo - mov [ebx+21], ecx - mov eax, [ramdisk_actual_size] - shl eax, 9 - mov [ebx+12], eax - pushad - call syscall_file_system_lfn_protected ;in ebx - popad - mov [esp+32], eax - ret diff --git a/kernel/branches/Kolibri-F/boot/ETFONT.FNT b/kernel/branches/Kolibri-F/boot/ETFONT.FNT deleted file mode 100644 index 114f0609fd8a6364136a3dccfc4224eeb224155d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmZu!&5GMr6uzXOm2jpzwHcgE7g>q~98rV^LSLbqu0&GQEJT=g@Nkvk&jj&MM(l z`^)|QV!PifcCKhaWpZRQkCL(vqcq)aw^5WTKT0c1?l6WS5(#(Dw7nn$L_C`2&z|Kn zod+-8fB5kJLiyv-w~yxyXf7Jk9F#^dAo%3TNenu@xf1;5#hVwPU$)l^8Hl3GbemqP z{M*IV&92?uTrJ)*`(7{_PuuBu6x>ts6sn`j9Cl<5guC$HTwY$jen7;yth1!3>mmv3 zQUv%)DHDivh(67yU<|4M^aSb*B3)q{DwlP{S)0W@b#8Jo;brI(2KGkfq46q5es7N>CUO@h7y&Y9+xulAT zV3f?E3#9caYZ0$iCvcDkL15(#kJF-Q;qqAKw$d|t@4O_VE9UqlkqM{UM^W`Z|Y!&1SP+sDDS4kd_=0`8%wD zl2-hk;50u+go|_Cpl(+XGtY~i@Z0?P%lXUfd9L|VoMkt?`J1}VzZXoF*qqv<#mAHi zf6S|)+wa#fHJ`)iweW8;CU39)+_oquNcCUewwsR~=3EohcsV{&q5dgo1k< z635DS=wPSGvF}%@Y@aY>K2=ln{?8TNHjev^MP=q;>G!L<$}-9}7J=7L)>r_RzhhV` zAg=qHgvuJ5!1zh=bH+8&{DMCt@um#9g+qTaBmJ6REX|}}{~&N9YzGkXg2|AV1)%aG zj2V^>=RUPa@Un}0P3o;*vwu{CE*{~RehHX=wx!pzyjveUA1lD-AI0$|n=_c6N704M0HeLmbskxep}l1rp-uwGEM zJ|=yA>~c3)9}(UR35BcmC;2|E$%1qkGDq(8F}1}u&ro~oR}gAulWMhkMe@!~i>7HQ zBOe)xzf>R27K+Cm)MN3tqbp7^q&WZh+f+nk zH_#!*E0`3kV&ai=K*dV%*FOwDKmIZN{Qc|j!m?cJAy`CeZ6UY_N?bn@)azSF0Ayu8gf{~06xfxXGZ z`)l#3oZNcx>iEgQe6LUZi4OC7STCPH{u9)@n142Ob3peGNaY6Zy4iZQTCL@L?&!bO zszEK-Gztv^@k3-P=VQ6va7H{N8_fY zSlhFm#|hSC?z8a6IL=N z{d-|+LXXeBiJ?QHiHC+CzrqWx=gv1z-S`P;Z0hNxU3JH845LZnE5!ZKi`s)WZ-Z#l e_IRI|MWZlvL diff --git a/kernel/branches/Kolibri-F/boot/bootcode.inc b/kernel/branches/Kolibri-F/boot/bootcode.inc deleted file mode 100644 index e0dc69e98..000000000 --- a/kernel/branches/Kolibri-F/boot/bootcode.inc +++ /dev/null @@ -1,1400 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;; BOOTCODE.INC ;; -;; ;; -;; KolibriOS 16-bit loader, ;; -;; based on bootcode for MenuetOS ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -;========================================================================== -; -; 16 BIT FUNCTIONS -; -;========================================================================== - - -putchar: -; in: al=character - mov ah, 0Eh - mov bh, 0 - int 10h - ret - -print: -; in: si->string - mov al, 186 - call putchar - mov al, ' ' - call putchar - -printplain: -; in: si->string - pusha - lodsb -@@: - call putchar - lodsb - test al, al - jnz @b - popa - ret - -getkey: ; Use BIOS INT 16h to read a key from the keyboard -; get number in range [bl,bh] (bl,bh in ['0'..'9']) -; in: bx=range -; out: ax=digit (1..9, 10 for 0) - mov ah, 0 ; If 'int 16h' is called with 'ah' equal to zero, the BIOS will not return control to the caller - int 16h ; until a key is available in the system type ahead buffer. On return, 'al' contains the ASCII - cmp al, 27 ; code for the key read from the buffer and 'ah' contains the keyboard scan code. (27=>ESC) - jz @f ; If ESC is pressed, return (user doesn't want to change any value). - cmp al, bl ; Compare 'al' (ASCII code of key pressed) with 'bl' (lowest accepted char from the range). - jb getkey ; ASCII code is below lowest accepted value => continue waiting for another key. - cmp al, bh ; Compare 'al' (ASCII code of key pressed) with 'bh' (highest accepted char from the range). - ja getkey ; ASCII code is above highest accepted value => continue waiting for another key. - push ax ; If the pressed key is in the accepted range, save it on the stack and echo to screen. - call putchar - pop ax - and ax, 0Fh ; Convert ASCII code to number: '1'->1, '2'->2, etc. 0Fh=1111b. - jnz @f ; ASCII code for '0' is 48 (110000b). (110000b AND 1111b) = 0 - mov al, 10 ; So if key '0' was entered, return 10 in 'ax' -@@: - ret - -setcursor: -; in: dl=column, dh=row - mov ah, 2 - mov bh, 0 - int 10h - ret - -macro _setcursor row,column -{ - mov dx, row*256 + column - call setcursor -} - -macro _ask_question question,range,variable_to_set -{ - _setcursor 16,0 - mov si, question ; Print the question - call print - mov bx, range ; range accepted for answer - call getkey - cmp al, 27 ; If ESC was pressed, do not change the value - jz .esc_pressed - mov [variable_to_set], al -} - -boot_read_floppy: - push si - xor si, si - mov ah, 2 ; read -@@: - push ax - int 0x13 - pop ax - jnc @f - inc si - cmp si, 10 - jb @b -sayerr_badsect: - mov si, badsect -sayerr_plain: - call printplain - jmp $ -@@: - pop si - ret - -; convert abs. sector number (AX) to BIOS T:H:S -; sector number = (abs.sector%BPB_SecPerTrk)+1 -; pre.track number = (abs.sector/BPB_SecPerTrk) -; head number = pre.track number%BPB_NumHeads -; track number = pre.track number/BPB_NumHeads -; Return: cl - sector number -; ch - track number -; dl - drive number (0 = a:) -; dh - head number -conv_abs_to_THS: - push bx - mov bx, word [BPB_SecPerTrk] - xor dx, dx - div bx - inc dx - mov cl, dl ; cl = sector number - mov bx, word [BPB_NumHeads] - xor dx, dx - div bx - ; !!!!!!! ax = track number, dx = head number - mov ch, al ; ch=track number - xchg dh, dl ; dh=head number - mov dl, 0 ; dl=0 (drive 0 (a:)) - pop bx - retn -; needed variables -BPB_SecPerTrk dw 0 ; sectors per track -BPB_NumHeads dw 0 ; number of heads -BPB_FATSz16 dw 0 ; size of FAT -BPB_RootEntCnt dw 0 ; count of root dir. entries -BPB_BytsPerSec dw 0 ; bytes per sector -BPB_RsvdSecCnt dw 0 ; number of reserved sectors -BPB_TotSec16 dw 0 ; count of the sectors on the volume -BPB_SecPerClus db 0 ; number of sectors per cluster -BPB_NumFATs db 0 ; number of FAT tables -abs_sector_adj dw 0 ; adjustment to make abs. sector number -end_of_FAT dw 0 ; end of FAT table -FirstDataSector dw 0 ; begin of data - -;========================================================================= -; -; 16 BIT CODE -; -;========================================================================= - -include 'bootvesa.inc' ;Include source for boot vesa -if defined extended_primary_loader -include 'parsers.inc' -end if - -start_of_code: - -if defined extended_primary_loader -; save data from primary loader - mov word [cs:bootcallback], si - mov word [cs:bootcallback+2], ds - push cs - pop ds - mov [bootdevice], ax - mov [bootfs], bx - -; set up stack - mov ax, (TMP_STACK_TOP and 0xF0000) shr 4 - mov ss, ax - mov sp, TMP_STACK_TOP and 0xFFFF - -; try to load configuration file - mov ax, 1 - mov di, config_file_struct - call [bootcallback] - cld - push cs - pop es -; bx=0 - ok, bx=1 - part of file loaded, assume this is ok - cmp bx, 1 - ja .config_bad -; configuration file was loaded, parse -; if length is too big, use first 0FFFFh bytes - test dx, dx - jz @f - mov ax, 0FFFFh -@@: -; ds:si will be pointer to current data, dx = limit - xchg ax, dx - push 4000h - pop ds - xor si, si -.parse_loop: -; skip spaces - cmp si, dx - jae .parse_done - lodsb - cmp al, ' ' - jbe .parse_loop - dec si -; loop over all possible configuration values - mov bx, config_file_variables -.find_variant: -; get length - mov cx, [es:bx] -; zero length = end of list - jecxz .find_newline -; skip over length - inc bx - inc bx - mov di, bx -; skip over string - add bx, cx -; test whether we have at least cx symbols left - mov ax, cx - add ax, si - jc .next_variant1 - cmp ax, dx - jae .next_variant1 -; save current position - push si -; compare strings - repz cmpsb - jnz .next_variant2 -; strings are equal; look for "=" with possible spaces before and after -@@: - cmp si, dx - jae .next_variant2 - lodsb - cmp al, ' ' - jbe @b - cmp al, '=' - jnz .next_variant2 -; ok, we found the true variant -; ignore saved position on the stack - pop ax -; call the parser - call word [es:bx] -; line parsed, find next -.find_newline: - cmp si, dx - jae .parse_done - lodsb - cmp al, 13 - jz .parse_loop - cmp al, 10 - jz .parse_loop - jmp .find_newline -.next_variant2: -; continue to the next variant, restoring current position - pop si -.next_variant1: -; continue to the next variant -; skip over the parser - inc bx - inc bx - jmp .find_variant -.parse_done: -.config_bad: - -; set up segment registers - push cs - pop ds -else - cld - push 0 - pop es -; \begin{diamond}[02.12.2005] -; if bootloader sets ax = 'KL', then ds:si points to loader block - cmp ax, 'KL' - jnz @f - mov word [cs:cfgmanager.loader_block], si - mov word [cs:cfgmanager.loader_block+2], ds - mov word [es:BOOT_LO.kernel_restart], kernel_restart_bootblock -@@: -; \end{diamond}[02.12.2005] - -; if bootloader sets cx = 'HA' and dx = 'RD', then bx contains identifier of source disk -; (see comment to BOOT_LO.sys_disk and loader_doc.txt) - mov word [es:BOOT_LO.sys_disk], 'r1' ; default value: /rd/1 - cmp cx, 'HA' - jnz no_hd_load - cmp dx, 'RD' - jnz no_hd_load - mov [es:BOOT_LO.sys_disk], bx -no_hd_load: - -; set up stack - mov ax, (TMP_STACK_TOP and 0xF0000) shr 4 - mov ss, ax - mov sp, TMP_STACK_TOP and 0xFFFF -; set up segment registers - push cs - pop ds - push cs - pop es -end if - -; set videomode - mov ax, 3 - int 0x10 - -if lang eq ru - ; Load & set russian VGA font (RU.INC) - mov bp, RU_FNT1 ; RU_FNT1 - First part - mov bx, 1000h ; 768 bytes - mov cx, 30h ; 48 symbols - mov dx, 80h ; 128 - position of first symbol - mov ax, 1100h - int 10h - - mov bp, RU_FNT2 ; RU_FNT2 -Second part - mov bx, 1000h ; 512 bytes - mov cx, 20h ; 32 symbols - mov dx, 0E0h ; 224 - position of first symbol - mov ax, 1100h - int 10h - ; End set VGA russian font -else if lang eq et - mov bp, ET_FNT ; ET_FNT1 - mov bx, 1000h ; - mov cx, 255 ; 256 symbols - xor dx, dx ; 0 - position of first symbol - mov ax, 1100h - int 10h -end if - -; draw frames - push 0xb800 - pop es - xor di, di - mov ah, 1*16+15 - -; draw top - mov si, d80x25_top - mov cx, d80x25_top_num * 80 -@@: - lodsb - stosw - loop @b -; draw spaces - mov si, space_msg - mov dx, 25 - d80x25_top_num - d80x25_bottom_num -dfl1: - push si - mov cx, 80 -@@: - lodsb - stosw - loop @b - pop si - dec dx - jnz dfl1 -; draw bottom - mov si, d80x25_bottom - mov cx, d80x25_bottom_num * 80 -@@: - lodsb - stosw - loop @b - - mov byte [space_msg+80], 0 ; now space_msg is null terminated - - _setcursor d80x25_top_num,0 - - -; TEST FOR 386+ - - mov bx, 0x4000 - pushf - pop ax - mov dx, ax - xor ax, bx - push ax - popf - pushf - pop ax - and ax, bx - and dx, bx - cmp ax, dx - jnz cpugood - mov si, not386 -sayerr: - call print - jmp $ - cpugood: - - push 0 - popf - -; set up esp - movzx esp, sp - - push 0 - pop es - - xor cx, cx -@@: - in al, 64h - test al, 2 - loopnz @b - - mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование - out 0x60, al - xor cx, cx -@@: - in al, 64h - test al, 1 - loopz @b - in al, 0x60 - -;;;/diamond today 5.02.2008 -; set keyboard typematic rate & delay - mov al, 0xf3 - out 0x60, al - xor cx, cx -@@: - in al, 64h - test al, 1 - loopz @b - in al, 0x60 - mov al, 0 - out 0x60, al - xor cx, cx -@@: - in al, 64h - test al, 1 - loopz @b - in al, 0x60 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - sti -; --------------- APM --------------------- - and word [es:BOOT_LO.apm_version], 0 ; ver = 0.0 (APM not found) - mov ax, 0x5300 - xor bx, bx - int 0x15 - jc apm_end ; APM not found - test cx, 2 - jz apm_end ; APM 32-bit protected-mode interface not supported - mov [es:BOOT_LO.apm_version], ax ; Save APM Version - mov [es:BOOT_LO.apm_flags], cx ; Save APM flags - - ; Write APM ver ---- - and ax, 0xf0f - add ax, '00' - mov si, msg_apm - mov [si + 5], ah - mov [si + 7], al - _setcursor 0, 3 - call printplain - ; ------------------ - - mov ax, 0x5304 ; Disconnect interface - xor bx, bx - int 0x15 - mov ax, 0x5303 ; Connect 32 bit mode interface - xor bx, bx - int 0x15 - - mov [es:BOOT_LO.apm_entry], ebx - mov [es:BOOT_LO.apm_code_32], ax - mov [es:BOOT_LO.apm_code_16], cx - mov [es:BOOT_LO.apm_data_16], dx - -apm_end: - _setcursor d80x25_top_num, 0 - -if ~ defined extended_primary_loader -;CHECK current of code - cmp [cfgmanager.loader_block], -1 - jz noloaderblock - les bx, [cfgmanager.loader_block] - cmp byte [es:bx], 1 - mov si, loader_block_error - jnz sayerr - push 0 - pop es -end if - -noloaderblock: -; DISPLAY VESA INFORMATION - call print_vesa_info - call calc_vmodes_table - call check_first_parm ;check and enable cursor_pos - -; \begin{diamond}[30.11.2005] -cfgmanager: -; settings: -; a) preboot_graph = graphical mode -; preboot_gprobe = probe this mode? -; b) preboot_biosdisk = use BIOS disks through V86 emulation? // (earlier was: preboot_dma = use DMA access?) -; c) preboot_debug = duplicates kernel debug output to the screen -; d) preboot_launcher = start the first app (right now it's LAUNCHER) after kernel is loaded? -; e) preboot_device = from where to boot? - -; determine default settings -if ~ defined extended_primary_loader - mov [.bSettingsChanged], 0 -end if - -;.preboot_gr_end: - mov di, preboot_device -; if image in memory is present and [preboot_device] is uninitialized, -; set it to use this preloaded image - cmp byte [di], 0 - jnz .preboot_device_inited -if defined extended_primary_loader - inc byte [di] - cmp byte [bootdevice], 'f' ; floppy? - jz .preboot_device_inited - inc byte [di] -else - cmp [.loader_block], -1 - jz @f - les bx, [.loader_block] - test byte [es:bx+1], 1 - jz @f - mov byte [di], 3 - jmp .preboot_device_inited -@@: -; otherwise, set [preboot_device] to 1 (default value - boot from floppy) - mov byte [di], 1 -end if -.preboot_device_inited: -; following 4 lines set variables to 1 if its current value is 0 - cmp byte [di+preboot_dma-preboot_device], 1 - adc byte [di+preboot_dma-preboot_device], 0 - cmp byte [di+preboot_launcher-preboot_device], 1 ; Start LAUNCHER by default - adc byte [di+preboot_launcher-preboot_device], 0 - _setcursor 5,2 - - mov si, linef - call printplain - mov si, start_msg - call print - mov si, time_msg - call print -; get start time - call .gettime - mov [.starttime], eax - mov word [.timer], .newtimer - mov word [.timer+2], cs -.printcfg: - - _setcursor 9,0 - mov si, current_cfg_msg - call print - mov si, curvideo_msg - call print - - call draw_current_vmode - - mov si, usebd_msg - cmp [preboot_biosdisk], 1 - call .say_on_off - mov si, debug_mode_msg - cmp [preboot_debug], 1 - call .say_on_off - mov si, launcher_msg - cmp [preboot_launcher], 1 - call .say_on_off - mov si, preboot_device_msg - call print - mov al, [preboot_device] -if defined extended_primary_loader - and eax, 3 -else - and eax, 7 -end if - mov si, [preboot_device_msgs+eax*2] - call printplain -.show_remarks: -; show remarks in gray color - mov di, ((21-num_remarks)*80 + 2)*2 - push 0xB800 - pop es - mov cx, num_remarks - mov si, remarks -.write_remarks: - lodsw - push si - xchg ax, si - mov ah, 1*16+7 ; background: blue (1), foreground: gray (7) - push di -.write_remark: - lodsb - test al, al - jz @f - stosw - jmp .write_remark -@@: - pop di - pop si - add di, 80*2 - loop .write_remarks -.wait: - _setcursor 25,0 ; out of screen -; set timer interrupt handler - cli - push 0 - pop es - push dword [es:8*4] - pop dword [.oldtimer] - push dword [.timer] - pop dword [es:8*4] -; mov eax, [es:8*4] -; mov [.oldtimer], eax -; mov eax, [.timer] -; mov [es:8*4], eax - sti -; wait for keypressed - xor ax, ax - int 16h - push ax -; restore timer interrupt -; push 0 -; pop es - mov eax, [.oldtimer] - mov [es:8*4], eax - mov [.timer], eax - - _setcursor 7,0 - mov si, space_msg - call printplain -; clear remarks and restore normal attributes - push es - mov di, ((21-num_remarks)*80 + 2)*2 - push 0xB800 - pop es - mov cx, num_remarks - mov ax, ' ' + (1*16 + 15)*100h -@@: - push cx - mov cx, 76 - rep stosw - pop cx - add di, 4*2 - loop @b - pop es - pop ax -; switch on key - cmp al, 13 - jz .continue - or al, 20h - cmp al, 'a' ; select graphical mode - jz .change_a - cmp al, 'q' ; Trick to make 'A' key on azerty keyboard work - je .change_a - cmp al, 'b' ; use BIOS disks? // (selecting YES will make BIOS disks visible as /bd) - jz .change_b - cmp al, 'c' ; load kernel in debug mode? - jz .change_c - cmp al, 'd' ; start launcher after kernel is loaded? - jz .change_d - cmp al, 'e' ; select boot origin - jnz .show_remarks -; e) preboot_device = from where to boot? -if defined extended_primary_loader - _ask_question bdev,'13',preboot_device ; range accepted for answer: 1-3 -else - _ask_question bdev,'14',preboot_device ; range accepted for answer: 1-4 -end if - _setcursor 14,0 - -.d: -if ~ defined extended_primary_loader - mov [.bSettingsChanged], 1 -end if -.esc_pressed: - call clear_vmodes_table ;clear vmodes_table - jmp .printcfg - -.change_a: - call clear_vmodes_table ;clear vmodes_table - - mov si, word [cursor_pos] - mov word [cursor_pos_old], si -.loops: - call draw_vmodes_table - _setcursor 25,0 ; out of screen - xor ax, ax - int 0x16 -; call clear_table_cursor ;clear current position of cursor - - mov si, word [cursor_pos] - - cmp al, 27 ; If ESC was pressed, do not change the value - jnz @f ; Just exit the resolution selection box - - mov si, word [cursor_pos_old] - mov word [cursor_pos], si - jmp .esc_pressed -@@: - cmp ah, 0x48;x,0x48E0 ; up - jne .down - cmp si, modes_table - jbe .loops - sub word [cursor_pos], size_of_step - jmp .loops - -.down: - cmp ah, 0x50;x,0x50E0 ; down - jne .pgup - cmp word[es:si+10], -1 - je .loops - add word [cursor_pos], size_of_step - jmp .loops - -.pgup: - cmp ah, 0x49 ; page up - jne .pgdn - sub si, size_of_step*long_v_table - cmp si, modes_table - jae @f - mov si, modes_table -@@: - mov word [cursor_pos], si - mov si, word [home_cursor] - sub si, size_of_step*long_v_table - cmp si, modes_table - jae @f - mov si, modes_table -@@: - mov word [home_cursor], si - jmp .loops - -.pgdn: - cmp ah, 0x51 ; page down - jne .enter - mov ax, [end_cursor] - add si, size_of_step*long_v_table - cmp si, ax - jb @f - mov si, ax - sub si, size_of_step -@@: - mov word [cursor_pos], si - mov si, word [home_cursor] - sub ax, size_of_step*long_v_table - add si, size_of_step*long_v_table - cmp si, ax - jb @f - mov si, ax -@@: - mov word [home_cursor], si - jmp .loops - -.enter: - cmp al, 0x0D;x,0x1C0D ; enter - jne .loops - push word [cursor_pos] - pop bp - push word [es:bp] - pop word [x_save] - push word [es:bp+2] - pop word [y_save] - push word [es:bp+6] - pop word [number_vm] - mov word [preboot_graph], bp ;save choose - - jmp .d - -.change_b: ; b) preboot_biosdisk = use BIOS disks through V86 emulation? -; _setcursor 16,0 -; mov si, ask_dma // (earlier was: preboot_dma = use DMA access?) -; call print -; mov bx, '13' ; range accepted for answer: 1-3 -; call getkey -; mov [preboot_dma], al - _ask_question ask_bd,'12',preboot_biosdisk ; range accepted for answer: 1-2 - _setcursor 11,0 - jmp .d -.change_c: ; c) preboot_debug = duplicates kernel debug output to the screen - _ask_question ask_debug,'12',preboot_debug ; range accepted for answer: 1-2 - _setcursor 12,0 - jmp .d -.change_d: ; d) preboot_launcher = start the first app (right now it's LAUNCHER) after kernel is loaded? - _ask_question ask_launcher,'12',preboot_launcher ; range accepted for answer: 1-2 - _setcursor 13,0 - jmp .d -;;;;;;;;;;;;;;;;;;;;;;;;;;;; -.say_on_off: - pushf - call print - mov si, on_msg - popf - jz @f - mov si, off_msg -@@: - jmp printplain -; novesa and vervesa strings are not used at the moment of executing this code -virtual at novesa -.oldtimer dd ? -.starttime dd ? -if ~ defined extended_primary_loader -.bSettingsChanged db ? -end if -.timer dd ? -end virtual -if ~ defined extended_primary_loader -.loader_block dd -1 -end if -.gettime: - mov ah, 0 - int 1Ah - xchg ax, cx - shl eax, 10h - xchg ax, dx - ret -.newtimer: - push ds - push cs - pop ds - pushf - call [.oldtimer] - pushad - call .gettime - sub eax, [.starttime] -if defined extended_primary_loader - sub ax, [preboot_timeout] -else - ; bios 0x1A timer runs at ~18 ticks per second - sub ax, 18*PREBOOT_TIMEOUT -end if - jae .timergo - neg ax - add ax, 18-1 - mov bx, 18 - xor dx, dx - div bx -if lang eq ru -; подождите 5 секунд, 4/3/2 секунды, 1 секунду - cmp al, 5 - mov cl, ' ' - jae @f - cmp al, 1 - mov cl, 0xE3 ; 'у' in cp866 - jz @f - mov cl, 0xEB ; 'ы' in cp866 -@@: - mov [time_str+9], cl -else if lang eq et - cmp al, 1 - ja @f - mov byte [time_str+9], ' ' - mov byte [time_str+10], ' ' -@@: -else if lang eq sp -; esperar 5/4/3/2 segundos, 1 segundo - cmp al, 1 - mov cl, 's' - ja @f - mov cl, ' ' -@@: - mov [time_str+10], cl -else -; wait 5/4/3/2 seconds, 1 second - cmp al, 1 - mov cl, 's' - ja @f - mov cl, ' ' -@@: - mov [time_str+9], cl -end if - add al, '0' - mov [time_str+1], al - mov si, time_msg - _setcursor 7,0 - call print - _setcursor 25,0 - popad - pop ds - iret -.timergo: - push 0 - pop es - mov eax, [.oldtimer] - mov [es:8*4], eax - mov sp, 0EC00h -.continue: - sti - _setcursor 6,0 - mov si, space_msg - call printplain - call printplain - _setcursor 6,0 - mov si, loading_msg - call print - _setcursor 16,0 -if ~ defined extended_primary_loader - cmp [.bSettingsChanged], 0 - jz .load - cmp [.loader_block], -1 - jz .load - les bx, [.loader_block] - mov eax, [es:bx+3] - push ds - pop es - test eax, eax - jz .load - push eax - mov si, save_quest - call print -.waityn: - mov ah, 0 - int 16h - or al, 20h - cmp al, 'n' - jz .loadc - if lang eq sp - cmp al, 's' - else - cmp al, 'y' - end if - jnz .waityn - call putchar - mov byte [space_msg+80], 186 - - pop eax - push cs - push .cont - push eax - retf ;call back -.loadc: - pop eax -.cont: - push cs - pop ds - mov si, space_msg - mov byte [si+80], 0 - _setcursor 16,0 - call printplain - _setcursor 16,0 -.load: -end if -; \end{diamond}[02.12.2005] - -; ASK GRAPHICS MODE - - call set_vmode - -; GRAPHICS ACCELERATION -; force yes - mov [es:BOOT_LO.mtrr], byte 1 - -; DMA ACCESS TO HD - - mov al, [preboot_dma] - mov [es:BOOT_LO.dma], al - -; Set kernel DEBUG mode - if nonzero, duplicates debug output to the screen. - mov al, [preboot_debug] - mov [es:BOOT_LO.debug_print], al ;// 0x901E - -; Start the first app (right now it's LAUNCHER) after kernel is loaded? - mov al, [preboot_launcher] - mov [es:BOOT_LO.launcher_start], al ;// 0x901D - -; BOOT DEVICE - - mov al, [preboot_device] -if defined extended_primary_loader - cmp al, RD_LOAD_FROM_MEMORY - jnz @f - mov al, RD_LOAD_FROM_NONE -@@: -end if - mov [es:BOOT_LO.rd_load_from], al - -; /sys path - mov eax, dword[preboot_syspath+0] - mov dword[es:BOOT_LO.syspath+0], eax - mov eax, dword[preboot_syspath+4] - mov dword[es:BOOT_LO.syspath+4], eax - mov eax, dword[preboot_syspath+8] - mov dword[es:BOOT_LO.syspath+8], eax - mov eax, dword[preboot_syspath+12] - mov dword[es:BOOT_LO.syspath+12], eax - - -; GET MEMORY MAP -include '../detect/biosmem.inc' - -; READ DISKETTE TO MEMORY - - cmp byte [es:BOOT_LO.rd_load_from], RD_LOAD_FROM_FLOPPY - jne no_sys_on_floppy - mov si, diskload - call print - xor ax, ax ; reset drive - xor dx, dx - int 0x13 -; do we boot from CD-ROM? - mov ah, 41h - mov bx, 55AAh - xor dx, dx - int 0x13 - jc .nocd - cmp bx, 0AA55h - jnz .nocd - mov ah, 48h - push ds - push es - pop ds - mov si, 0xa000 - mov word [si], 30 - int 0x13 - pop ds - jc .nocd - push ds - lds si, [es:si+26] - test byte [ds:si+10], 40h - pop ds - jz .nocd -; yes - read all floppy by 18 sectors - -; TODO: !!!! read only first sector and set variables !!!!! -; ... -; TODO: !!! then read flippy image track by track - - mov cx, 0x0001 ; startcyl,startsector -.a1: - push cx dx - mov al, 18 - mov bx, 0xa000 - call boot_read_floppy - mov si, movedesc - push es - push ds - pop es - mov cx, 256*18 - mov ah, 0x87 - int 0x15 - pop es - pop dx cx - test ah, ah - jnz sayerr_floppy - add dword [si+8*3+2], 512*18 - inc dh - cmp dh, 2 - jnz .a1 - mov dh, 0 - inc ch - cmp ch, 80 - jae ok_sys_on_floppy - pusha - mov al, ch - shr ch, 2 - add al, ch - aam - xchg al, ah - add ax, '00' - mov si, pros - mov [si], ax - call printplain - popa - jmp .a1 -.nocd: -; no - read only used sectors from floppy -; now load floppy image to memory -; at first load boot sector and first FAT table - -; read only first sector and fill variables - mov cx, 0x0001 ; first logical sector - xor dx, dx ; head = 0, drive = 0 (a:) - mov al, 1 ; read one sector - mov bx, 0xB000 ; es:bx -> data area - call boot_read_floppy -; fill the necessary parameters to work with a floppy - mov ax, word [es:bx+24] - mov word [BPB_SecPerTrk], ax - mov ax, word [es:bx+26] - mov word [BPB_NumHeads], ax - mov ax, word [es:bx+17] - mov word [BPB_RootEntCnt], ax - mov ax, word [es:bx+14] - mov word [BPB_RsvdSecCnt], ax - mov ax, word [es:bx+19] - mov word [BPB_TotSec16], ax - mov al, byte [es:bx+13] - mov byte [BPB_SecPerClus], al - mov al, byte [es:bx+16] - mov byte [BPB_NumFATs], al -; 18.11.2008 - mov ax, word [es:bx+22] - mov word [BPB_FATSz16], ax - mov cx, word [es:bx+11] - mov word [BPB_BytsPerSec], cx - -; count of clusters in FAT12 ((size_of_FAT*2)/3) -; mov ax, word [BPB_FATSz16] -; mov cx, word [BPB_BytsPerSec] -;end 18.11.2008 - xor dx, dx - mul cx - shl ax, 1 - mov cx, 3 - div cx ; now ax - number of clusters in FAT12 - mov word [end_of_FAT], ax - -; load first FAT table - mov cx, 0x0002 ; startcyl,startsector ; TODO!!!!! - xor dx, dx ; starthead,drive - mov al, byte [BPB_FATSz16] ; no of sectors to read - add bx, word [BPB_BytsPerSec] ; es:bx -> data area - call boot_read_floppy - mov bx, 0xB000 - -; and copy them to extended memory - mov si, movedesc - mov [si+8*2+3], bh ; from - - mov ax, word [BPB_BytsPerSec] - shr ax, 1 ; words per sector - mov cx, word [BPB_RsvdSecCnt] - add cx, word [BPB_FATSz16] - mul cx - push ax ; save to stack count of words in boot+FAT - xchg ax, cx - - push es - push ds - pop es - mov ah, 0x87 - int 0x15 - pop es - test ah, ah - jz @f -sayerr_floppy: - mov dx, 0x3f2 - mov al, 0 - out dx, al -sayerr_memmove: - mov si, memmovefailed - jmp sayerr_plain -@@: - pop ax ; restore from stack count of words in boot+FAT - shl ax, 1 ; make bytes count from count of words - and eax, 0ffffh - add dword [si+8*3+2], eax - -; copy first FAT to second copy -; TODO: BPB_NumFATs !!!!! - add bx, word [BPB_BytsPerSec] ; !!! TODO: may be need multiply by BPB_RsvdSecCnt !!! - mov byte [si+8*2+3], bh ; bx - begin of FAT - - mov ax, word [BPB_BytsPerSec] - shr ax, 1 ; words per sector - mov cx, word [BPB_FATSz16] - mul cx - mov cx, ax ; cx - count of words in FAT - - push es - push ds - pop es - mov ah, 0x87 - int 0x15 - pop es - test ah, ah - jnz sayerr_floppy - - mov ax, cx - shl ax, 1 - and eax, 0ffffh ; ax - count of bytes in FAT - add dword [si+8*3+2], eax - -; reading RootDir -; TODO: BPB_NumFATs - add bx, ax - add bx, 100h - and bx, 0ff00h ; bx - place in buffer to write RootDir - push bx - - mov bx, word [BPB_BytsPerSec] - shr bx, 5 ; divide bx by 32 - mov ax, word [BPB_RootEntCnt] - xor dx, dx - div bx - push ax ; ax - count of RootDir sectors - - mov ax, word [BPB_FATSz16] - xor cx, cx - mov cl, byte [BPB_NumFATs] - mul cx - add ax, word [BPB_RsvdSecCnt] ; ax - first sector of RootDir - - mov word [FirstDataSector], ax - pop bx - push bx - add word [FirstDataSector], bx ; Begin of data region of floppy - -; read RootDir - call conv_abs_to_THS - pop ax - pop bx ; place in buffer to write - push ax - call boot_read_floppy ; read RootDir into buffer -; copy RootDir - mov byte [si+8*2+3], bh ; from buffer - pop ax ; ax = count of RootDir sectors - mov cx, word [BPB_BytsPerSec] - mul cx - shr ax, 1 - mov cx, ax ; count of words to copy - push es - push ds - pop es - mov ah, 0x87 - int 0x15 - pop es - - mov ax, cx - shl ax, 1 - and eax, 0ffffh ; ax - count of bytes in RootDir - add dword [si+8*3+2], eax ; add count of bytes copied - -; Reading data clusters from floppy - mov byte [si+8*2+3], bh - push bx - - mov di, 2 ; First data cluster -.read_loop: - mov bx, di - shr bx, 1 ; bx+di = di*1.5 - jnc .even - test word [es:bx+di+0xB200], 0xFFF0 ; TODO: may not be 0xB200 !!! - jmp @f -.even: - test word [es:bx+di+0xB200], 0xFFF ; TODO: may not be 0xB200 !!! - -@@: - jz .skip -; read cluster di -;.read: - ;conv cluster di to abs. sector ax - ; ax = (N-2) * BPB_SecPerClus + FirstDataSector - mov ax, di - sub ax, 2 - xor bx, bx - mov bl, byte [BPB_SecPerClus] - mul bx - add ax, word [FirstDataSector] - call conv_abs_to_THS - pop bx - push bx - mov al, byte [BPB_SecPerClus] ; number of sectors in cluster - call boot_read_floppy - push es - push ds - pop es - pusha -; - mov ax, word [BPB_BytsPerSec] - xor cx, cx - mov cl, byte [BPB_SecPerClus] - mul cx - shr ax, 1 ; ax = (BPB_BytsPerSec * BPB_SecPerClus)/2 - mov cx, ax ; number of words to copy (count words in cluster) -; - mov ah, 0x87 - int 0x15 ; copy data - test ah, ah - popa - pop es - jnz sayerr_floppy -; skip cluster di -.skip: - mov ax, word [BPB_BytsPerSec] - xor cx, cx - mov cl, byte [BPB_SecPerClus] - mul cx - and eax, 0ffffh ; ax - count of bytes in cluster - add dword [si+8*3+2], eax - - mov ax, word [end_of_FAT] ; max cluster number - pusha -; draw percentage -; total clusters: ax -; read clusters: di - xchg ax, di - mov cx, 100 - mul cx - div di - aam - xchg al, ah - add ax, '00' - mov si, pros - cmp [si], ax - jz @f - mov [si], ax - call printplain -@@: - popa - inc di - cmp di, word [end_of_FAT] ; max number of cluster - jnz .read_loop - pop bx ; clear stack - -ok_sys_on_floppy: - mov si, backspace2 - call printplain - mov si, okt - call printplain -no_sys_on_floppy: - xor ax, ax ; reset drive - xor dx, dx - int 0x13 - mov dx, 0x3f2 ; floppy motor off - mov al, 0 - out dx, al - -if defined extended_primary_loader - cmp [es:BOOT_LO.rd_load_from], RD_LOAD_FROM_HD - jne no_sys_from_primary -; load kolibri.img using callback from primary loader - and word [movedesc + 24 + 2], 0 - mov byte [movedesc + 24 + 4], 10h -; read in blocks of 64K until file is fully loaded - mov ax, 1 -.repeat: - mov di, image_file_struct - call [bootcallback] - push cs - pop ds - push cs - pop es - cmp bx, 1 - ja sayerr_badsect - push bx - mov si, movedesc - and word [si + 16 + 2], 0 - mov byte [si + 16 + 4], 4 - mov ah, 87h - mov cx, 8000h - int 15h - pop bx - test ah, ah - jnz sayerr_memmove - inc byte [si + 24 + 4] - test bx, bx - jz no_sys_from_primary - mov ax, 2 - jmp .repeat -no_sys_from_primary: -end if - -; SET GRAPHICS - - xor ax, ax - mov es, ax - - mov ax, [es:BOOT_LO.vesa_mode] ; vga & 320x200 - mov bx, ax - cmp ax, 0x13 - je setgr - cmp ax, 0x12 - je setgr - mov ax, 0x4f02 ; Vesa -setgr: - int 0x10 - test ah, ah - mov si, fatalsel - jnz v_mode_error -; set mode 0x12 graphics registers: - cmp bx, 0x12 - jne gmok2 - - mov al, 0x05 - mov dx, 0x03ce - push dx - out dx, al ; select GDC mode register - mov al, 0x02 - inc dx - out dx, al ; set write mode 2 - - mov al, 0x02 - mov dx, 0x03c4 - out dx, al ; select VGA sequencer map mask register - mov al, 0x0f - inc dx - out dx, al ; set mask for all planes 0-3 - - mov al, 0x08 - pop dx - out dx, al ; select GDC bit mask register - ; for writes to 0x03cf -gmok2: - push ds - pop es diff --git a/kernel/branches/Kolibri-F/boot/booten.inc b/kernel/branches/Kolibri-F/boot/booten.inc deleted file mode 100644 index 376c01377..000000000 --- a/kernel/branches/Kolibri-F/boot/booten.inc +++ /dev/null @@ -1,107 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;====================================================================== -; -; BOOT DATA -; -;====================================================================== - -$Revision$ - - -d80x25_bottom: - db 186,' KolibriOS comes with ABSOLUTELY NO WARRANTY. See file COPYING for details ',186 - db 186,' If you find any bugs, please report them at: http://board.kolibrios.org ',186 - line_full_bottom -d80x25_bottom_num = 3 - -msg_apm db " APM x.x ", 0 -novesa db "Display: EGA/CGA",13,10,0 -s_vesa db "Version of VESA: " - .ver db "?.?",13,10,0 - -gr_mode db "Select a videomode: ",13,10,0 - -ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0 - -if defined extended_primary_loader -bdev db "Load ramdisk from [1-floppy; 2-kolibri.img; 3-don't load]: ",0 -else -bdev db "Load ramdisk from [1-floppy; 2-C:\kolibri.img (FAT32);" - db 13,10,186," " - db "3-use preloaded ram-image from kernel restart;" - db 13,10,186," " - db "4-create blank image]: ",0 -end if - -prnotfnd db "Fatal - Videomode not found.",0 - -not386 db "Fatal - CPU 386+ required.",0 -fatalsel db "Fatal - Graphics mode not supported by hardware.",0 -pres_key db "Press any key to choose a new videomode.",0 -badsect db 13,10,186," Fatal - Bad sector. Replace floppy.",0 -memmovefailed db 13,10,186," Fatal - Int 0x15 move failed.",0 -okt db " ... OK" -linef db 13,10,0 -diskload db "Loading diskette: 00 %",8,8,8,8,0 -pros db "00" -backspace2 db 8,8,0 -boot_dev db 0 ; 0=floppy, 1=hd -start_msg db "Press [abcde] to change settings, press [Enter] to continue booting",13,10,0 -time_msg db " or wait " -time_str db " 5 seconds" - db " to continue automatically",13,10,0 -current_cfg_msg db "Current settings:",13,10,0 -curvideo_msg db " [a] Videomode: ",0 - -mode0 db "320x200, EGA/CGA 256 colors",13,10,0 -mode9 db "640x480, VGA 16 colors",13,10,0 - -usebd_msg db " [b] Add disks visible by BIOS:",0 -on_msg db " on",13,10,0 -off_msg db " off",13,10,0 - -debug_mode_msg db " [c] Duplicate debug output to the screen:",0 -ask_debug db "Duplicate debug output to the screen? [1-yes, 2-no]: ",0 - -launcher_msg db " [d] Start LAUNCHER after kernel is loaded:",0 -ask_launcher db "Start first application (LAUNCHER) after kernel is loaded? [1-yes, 2-no]: ",0 - -preboot_device_msg db " [e] Floppy image: ",0 - -if defined extended_primary_loader -preboot_device_msgs dw 0,pdm1,pdm2,pdm3,0 -pdm1 db "real floppy",13,10,0 -pdm2 db "C:\kolibri.img (FAT32)",13,10,0 -pdm3 db "do not use floppy image",13,10,0 -else -preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0 -pdm1 db "real floppy",13,10,0 -pdm2 db "C:\kolibri.img (FAT32)",13,10,0 -pdm3 db "use already loaded image",13,10,0 -pdm4 db "create blank image",13,10,0 -end if - -loading_msg db "Loading KolibriOS...",0 - -if ~ defined extended_primary_loader -save_quest db "Remember current settings? [y/n]: ",0 -loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0 -end if - -_st latin1 '║ ┌───────────────────────────────┬─┐',13,10,0 -_r1 latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0 -_r2 latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0 -_rs latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0 -_bt latin1 '║ └───────────────────────────────┴─┘',13,10,0 - -remark1 db "Default values were selected to match most of configurations, but not all.",0 -remark2 db "If the system does not boot, try to disable option [b]. If the system gets",0 -remark3 db "stuck after booting, enable option [c], disable option [d] and make photo.",0 -remarks dw remark1, remark2, remark3 -num_remarks = 3 diff --git a/kernel/branches/Kolibri-F/boot/bootet.inc b/kernel/branches/Kolibri-F/boot/bootet.inc deleted file mode 100644 index 57145da1f..000000000 --- a/kernel/branches/Kolibri-F/boot/bootet.inc +++ /dev/null @@ -1,106 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;====================================================================== -; -; BOOT DATA -; -;====================================================================== - -$Revision$ - - -d80x25_bottom: - latin1 '║ KolibriOS on IGASUGUSE GARANTIITA. Vaata faili COPYING info saamiseks. Kui ║' - latin1 '║ leiate vigu, anna neist palun teada aadressil: http://board.kolibrios.org ║' - line_full_bottom -d80x25_bottom_num = 3 - -msg_apm latin1 " APM x.x ", 0 -novesa latin1 "Ekraan: EGA/CGA",13,10,0 -s_vesa latin1 "Vesa versioon: " - .ver db "?.?",13,10,0 - -gr_mode latin1 "Vali video resolutsioon: ",13,10,0 - -ask_bd latin1 "Lisa V86 reziimis BIOSle nähtavad kettad? [1-jah, 2-ei]: ",0 - -if defined extended_primary_loader -bdev latin1 "Paigalda mäluketas [1-diskett; 2-kolibri.img]: ",0 -else -bdev latin1 "Paigalda mäluketas [1-diskett; 2-C:\kolibri.img (FAT32);" - latin1 13,10,"║ " - latin1 "3-kasuta eellaaditud mäluketast kerneli restardist;" - latin1 13,10,"║ " - latin1 "4-loo tühi pilt]: ",0 -end if - -prnotfnd latin1 "Fataalne - Video resolutsiooni ei leitud.",0 - -not386 latin1 "Fataalne - CPU 386+ on vajalik.",0 -fatalsel latin1 "Fataalne - Riistvara ei toeta graafilist resolutsiooni.",0 -pres_key latin1 "Vajutage suvalist klahvi, et valida uus videomode.",0 -badsect latin1 13,10,"║ Fataalne - Vigane sektor. Asenda diskett.",0 -memmovefailed latin1 13,10,"║ Fataalne - Int 0x15 liigutamine ebaõnnestus.",0 -okt latin1 " ... OK" -linef latin1 13,10,0 -diskload latin1 "Loen disketti: 00 %",8,8,8,8,0 -pros latin1 "00" -backspace2 latin1 8,8,0 -boot_dev db 0 ; 0=floppy, 1=hd -start_msg latin1 "Vajuta [abcde] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0 -time_msg latin1 " või oota " -time_str latin1 " 5 sekundit" - latin1 " automaatseks jätkamiseks",13,10,0 -current_cfg_msg latin1 "Praegused seaded:",13,10,0 -curvideo_msg latin1 " [a] Video resolutsioon: ",0 - -mode0 latin1 "320x200, EGA/CGA 256 värvi",0 -mode9 latin1 "640x480, VGA 16 värvi",0 - -usebd_msg latin1 " [b] Lisa BIOSle nähtavad kettad:",0 -on_msg latin1 " sees",13,10,0 -off_msg latin1 " väljas",13,10,0 - -debug_mode_msg latin1 " [c] Dubleeri silumisinfo ekraanile:",0 -ask_debug latin1 "Dubleeri silumisinfo ekraanile? [1-jah, 2-ei]: ",0 - -launcher_msg latin1 " [d] Käivita LAUNCHER pärast kerneli laadimist:",0 -ask_launcher latin1 "Käivita esimese programm (LAUNCHER) peale kerneli laadimist? [1-jah, 2-ei]: ",0 - -preboot_device_msg latin1 " [e] Disketi kujutis: ",0 - -if defined extended_primary_loader -preboot_device_msgs dw 0,pdm1,pdm2,0 -pdm1 latin1 "reaalne diskett",13,10,0 -pdm2 latin1 "kolibri.img",13,10,0 -else -preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0 -pdm1 latin1 "reaalne diskett",13,10,0 -pdm2 latin1 "C:\kolibri.img (FAT32)",13,10,0 -pdm3 latin1 "kasuta juba laaditud kujutist",13,10,0 -pdm4 latin1 "loo tühi pilt",13,10,0 -end if - -loading_msg latin1 "Laadin KolibriOS...",0 - -if ~ defined extended_primary_loader -save_quest latin1 "Jäta meelde praegused seaded? [y/n]: ",0 -loader_block_error latin1 "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0 -end if - -_st latin1 '║ ┌───────────────────────────────┬─┐',13,10,0 -_r1 latin1 '║ │ 320x200 EGA/CGA 256 värvi │ │',13,10,0 -_r2 latin1 '║ │ 640x480 VGA 16 värvi │ │',13,10,0 -_rs latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0 -_bt latin1 '║ └───────────────────────────────┴─┘',13,10,0 - -remark1 latin1 "Vaikimisi väärtused on kasutatavad enamikes arvutites, kuid mitte kõigis.",0 -remark2 latin1 "Kui süsteem ei käivitu, proovige lülitada kirje [b] välja. Kui see läheb",0 -remark3 latin1 "kinni pärast käivitamist, võimaldama valik [c], keelake [d] ja teha foto.",0 -remarks dw remark1, remark2, remark3 -num_remarks = 3 \ No newline at end of file diff --git a/kernel/branches/Kolibri-F/boot/bootge.inc b/kernel/branches/Kolibri-F/boot/bootge.inc deleted file mode 100644 index b06ce1240..000000000 --- a/kernel/branches/Kolibri-F/boot/bootge.inc +++ /dev/null @@ -1,107 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;====================================================================== -; -; BOOT DATA -; -;====================================================================== - -$Revision$ - - -d80x25_bottom: - db 186,' KolibriOS wird ohne jegliche Garantie vertrieben. Details stehen in der ',186 - db 186,' Datei COPYING. Bitte melden Sie Fehler bei: http://board.kolibrios.org ',186 - line_full_bottom -d80x25_bottom_num = 3 - -msg_apm db " APM x.x ", 0 -novesa db "Anzeige: EGA/CGA ",13,10,0 -s_vesa db "Vesa-Version: " - .ver db "?.?",13,10,0 - -gr_mode db "Wahlen Sie einen videomode: ",13,10,0 - -ask_bd db "Add-Festplatten sichtbar BIOS in V86-Modus emuliert? [1-ja, 2 nein]: ",0 - -if defined extended_primary_loader -bdev db "Lade die Ramdisk von [1-Diskette; 2-kolibri.img]: ",0 -else -bdev db "Lade die Ramdisk von [1-Diskette; 2-C:\kolibri.img (FAT32);" - db 13,10,186," " - db "3-benutze ein bereits geladenes Kernel image;" - db 13,10,186," " - db "4-create blank image]: ",0 -end if - -prnotfnd db "Fatal - Videomodus nicht gefunden.",0 - -not386 db "Fatal - CPU 386+ benoetigt.",0 -fatalsel db "Fatal - Grafikmodus nicht unterstuetzt.",0 -pres_key db "Drucken Sie eine beliebige Taste, um eine neue videomode wahlen.",0 -badsect db 13,10,186," Fatal - Sektorfehler, Andere Diskette neutzen.",0 -memmovefailed db 13,10,186," Fatal - Int 0x15 Fehler.",0 -okt db " ... OK" -linef db 13,10,0 -diskload db "Lade Diskette: 00 %",8,8,8,8,0 -pros db "00" -backspace2 db 8,8,0 -boot_dev db 0 ; 0=floppy, 1=hd -start_msg db "Druecke [abcde], um die Einstellungen zu aendern, druecke [Enter] zum starten",13,10,0 -time_msg db " oder warte " -time_str db " 5 Sekunden" - db " bis zum automatischen Start",13,10,0 -current_cfg_msg db "Aktuelle Einstellungen:",13,10,0 -curvideo_msg db " [a] Videomodus: ",0 - -mode0 db "320x200, EGA/CGA 256 colors",13,10,0 -mode9 db "640x480, VGA 16 colors",13,10,0 - -usebd_msg db " [b] Add-Festplatten sichtbar durch das BIOS:",0 -on_msg db " an",13,10,0 -off_msg db " aus",13,10,0 - -debug_mode_msg db " [c] Duplizieren debuggen Ausgabe auf dem Bildschirm:",0 -ask_debug db "Duplizieren debuggen Ausgabe auf dem Bildschirm? [1-ja, 2 nein]: ",0 - -launcher_msg db " [d] Start LAUNCHER nach Kernel geladen wird:",0 -ask_launcher db "Starten erste Anwendung nach Kernel geladen wird? [1-ja, 2 nein]: ",0 - -preboot_device_msg db " [e] Diskettenimage: ",0 - -if defined extended_primary_loader -preboot_device_msgs dw 0,pdm1,pdm2,0 -pdm1 db "Echte Diskette",13,10,0 -pdm2 db "kolibri.img",13,10,0 -else -preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0 -pdm1 db "Echte Diskette",13,10,0 -pdm2 db "C:\kolibri.img (FAT32)",13,10,0 -pdm3 db "Nutze bereits geladenes Image",13,10,0 -pdm4 db "create blank image",13,10,0 -end if - -loading_msg db "Lade KolibriOS...",0 - -if ~ defined extended_primary_loader -save_quest db "Aktuelle Einstellungen speichern? [y/n]: ",0 -loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0 -end if - -_st latin1 '║ ┌───────────────────────────────┬─┐',13,10,0 -_r1 latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0 -_r2 latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0 -_rs latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0 -_bt latin1 '║ └───────────────────────────────┴─┘',13,10,0 - -remark1 db "Die Standardwerte sind fur die meisten gewahlt, aber nicht fur jedermann.",0 -remark2 db "Wenn das System nicht bootet, das Option [b] deaktivieren versuchen. Wenn es",0 -remark3 db "nach dem Booten hangen bleibt, aktivieren Sie Option [c], deaktivieren [d]",0 -remark4 db "und machen Fotos.",0 -remarks dw remark1, remark2, remark3, remark4 -num_remarks = 4 \ No newline at end of file diff --git a/kernel/branches/Kolibri-F/boot/bootru.inc b/kernel/branches/Kolibri-F/boot/bootru.inc deleted file mode 100644 index 1affe59ed..000000000 --- a/kernel/branches/Kolibri-F/boot/bootru.inc +++ /dev/null @@ -1,106 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;================================================================= -; -; BOOT DATA -; -;================================================================= - -$Revision$ - - -d80x25_bottom: - cp866 '║ KolibriOS НЕ ПРЕДОСТАВЛЯЕТ НИКАКИХ ГАРAНТИЙ. Подробнее смотрите в файле ║' - cp866 '║ COPYING.TXT. О найденных ошибках сообщайте на http://board.kolibrios.org ║' - line_full_bottom -d80x25_bottom_num = 3 - -msg_apm cp866 " APM x.x ", 0 -novesa cp866 "Видеокарта: EGA/CGA",13,10,0 -s_vesa cp866 "Версия VESA: " - .ver db "?.?",13,10,0 - -gr_mode cp866 "Выберите видеорежим: ",13,10,0 - -ask_bd cp866 "Добавить диски, видимые через BIOS в режиме V86? [1-да, 2-нет]: ",0 - -if defined extended_primary_loader -bdev cp866 "Загрузить образ из [1-дискета; 2-kolibri.img из папки загрузки;",13,10 - cp866 "║ 3-не загружать]: ",0 -else -bdev cp866 "Загрузить образ из [1-дискета; 2-C:\kolibri.img (FAT32);",13,10 - cp866 "║ 3-использовать уже загруженный образ;",13,10 - cp866 "║ 4-создать чистый образ]: ",0 -end if - -prnotfnd cp866 "Ошибка - Видеорежим не найден.",0 - -not386 cp866 "Ошибка - Требуется процессор 386+.",0 -fatalsel cp866 "Ошибка - Выбранный видеорежим не поддерживается.",0 -pres_key cp866 "Нажимите любую клавишу, для перехода в выбор режимов.",0 -badsect cp866 13,10,"║ Ошибка - Дискета повреждена. Попробуйте другую.",0 -memmovefailed cp866 13,10,"║ Ошибка - Int 0x15 move failed.",0 -okt cp866 " ... OK" -linef cp866 13,10,0 -diskload cp866 "Загрузка дискеты: 00 %",8,8,8,8,0 -pros cp866 "00" -backspace2 cp866 8,8,0 -boot_dev db 0 -start_msg cp866 "Нажмите [abcde] для изменения настроек, [Enter] для продолжения загрузки",13,10,0 -time_msg cp866 " или подождите " -time_str cp866 " 5 секунд " - cp866 " до автоматического продолжения",13,10,0 -current_cfg_msg cp866 "Текущие настройки:",13,10,0 -curvideo_msg cp866 " [a] Видеорежим: ",0 - -mode0 cp866 "320x200, EGA/CGA 256 цветов",13,10,0 -mode9 cp866 "640x480, VGA 16 цветов",13,10,0 - -usebd_msg cp866 " [b] Добавить диски, видимые через BIOS:",0 -on_msg cp866 " вкл",13,10,0 -off_msg cp866 " выкл",13,10,0 - -debug_mode_msg cp866 " [c] Дублировать дебаг-вывод на экран монитора:",0 -ask_debug cp866 "Дублировать дебаг-вывод на экран монитора? [1-да, 2-нет]: ",0 - -launcher_msg cp866 " [d] Запустить программу LAUNCHER после загрузки ядра:",0 -ask_launcher cp866 "Запустить первую программу (LAUNCHER) после загрузки ядра? [1-да, 2-нет]: ",0 - -preboot_device_msg cp866 " [e] Образ дискеты: ",0 - -if defined extended_primary_loader -preboot_device_msgs dw 0,pdm1,pdm2,pdm3,0 -pdm1 cp866 "настоящая дискета",13,10,0 -pdm2 cp866 "kolibri.img из папки загрузки",13,10,0 -pdm3 cp866 "не загружать образ рамдиска",13,10,0 -else -preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0 -pdm1 cp866 "настоящая дискета",13,10,0 -pdm2 cp866 "C:\kolibri.img (FAT32)",13,10,0 -pdm3 cp866 "использовать уже загруженный образ",13,10,0 -pdm4 cp866 "создать чистый образ",13,10,0 -end if - -loading_msg cp866 "Идёт загрузка KolibriOS...",0 - -if ~ defined extended_primary_loader ; saving not supported in this case -save_quest cp866 "Запомнить текущие настройки? [y/n]: ",0 -loader_block_error cp866 "Ошибка в данных начального загрузчика, продолжение невозможно.",0 -end if - -_st cp866 '║ ┌───────────────────────────────┬─┐ ',13,10,0 -_r1 cp866 '║ │ 320x200 EGA/CGA 256 цветов │ │ ',13,10,0 -_r2 cp866 '║ │ 640x480 VGA 16 цветов │ │ ',13,10,0 -_rs cp866 '║ │ ????x????@?? SVGA VESA │ │ ',13,10,0 -_bt cp866 '║ └───────────────────────────────┴─┘ ',13,10,0 - -remark1 cp866 "Значения по умолчанию выбраны для удобства большинства, но не всех. Если у",0 -remark2 cp866 "Вас не грузится система, попробуйте отключить пункт [b]. Если она зависла",0 -remark3 cp866 "после запуска, включите пункт [c], отключите пункт [d] и сделайте фото лога.",0 -remarks dw remark1, remark2, remark3 -num_remarks = 3 diff --git a/kernel/branches/Kolibri-F/boot/bootsp.inc b/kernel/branches/Kolibri-F/boot/bootsp.inc deleted file mode 100644 index ae6480c51..000000000 --- a/kernel/branches/Kolibri-F/boot/bootsp.inc +++ /dev/null @@ -1,108 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;====================================================================== -; -; BOOT DATA -; -;====================================================================== - -; Para modificar éste archivo es necesario abrirlo con codificación CP850 - -$Revision$ - - -d80x25_bottom: - cp850 '║ KolibriOS viene ABSOLUTAMENTE SIN GARANTíA. Lee el archivo COPYING por más ║' - cp850 '║ detalles. Por favor, informar de los errores en: http://board.kolibrios.org ║' - line_full_bottom -d80x25_bottom_num = 3 - -msg_apm cp850 " APM x.x ", 0 -novesa cp850 "Monitor: EGA/CGA",13,10,0 -s_vesa cp850 "Versión de VESA: " - .ver db "?.?",13,10,0 - -gr_mode cp850 "Selecciona un modo de video: ",13,10,0 - -ask_bd cp850 "¿Agregar discos visibles por el BIOS emulados en modo V86? [1-si, 2-no]: ",0 - -if defined extended_primary_loader -bdev cp850 "Cargar unidad ram desde [1-disquete; 2-kolibri.img]: ",0 -else -bdev cp850 "Cargar unidad ram desde [1-disquete; 2-C:\kolibri.img (FAT32);" - cp850 13,10,"║ " - cp850 "3-usar imagen precargada en el reinicio del núcleo;" - cp850 13,10,"║ " - cp850 "4-crear imagen vacía]: ",0 -end if - -prnotfnd cp850 "Fatal - Modo de video no encontrado.",0 - -not386 cp850 "Fatal - CPU 386+ requerido.",0 -fatalsel cp850 "Fatal - Modo de gráficos no soportado por hardware.",0 -pres_key cp850 "Presiona una tecla para seleccionar otro modo de video.",0 -badsect cp850 13,10,"║ Fatal - Sector mal. Reemplaze el disquete.",0 -memmovefailed cp850 13,10,"║ Fatal - Int 0x15 move failed.",0 -okt cp850 " ... BIEN" -linef cp850 13,10,0 -diskload cp850 "Cargando disquete: 00 %",8,8,8,8,0 -pros cp850 "00" -backspace2 cp850 8,8,0 -boot_dev db 0 ; 0=floppy, 1=hd -start_msg cp850 "Presiona [abcde] para cambiar la configuración, [Enter] para continuar",13,10,0 -time_msg cp850 " o espera " -time_str cp850 " 5 segundos" - cp850 " para que inicie automáticamente",13,10,0 -current_cfg_msg cp850 "Configuración actual:",13,10,0 -curvideo_msg cp850 " [a] Modo de video: ",0 - -mode0 cp850 "320x200, EGA/CGA 256 colores",13,10,0 -mode9 cp850 "640x480, VGA 16 colores",13,10,0 - -usebd_msg cp850 " [b] Agregar discos visibles por el BIOS:",0 -on_msg cp850 " activado",13,10,0 -off_msg cp850 " desactivado",13,10,0 - -debug_mode_msg cp850 " [c] Duplicar depurar salida a la pantalla:",0 -ask_debug cp850 "¿Duplicar depurar la salida a la pantalla? [1-si, 2-no]: ",0 - -launcher_msg cp850 " [d] Iniciar LAUNCHER después de cargar kernel:",0 -ask_launcher cp850 "¿Inicie la primera aplicación después de cargar el kernel? [1-si, 2-no]: ",0 - -preboot_device_msg cp850 " [e] Imagen de disquete: ",0 - -if defined extended_primary_loader -preboot_device_msgs dw 0,pdm1,pdm2,0 -pdm1 cp850 "disquete real",13,10,0 -pdm2 cp850 "C:\kolibri.img (FAT32)",13,10,0 -else -preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0 -pdm1 cp850 "disquete real",13,10,0 -pdm2 cp850 "C:\kolibri.img (FAT32)",13,10,0 -pdm3 cp850 "usar imagen ya cargada",13,10,0 -pdm4 cp850 "crear imagen vacía",13,10,0 -end if - -loading_msg cp850 "Cargando KolibriOS...",0 - -if ~ defined extended_primary_loader -save_quest cp850 "¿Recordar configuración actual? [s/n]: ",0 -loader_block_error cp850 "Bootloader inválido, no puedo continuar. Detenido.",0 -end if - -_st cp850 '║ ┌───────────────────────────────┬─┐',13,10,0 -_r1 cp850 '║ │ 320x200 EGA/CGA 256 colores │ │',13,10,0 -_r2 cp850 '║ │ 640x480 VGA 16 colores │ │',13,10,0 -_rs cp850 '║ │ ????x????@?? SVGA VESA │ │',13,10,0 -_bt cp850 '║ └───────────────────────────────┴─┘',13,10,0 - -remark1 cp850 "Los valores por defecto puede que no funcionen en algunas configuraciones.",0 -remark2 cp850 "Si el sistema no inicia, prueba deshabilitar la opción [b]. Si se bloquea",0 -remark3 cp850 "después de arrancar, habilite la opción [c], desactivar [d] y hacer fotos.",0 -remarks dw remark1, remark2, remark3 -num_remarks = 3 diff --git a/kernel/branches/Kolibri-F/boot/bootstr.inc b/kernel/branches/Kolibri-F/boot/bootstr.inc deleted file mode 100644 index ba2d7fcf2..000000000 --- a/kernel/branches/Kolibri-F/boot/bootstr.inc +++ /dev/null @@ -1,56 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; boot data: common strings (for all languages) -macro line_full_top { - db 201 - times 78 db 205 - db 187 -} -macro line_full_bottom { - db 200 - times 78 db 205 - db 188 -} -macro line_half { - db 186,' ' - times 76 db 0xc4 - db ' ',186 -} -macro line_space { - db 186 - times 78 db 32 - db 186 -} -d80x25_top: - line_full_top - cur_line_pos = 72 - ; this signature will be replaced with revision number (in kernel.asm) - store dword '****' at d80x25_top + cur_line_pos - -space_msg: - line_space -verstr: -; line_space -; version string - db 186,32 - repeat 78 - load a byte from version+%-1 - if a = 13 - break - end if - db a - end repeat - repeat 78 - ($-verstr) - db ' ' - end repeat - db 32,186 - line_half -d80x25_top_num = 4 diff --git a/kernel/branches/Kolibri-F/boot/bootvesa.inc b/kernel/branches/Kolibri-F/boot/bootvesa.inc deleted file mode 100644 index 39a60fe64..000000000 --- a/kernel/branches/Kolibri-F/boot/bootvesa.inc +++ /dev/null @@ -1,801 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -struc VBE_VGAInfo { - .VESASignature dd ? ; char - .VESAVersion dw ? ; short - .OemStringPtr dd ? ; char * - .Capabilities dd ? ; ulong - .VideoModePtr dd ? ; ulong - .TotalMemory dw ? ; short - ; VBE 2.0+ - .OemSoftwareRev db ? ; short - .OemVendorNamePtr dw ? ; char * - .OemProductNamePtr dw ? ; char * - .OemProductRevPtr dw ? ; char * - .reserved rb 222 ; char - .OemData rb 256 ; char -} - -struc VBE_ModeInfo { - .ModeAttributes dw ? ; short - .WinAAttributes db ? ; char - .WinBAttributes db ? ; char - .WinGranularity dw ? ; short - .WinSize dw ? ; short - .WinASegment dw ? ; ushort - .WinBSegment dw ? ; ushort - .WinFuncPtr dd ? ; void * - .BytesPerScanLine dw ? ; short - .XRes dw ? ; short - .YRes dw ? ; short - .XCharSize db ? ; char - .YCharSize db ? ; char - .NumberOfPlanes db ? ; char - .BitsPerPixel db ? ; char - .NumberOfBanks db ? ; char - .MemoryModel db ? ; char - .BankSize db ? ; char - .NumberOfImagePages db ? ; char - .res1 db ? ; char - .RedMaskSize db ? ; char - .RedFieldPosition db ? ; char - .GreenMaskSize db ? ; char - .GreenFieldPosition db ? ; char - .BlueMaskSize db ? ; char - .BlueFieldPosition db ? ; char - .RsvedMaskSize db ? ; char - .RsvedFieldPosition db ? ; char - .DirectColorModeInfo db ? ; char ; MISSED IN THIS TUTORIAL!! SEE ABOVE - ; VBE 2.0+ - .PhysBasePtr dd ? ; ulong - .OffScreenMemOffset dd ? ; ulong - .OffScreenMemSize dw ? ; short - ; VBE 3.0+ - .LinbytesPerScanLine dw ? ; short - .BankNumberOfImagePages db ? ; char - .LinNumberOfImagePages db ? ; char - .LinRedMaskSize db ? ; char - .LinRedFieldPosition db ? ; char - .LingreenMaskSize db ? ; char - .LinGreenFieldPosition db ? ; char - .LinBlueMaskSize db ? ; char - .LinBlueFieldPosition db ? ; char - .LinRsvdMaskSize db ? ; char - .LinRsvdFieldPosition db ? ; char - .MaxPixelClock dd ? ; ulong - .res2 rb 190 ; char -} - -virtual at $A000 - vi VBE_VGAInfo - mi VBE_ModeInfo -modes_table: -end virtual -cursor_pos dw 0 ;временное хранение курсора. -cursor_pos_old dw 0 -home_cursor dw 0 ;current shows rows a table -end_cursor dw 0 ;end of position current shows rows a table -scroll_start dw 0 ;start position of scroll bar -scroll_end dw 0 ;end position of scroll bar -long_v_table = 9 ;long of visible video table -size_of_step = 10 -scroll_area_size = long_v_table - 2 -int2str: - dec bl - jz @f - xor edx, edx - div ecx - push edx - call int2str - pop eax - @@: - or al, 0x30 - mov [ds:di], al - inc di - ret - -int2strnz: - cmp eax, ecx - jb @f - xor edx, edx - div ecx - push edx - call int2strnz - pop eax - @@: - or al, 0x30 - mov [es:di], al - inc di - ret - -;------------------------------------------------------- -;Write message about incorrect v_mode and write message about jmp on swith v_mode -v_mode_error: - _setcursor 19,2 - mov si, fatalsel - call printplain - _setcursor 20,2 - mov si, pres_key - call printplain - xor eax, eax - int 16h - jmp cfgmanager.d -;------------------------------------------------------- -; - - - -;------------------------------------------------------- -print_vesa_info: - _setcursor 5,2 - - mov [es:vi.VESASignature], 'VBE2' - mov ax, 0x4F00 - mov di, vi ;0xa000 - int 0x10 - or ah, ah - jz @f - mov [es:vi.VESASignature], 'VESA' - mov ax, $4F00 - mov di, vi - int 0x10 - or ah, ah - jnz .exit - @@: - cmp [es:vi.VESASignature], 'VESA' - jne .exit - cmp [es:vi.VESAVersion], 0x0100 - jb .exit - jmp .vesaok2 - - .exit: - mov si, novesa - call printplain - ret - - .vesaok2: - mov ax, [es:vi.VESAVersion] - add ax, '00' - - mov [s_vesa.ver], ah - mov [s_vesa.ver+2], al - mov si, s_vesa - call printplain - - _setcursor 4,2 - mov si, word[es:vi.OemStringPtr] - mov di, si - - push ds - mov ds, word[es:vi.OemStringPtr+2] - call printplain - pop ds - - ret -;----------------------------------------------------------------------------- - -calc_vmodes_table: - pushad - -; push 0 -; pop es - - lfs si, [es:vi.VideoModePtr] - - mov bx, modes_table -;save no vesa mode of work 320x200, EGA/CGA 256 梥⮢ and 640x480, VGA 16 梥⮢ - mov word [es:bx], 640 - mov word [es:bx+2], 480 - mov word [es:bx+6], 0x13 - - mov word [es:bx+10], 640 - mov word [es:bx+12], 480 - mov word [es:bx+16], 0x12 - add bx, 20 - .next_mode: - mov cx, word [fs:si]; mode number - cmp cx, -1 - je .modes_ok.2 - - mov ax, 0x4F01 - mov di, mi - int 0x10 - - or ah, ah - jnz .modes_ok.2;vesa_info.exit - - test [es:mi.ModeAttributes], 00000001b ;videomode support ? - jz @f - test [es:mi.ModeAttributes], 00010000b ;picture ? - jz @f - test [es:mi.ModeAttributes], 10000000b ;LFB ? - jz @f - - cmp [es:mi.BitsPerPixel], 16 ;List only supported videomodes (16, 24 and 32 bpp) - jb @f - -; 16 bpp might actually be 15 bpp - cmp [es:mi.BitsPerPixel], 16 - jne .l0 - cmp [es:mi.GreenMaskSize], 5 - jne .l0 -; mov [es:mi.BitsPerPixel],15 - jmp @f ; 15 bpp isnt supported ATM - - -.l0: - cmp [es:mi.XRes], 640 - jb @f - cmp [es:mi.YRes], 480 - jb @f -; cmp [es:mi.BitsPerPixel],8 -; jb @f - - mov ax, [es:mi.XRes] - mov [es:bx+0], ax ; +0[2] : resolution X - mov ax, [es:mi.YRes] - mov [es:bx+2], ax ; +2[2] : resolution Y - mov ax, [es:mi.ModeAttributes] - mov [es:bx+4], ax ; +4[2] : attributes - - cmp [s_vesa.ver], '2' -; jb .lp1 - jb @f ; We do not use Vesa 1.2 mode is now - - or cx, 0x4000 ; use LFB -.lp1: - mov [es:bx+6], cx ; +6 : mode number - movzx ax, byte [es:mi.BitsPerPixel] - mov word [es:bx+8], ax ; +8 : bits per pixel - add bx, size_of_step ; size of record - - @@: - add si, 2 - jmp .next_mode - - .modes_ok.2: - - mov word[es:bx], -1 ;end video table - mov word[end_cursor], bx ;save end cursor position -;;;;;;;;;;;;;;;;;; -;Sort array -; mov si,modes_table -;.new_mode: -; mov ax,word [es:si] -; cmp ax,-1 -; je .exxit -; add ax,word [es:si+2] -; add ax,word [es:si+8] -; mov bp,si -;.again: -; add bp,12 -; mov bx,word [es:bp] -; cmp bx,-1 -; je .exit -; add bx,word [es:bp+2] -; add bx,word [es:bp+8] -; -; cmp ax,bx -; ja .loops -; jmp .again -;.loops: -; push dword [es:si] -; push dword [es:si+4] -; push dword [es:si+8] -; push dword [es:bp] -; push dword [es:bp+4] -; push dword [es:bp+8] -; -; pop dword [es:si+8] -; pop dword [es:si+4] -; pop dword [es:si] -; pop dword [es:bp+8] -; pop dword [es:bp+4] -; pop dword [es:bp] -; jmp .new_mode -; -;.exit: add si,12 -; jmp .new_mode -;.exxit: - popad - ret - -;----------------------------------------------------------------------------- - -draw_current_vmode: - push 0 - pop es - - mov si, word [cursor_pos] - - cmp word [es:si+6], 0x12 - je .no_vesa_0x12 - - cmp word [es:si+6], 0x13 - je .no_vesa_0x13 - -if defined extended_primary_loader - mov di, config_file_variables -else - mov di, loader_block_error -end if - movzx eax, word[es:si+0] - mov ecx, 10 - call int2strnz - mov byte[es:di], 'x' - inc di - movzx eax, word[es:si+2] - call int2strnz - mov byte[es:di], 'x' - inc di - movzx eax, word[es:si+8] - call int2strnz - mov dword[es:di], 0x00000d0a -if defined extended_primary_loader - mov si, config_file_variables -else - mov si, loader_block_error -end if - push ds - push es - pop ds - call printplain - pop ds - ret -.no_vesa_0x13: - mov si, mode0 - jmp .print -.no_vesa_0x12: - mov si, mode9 -.print: - call printplain - ret -;----------------------------------------------------------------------------- -check_first_parm: -if defined extended_primary_loader - mov cx, [number_vm] - jcxz .novbemode - mov si, modes_table -.findvbemode: - cmp [es:si+6], cx - jnz @f - cmp word [es:si+8], 32 - je .ok_found_mode - cmp word [es:si+8], 24 - je .ok_found_mode - cmp word [es:si+8], 16 - je .ok_found_mode -@@: - add si, size_of_step - cmp word [es:si], -1 - jnz .findvbemode -.novbemode: - mov ax, [x_save] - test ax, ax - jz .zerro - mov bx, [y_save] - mov si, modes_table - call .loops - test ax, ax - jz .ok_found_mode -else - mov si, word [preboot_graph] - test si, si - jnz .no_zero ;if no zero -end if -.zerro: -; mov ax,modes_table -; mov word [cursor_pos],ax -; mov word [home_cursor],ax -; mov word [preboot_graph],ax -;SET default video of mode first probe will fined a move of work 1024x768@32 - mov cx, 32 - .find_mode: - mov ax, 1024 - mov bx, 768 - mov si, modes_table - call .loops - test ax, ax - jz .ok_found_mode - mov ax, 800 - mov bx, 600 - mov si, modes_table - call .loops - test ax, ax - jz .ok_found_mode - mov ax, 640 - mov bx, 480 - mov si, modes_table - call .loops - test ax, ax - jz .ok_found_mode - sub cx, 8 - jnz .find_mode - - mov si, modes_table -if ~ defined extended_primary_loader - jmp .ok_found_mode - - - -.no_zero: - mov bp, word [number_vm] - cmp bp, word [es:si+6] - jz .ok_found_mode - mov ax, word [x_save] - mov bx, word [y_save] - mov si, modes_table - call .loops - test ax, ax - jz .ok_found_mode - - mov si, modes_table -; cmp ax,modes_table -; jb .zerro ;check on correct if bellow -; cmp ax,word [end_cursor] -; ja .zerro ;check on correct if anymore -end if - -.ok_found_mode: - mov word [home_cursor], si -; mov word [cursor_pos],si - mov word [preboot_graph], si - mov ax, si - - mov ecx, long_v_table - -.loop: - add ax, size_of_step - cmp ax, word [end_cursor] - jae .next_step - loop .loop -.next_step: - sub ax, size_of_step*long_v_table - cmp ax, modes_table - jae @f - mov ax, modes_table -@@: - - mov word [home_cursor], ax - mov si, [preboot_graph] - mov word [cursor_pos], si - - push word [es:si] - pop word [x_save] - push word [es:si+2] - pop word [y_save] - push word [es:si+6] - pop word [number_vm] - - ret -;;;;;;;;;;;;;;;;;;;;;;;;;;; -.loops: - cmp ax, word [es:si] - jne .next - cmp bx, word [es:si+2] - jne .next - jcxz @f - cmp cx, word [es:si+8] - jne .next -@@: - xor ax, ax - ret -.next: - add si, size_of_step - cmp word [es:si], -1 - je .exit - jmp .loops -.exit: - or ax, -1 - ret - - -;----------------------------------------------------------------------------- - -;default_vmode: - -;----------------------------------------------------------------------------- -draw_vmodes_table: - _setcursor 9, 2 - mov si, gr_mode - call printplain - - mov si, _st - call printplain - - push word [cursor_pos] - pop ax - push word [home_cursor] - pop si - mov cx, si - - cmp ax, si - je .ok - jb .low - - - add cx, size_of_step*long_v_table - - cmp ax, cx - jb .ok - - sub cx, size_of_step*long_v_table - add cx, size_of_step - cmp cx, word[end_cursor] - jae .ok - add si, size_of_step - push si - pop word [home_cursor] - jmp .ok - - -.low: - sub cx, size_of_step - cmp cx, modes_table - jb .ok - push cx - push cx - pop word [home_cursor] - pop si - - -.ok: -; calculate scroll position - push si - mov ax, [end_cursor] - sub ax, modes_table - mov bx, size_of_step - cwd - div bx - mov si, ax ; si = size of list - mov ax, [home_cursor] - sub ax, modes_table - cwd - div bx - mov di, ax - mov ax, scroll_area_size*long_v_table - cwd - div si - test ax, ax - jnz @f - inc ax -@@: - cmp al, scroll_area_size - jb @f - mov al, scroll_area_size -@@: - mov cx, ax -; cx = scroll height -; calculate scroll pos - xor bx, bx ; initialize scroll pos - sub al, scroll_area_size+1 - neg al - sub si, long_v_table-1 - jbe @f - mul di - div si - mov bx, ax -@@: - inc bx - imul ax, bx, size_of_step - add ax, [home_cursor] - mov [scroll_start], ax - imul cx, size_of_step - add ax, cx - mov [scroll_end], ax - pop si - mov bp, long_v_table ;show rows -.@@_next_bit: -;clear cursor - mov ax, ' ' - mov word[ds:_r1+21], ax - mov word[ds:_r1+50], ax - - mov word[ds:_r2+21], ax - mov word[ds:_r2+45], ax - - mov word[ds:_rs+21], ax - mov word[ds:_rs+46], ax -; draw string - cmp word [es:si+6], 0x12 - je .show_0x12 - cmp word [es:si+6], 0x13 - je .show_0x13 - - movzx eax, word[es:si] - cmp ax, -1 - je .@@_end - mov di, _rs+23 - mov ecx, 10 - mov bl, 4 - call int2str - movzx eax, word[es:si+2] - inc di - mov bl, 4 - call int2str - - movzx eax, word[es:si+8] - inc di - mov bl, 2 - call int2str - - cmp si, word [cursor_pos] - jne .next -;draw cursor - mov word[ds:_rs+21], '>>' - mov word[ds:_rs+46], '<<' - - - -.next: - push si - mov si, _rs -.@@_sh: -; add to the string pseudographics for scrollbar - pop bx - push bx - mov byte [si+53], ' ' - cmp bx, [scroll_start] - jb @f - cmp bx, [scroll_end] - jae @f - mov byte [si+53], 0xDB ; filled bar -@@: - push bx - add bx, size_of_step - cmp bx, [end_cursor] - jnz @f - mov byte [si+53], 31 ; 'down arrow' symbol -@@: - sub bx, [home_cursor] - cmp bx, size_of_step*long_v_table - jnz @f - mov byte [si+53], 31 ; 'down arrow' symbol -@@: - pop bx - cmp bx, [home_cursor] - jnz @f - mov byte [si+53], 30 ; 'up arrow' symbol -@@: - call printplain - pop si - add si, size_of_step - - dec bp - jnz .@@_next_bit - -.@@_end: - mov si, _bt - call printplain - ret -.show_0x13: - push si - - cmp si, word [cursor_pos] - jne @f - mov word[ds:_r1+21], '>>' - mov word[ds:_r1+50], '<<' -@@: - mov si, _r1 - jmp .@@_sh -.show_0x12: - push si - cmp si, word [cursor_pos] - jne @f - - mov word[ds:_r2+21], '>>' - mov word[ds:_r2+45], '<<' -@@: - mov si, _r2 - jmp .@@_sh - -;----------------------------------------------------------------------------- -;Clear arrea of current video page (0xb800) -clear_vmodes_table: - pusha - ; draw frames - push es - push 0xb800 - pop es - mov di, 1444 - xor ax, ax - mov ah, 1*16+15 - mov cx, 77 - mov bp, 12 -.loop_start: - rep stosw - mov cx, 77 - add di, 6 - dec bp - jns .loop_start - pop es - popa - ret - -;----------------------------------------------------------------------------- - -set_vmode: - push 0 ;0;x1000 - pop es - - mov si, word [preboot_graph] ;[preboot_graph] - mov cx, word [es:si+6] ; number of mode - - - mov ax, word [es:si+0] ; resolution X - mov bx, word [es:si+2] ; resolution Y - - - mov word [es:BOOT_LO.x_res], ax ; resolution X - mov word [es:BOOT_LO.y_res], bx ; resolution Y - mov word [es:BOOT_LO.vesa_mode], cx ; number of mode - - cmp cx, 0x12 - je .mode0x12_0x13 - cmp cx, 0x13 - je .mode0x12_0x13 - - -; cmp byte [s_vesa.ver], '2' -; jb .vesa12 - -; VESA 2 and Vesa 3 - - mov ax, 0x4f01 - and cx, 0xfff - mov di, mi;0xa000 - int 0x10 - ; LFB - mov eax, [es:mi.PhysBasePtr];di+0x28] - mov [es:BOOT_LO.lfb], eax - ; ---- vbe voodoo - BytesPerLine = 0x10 - mov ax, [es:di+BytesPerLine] - mov [es:BOOT_LO.pitch], ax - ; BPP - cmp [es:mi.BitsPerPixel], 16 - jne .l0 - cmp [es:mi.GreenMaskSize], 5 - jne .l0 - mov [es:mi.BitsPerPixel], 15 -.l0: - mov al, byte [es:di+0x19] - mov [es:BOOT_LO.bpp], al - jmp .exit - -.mode0x12_0x13: - mov byte [es:BOOT_LO.bpp], 32 - or dword [es:BOOT_LO.lfb], 0xFFFFFFFF; 0x800000 - - -; VESA 1.2 PM BANK SWITCH ADDRESS - -;.vesa12: -; mov ax, 0x4f0A -; xor bx, bx -; int 0x10 -; xor eax, eax -; xor ebx, ebx -; mov ax, es -; shl eax, 4 -; mov bx, di -; add eax, ebx -; movzx ebx, word[es:di] -; add eax, ebx -; push 0x0000 -; pop es -; mov [es:BOOT_LO.bank_sw], eax - .exit: - ret - -;============================================================================= -;============================================================================= -;============================================================================= - diff --git a/kernel/branches/Kolibri-F/boot/et.inc b/kernel/branches/Kolibri-F/boot/et.inc deleted file mode 100644 index 585d3368e..000000000 --- a/kernel/branches/Kolibri-F/boot/et.inc +++ /dev/null @@ -1,16 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; Full ASCII code font -; only õ,ä,ü added -; Kaitz -ET_FNT: - fontfile file "ETFONT.FNT" - diff --git a/kernel/branches/Kolibri-F/boot/parsers.inc b/kernel/branches/Kolibri-F/boot/parsers.inc deleted file mode 100644 index e4cf0a98a..000000000 --- a/kernel/branches/Kolibri-F/boot/parsers.inc +++ /dev/null @@ -1,172 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2011-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; All parsers are called with ds:si -> value of the variable, -; possibly with spaces before, and dx = limit of config file. - -; Three subroutines parse_char, parse_number and parse_bool set CF -; if something has failed, otherwise return the value in al/ax. - -parse_timeout: -; timeout is a number not greater than 9 - call parse_number - jc .nothing - cmp ax, 9 - jbe @f - mov ax, 9 -@@: - imul ax, 18 - mov [es:preboot_timeout], ax -.nothing: - ret - -parse_resolution: -; resolution is *, 'x' can be used instead of '*' -; parse width - call parse_number - jc .nothing -; save width - xchg ax, bx -; test for 'x' or '*' - call parse_char - cmp al, 'x' - jz @f - cmp al, '*' - jnz .nothing -@@: -; parse height - call parse_number - jc .nothing -; write width and height - mov [es:x_save], bx - mov [es:y_save], ax -.nothing: - ret - -parse_vbemode: -; vbemode is a number - call parse_number - jc .nothing - mov [es:number_vm], ax -.nothing: - ret - -parse_biosdisks: -; using biosdisks is a boolean setting - call parse_bool - jc .nothing -; convert 0 to 2, 1 to 1 - inc ax - xor al, 3 - mov [es:preboot_biosdisk], al -.nothing: - ret - -parse_imgfrom: -; boot device (1-floppy 2-kolibri.img using primary loader, 3-don't use ramdisk) - call parse_number - jc .nothing - cmp al, 1 - jb .nothing - cmp al, 3 - ja .nothing - mov [es:preboot_device], al -.nothing: - ret - -parse_syspath: -; everything except spaces - mov bx, preboot_syspath -.next_char: - call parse_char - jc .done - mov [es:bx], al - inc bx - jmp .next_char -.done: - mov byte[es:bx], 0 ; terminator - ret - -parse_char: -; skip spaces and return the next character or CF if EOF. - cmp si, dx - jae .eof - lodsb - cmp al, ' ' - jbe parse_char - ret -.eof: - stc - ret - -parse_number: -; initialize high part of ax to zero - xor ax, ax -; skip spaces - call parse_char - jc .bad -; al should be a digit - sub al, '0' - cmp al, 9 - ja .bad -; accumulate the value in cx - xchg cx, ax -@@: - cmp si, dx - jae .eof - lodsb - sub al, '0' - cmp al, 9 - ja .end - imul cx, 10 - add cx, ax - jmp @b -; if the end is caused by non-digit, unwind the last character -.end: - dec si -.eof: - xchg cx, ax - clc - ret -.bad: - stc - ret - -parse_bool: -; skip spaces - call parse_char - jc .bad -; Boolean false can be represented as 0=no=off, -; boolean true can be represented as 1=yes=on. - cmp al, '0' - jz .false - cmp al, '1' - jz .true - mov ah, al - cmp si, dx - jae .bad - lodsb - cmp ax, 'n'*256 + 'o' - jz .false - cmp ax, 'o'*256 + 'f' - jz .false - cmp ax, 'y'*256 + 'e' - jz .true - cmp ax, 'o'*256 + 'n' - jz .true -.bad: - stc - ret -.true: - xor ax, ax - inc ax - ret -.false: - xor ax, ax - ret diff --git a/kernel/branches/Kolibri-F/boot/preboot.inc b/kernel/branches/Kolibri-F/boot/preboot.inc deleted file mode 100644 index 1492e181f..000000000 --- a/kernel/branches/Kolibri-F/boot/preboot.inc +++ /dev/null @@ -1,46 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -display_modechg db 0 ; display mode change for text, yes/no (0 or 2) - ; - ; !! Important note !! - ; - ; Must be set to 2, to avoid two screenmode - ; changes within a very short period of time. - -display_atboot db 0 ; show boot screen messages ( 2-no ) - -preboot_graph dw 0 ; graph mode -x_save dw 0 ; x -y_save dw 0 ; y -number_vm dw 0 ; -;pixel_save dw 0 ; per to pixel -preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes) -preboot_debug db 0 ; load kernel in debug mode? (1-yes, 2-no) -preboot_launcher db 0 ; start launcher after kernel is loaded? (1-yes, 2-no) -preboot_dma db 0 ; use DMA for access to HDD (1-always, 2-only for read, 3-never) -preboot_device db 0 ; device to load ramdisk from - ; 1-floppy 2-harddisk 3-kernel restart - ; 4-format ram disk 5-don't use ramdisk - ; !!!! 0 - autodetect !!!! -preboot_biosdisk db 0 ; use V86 to access disks through BIOS (1-yes, 2-no) -preboot_syspath db '/RD/1',0 ; path to /sys dir - rb 20-($-preboot_syspath) -if defined extended_primary_loader -; timeout in 1/18th of second for config settings screen -preboot_timeout dw PREBOOT_TIMEOUT*18 -end if - - if $>0x200 -ERROR: - prebooting parameters must fit in first sector!!! - end if -hdsysimage db 'KOLIBRI.IMG',0 ; load from -image_save db 'KOLIBRI.IMG',0 ; save to diff --git a/kernel/branches/Kolibri-F/boot/rdload.inc b/kernel/branches/Kolibri-F/boot/rdload.inc deleted file mode 100644 index bad0ba715..000000000 --- a/kernel/branches/Kolibri-F/boot/rdload.inc +++ /dev/null @@ -1,128 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -read_ramdisk: -; READ RAMDISK IMAGE FROM HD (only for IDE0, IDE1, IDE2, IDE3) - - cmp byte [BOOT.rd_load_from], RD_LOAD_FROM_HD - jne no_sys_on_hd.1 - - xor ebp, ebp -.hd_loop: - lea eax, [ebp+'0'] - mov [read_image_fsinfo.name_digit], al - movzx eax, byte [DRIVE_DATA+2+ebp] - test eax, eax - jz .next_hd - push eax - mov esi, 1 -.partition_loop: - mov eax, esi - push -'0' -@@: - xor edx, edx - div [_10] - push edx - test eax, eax - jnz @b - mov edi, read_image_fsinfo.partition -@@: - pop eax - add al, '0' - stosb - jnz @b - mov byte [edi-1], '/' - push esi edi - mov esi, bootpath1 - mov ecx, bootpath1.len - rep movsb - call read_image - test eax, eax - jz .yes - cmp eax, 6 - jz .yes - pop edi - push edi - mov esi, bootpath2 - mov ecx, bootpath2.len - rep movsb - call read_image - test eax, eax - jz .yes - cmp eax, 6 - jz .yes - pop edi esi - inc esi - cmp esi, [esp] - jbe .partition_loop - pop eax -.next_hd: - inc ebp - cmp ebp, 4 - jb .hd_loop - jmp no_sys_on_hd -.yes: - DEBUGF 1, "K : RD found: %s\n", read_image_fsinfo.name - pop edi esi eax - - call register_ramdisk - jmp yes_sys_on_hd -;----------------------------------------------------------------------------- -iglobal -align 4 -read_image_fsinfo: - dd 0 ; function: read - dq 0 ; offset: zero - dd 1474560 ; size - dd RAMDISK ; buffer -.name db '/hd' -.name_digit db '0' - db '/' -.partition: - rb 64 ; should be enough for '255/KOLIBRI/KOLIBRI.IMG' - -bootpath1 db 'KOLIBRI.IMG',0 -.len = $ - bootpath1 -bootpath2 db 'KOLIBRI/KOLIBRI.IMG',0 -.len = $ - bootpath2 -endg - -read_image: - mov ebx, read_image_fsinfo - pushad - call syscall_file_system_lfn_protected - popad - ret - -no_sys_on_hd: - DEBUGF 1, "K : RD not found\n" -.1: - ; test_to_format_ram_disk (need if not using ram disk) - cmp byte [BOOT.rd_load_from], RD_LOAD_FROM_FORMAT - jne not_format_ram_disk - ; format_ram_disk - mov edi, RAMDISK - mov ecx, 0x1080 - xor eax, eax -@@: - stosd - loop @b - - mov ecx, 0x58F7F - mov eax, 0xF6F6F6F6 -@@: - stosd - loop @b - - mov [RAMDISK+0x200], dword 0xFFFFF0 ; fat table - mov [RAMDISK+0x4200], dword 0xFFFFF0 - -not_format_ram_disk: -yes_sys_on_hd: diff --git a/kernel/branches/Kolibri-F/boot/ru.inc b/kernel/branches/Kolibri-F/boot/ru.inc deleted file mode 100644 index df4089c13..000000000 --- a/kernel/branches/Kolibri-F/boot/ru.inc +++ /dev/null @@ -1,102 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; Generated by RUFNT.EXE -; By BadBugsKiller (C) -; Modifyed by BadBugsKiller 12.01.2004 17:45 -; Шрифт уменьшен в размере и теперь состоит из 2-ух частей, -; содержащих только символы русского алфавита. -; символы в кодировке ASCII (ДОС'овская), кодовая страница 866. -RU_FNT1: - db 0x00, 0x00, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xFE, 0x62, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0x81, 0x00, 0x00 - db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x7E, 0x7E, 0x5A, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 - db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCF, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 - - db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 - db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03, 0x03, 0x00, 0x00 - db 0x00, 0x00, 0xF8, 0xF0, 0xB0, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xF3, 0xDB, 0xDB, 0xDB, 0xDB, 0xF3, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x26, 0x3E, 0x26, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x3E, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 - - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x02, 0x06, 0x7C, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0xC3, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0x54, 0x7C, 0x54, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 - -RU_FNT2: - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 - db 0x00, 0x00, 0x00, 0x3C, 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x03, 0x03, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB0, 0xB0, 0x3E, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC6, 0xC6, 0x7E, 0x36, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 - - db 0x6C, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC8, 0xF8, 0xC8, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xF8, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 - db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 - db 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0xCF, 0xCD, 0xEF, 0xEC, 0xFF, 0xDC, 0xDC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 - db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 diff --git a/kernel/branches/Kolibri-F/boot/shutdown.inc b/kernel/branches/Kolibri-F/boot/shutdown.inc deleted file mode 100644 index bd7f46dfe..000000000 --- a/kernel/branches/Kolibri-F/boot/shutdown.inc +++ /dev/null @@ -1,408 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;; Shutdown for Menuet ;; -;; ;; -;; Distributed under General Public License ;; -;; See file COPYING for details. ;; -;; Copyright 2003 Ville Turjanmaa ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -align 4 -system_shutdown: ; shut down the system - - cmp [BOOT.shutdown_type], SYSTEM_SHUTDOWN - jb @F - cmp [BOOT.shutdown_type], SYSTEM_RESTART - jbe .valid -@@: - ret -.valid: - call stop_all_services - -yes_shutdown_param: -; Shutdown other CPUs, if initialized - cmp [ap_initialized], 0 - jz .no_shutdown_cpus - mov edi, [LAPIC_BASE] - add edi, 300h - mov esi, smpt+4 - mov ebx, [cpu_count] - dec ebx -.shutdown_cpus_loop: - lodsd - push esi - xor esi, esi - inc esi - shl eax, 24 - mov [edi+10h], eax -; assert INIT IPI - mov dword [edi], 0C500h - call delay_ms -@@: - test dword [edi], 1000h - jnz @b -; deassert INIT IPI - mov dword [edi], 8500h - call delay_ms -@@: - test dword [edi], 1000h - jnz @b -; don't send STARTUP IPI: let other CPUs be in wait-for-startup state - pop esi - dec ebx - jnz .shutdown_cpus_loop -.no_shutdown_cpus: - - cli - call IRQ_mask_all - - movzx eax, [BOOT.shutdown_type] - cmp al, SYSTEM_RESTART - jne @F - -; load kernel.mnt to _CLEAN_ZONE - mov ebx, kernel_file_load - pushad - call syscall_file_system_lfn - popad -@@: - mov esi, OS_BASE+restart_code_start ; move kernel re-starter to 0x5000:0 - mov edi, OS_BASE+0x50000 - mov ecx, (restart_code_end - restart_code_start)/4 - rep movsd - - cmp [BOOT.shutdown_type], SYSTEM_SHUTDOWN - jne not_power_off - -; system_power_off - - mov ebx, [acpi_fadt_base] - test ebx, ebx - jz no_acpi - cmp [ebx+ACPI_TABLE.Signature], 'FACP' - jne no_acpi - mov esi, [acpi_ssdt_base] ; first SSDT is DSDT - test esi, esi - jz no_acpi - cmp [esi+ACPI_TABLE.Signature], 'DSDT' - jne no_acpi - mov eax, [esi+ACPI_TABLE.Length] - sub eax, 36+4 - jbe no_acpi - add esi, 36 -.scan_dsdt: - cmp dword [esi], '_S5_' - jnz .scan_dsdt_cont - cmp byte [esi+4], 12h ; DefPackage opcode - jnz .scan_dsdt_cont - mov dl, [esi+6] - cmp dl, 4 ; _S5_ package must contain 4 bytes - ; ...in theory; in practice, VirtualBox has 2 bytes - ja .scan_dsdt_cont - cmp dl, 1 - jb .scan_dsdt_cont - lea esi, [esi+7] - xor ecx, ecx - cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx - jz @f - cmp byte [esi], 0xA - jnz no_acpi - inc esi - mov cl, [esi] -@@: - inc esi - cmp dl, 2 - jb @f - cmp byte [esi], 0 - jz @f - cmp byte [esi], 0xA - jnz no_acpi - inc esi - mov ch, [esi] -@@: - jmp do_acpi_power_off -.scan_dsdt_cont: - inc esi - dec eax - jnz .scan_dsdt - jmp no_acpi -do_acpi_power_off: - mov edx, [ebx+ACPI_FADT.SMI_CMD] - test edx, edx - jz .nosmi - mov al, [ebx+ACPI_FADT.ACPI_ENABLE] - out dx, al - mov edx, [ebx+ACPI_FADT.PM1a_CNT_BLK] -@@: - in ax, dx - test al, 1 - jz @b -.nosmi: - and cx, 0x0707 - shl cx, 2 - or cx, 0x2020 - mov edx, [ebx+ACPI_FADT.PM1a_CNT_BLK] - in ax, dx - and ax, 203h - or ah, cl - out dx, ax - mov edx, [ebx+ACPI_FADT.PM1b_CNT_BLK] - test edx, edx - jz @f - in ax, dx - and ax, 203h - or ah, ch - out dx, ax -@@: - jmp no_acpi - -not_power_off: - cmp [BOOT.shutdown_type], SYSTEM_REBOOT - jnz not_reboot - ; try to reboot via ACPI fixed features - mov ebx, [acpi_fadt_base] - test ebx, ebx - jz no_acpi - cmp [ebx+ACPI_TABLE.Signature], 'FACP' - jne no_acpi - cmp [ebx+ACPI_FADT.Length], ACPI_FADT.RESET_VALUE - jbe no_acpi - test [ebx+ACPI_FADT.Flags], 1 SHL 10 ; reset_reg_supported - jz no_acpi - cmp [ebx+ACPI_FADT.RESET_REG.ASID], ASID.SYSTEM_IO - jnz no_acpi - cmp [ebx+ACPI_FADT.RESET_REG.BitWidth], 8 - jnz no_acpi - cmp [ebx+ACPI_FADT.RESET_REG.BitOffset], 0 - jnz no_acpi - cmp [ebx+ACPI_FADT.RESET_REG.AccessSize], ACCESS_SIZE.BYTE - ja no_acpi - cmp [ebx+ACPI_FADT.RESET_REG.Address.hi], 0 - jnz no_acpi - ; 'enable' ACPI - mov edx, [ebx+ACPI_FADT.SMI_CMD] - test edx, edx - jz .nosmi - mov al, [ebx+ACPI_FADT.ACPI_ENABLE] - out dx, al - mov edx, [ebx+ACPI_FADT.PM1a_CNT_BLK] -@@: - in ax, dx - test al, 1 - jz @b -.nosmi: - - mov edx, [ebx+ACPI_FADT.RESET_REG.Address.lo] - movzx eax, [ebx+ACPI_FADT.RESET_VALUE] - out dx, al - jmp no_acpi - -not_reboot: -no_acpi: - call create_trampoline_pgmap - mov cr3, eax - jmp @F -org $-OS_BASE -@@: - -;disable paging - - mov eax, cr0 - and eax, 0x7FFFFFFF - mov cr0, eax - mov eax, cr3 - mov cr3, eax - - jmp 0x50000 - -align 4 -restart_code_start: -org 0x50000 - - cmp [BOOT_LO.shutdown_type], SYSTEM_RESTART - jne @F - - mov esi, _CLEAN_ZONE-OS_BASE - mov edi, 0x10000 - mov ecx, 0x31000/4 - cld - rep movsd -@@: - - xor ebx, ebx - xor edx, edx - xor ecx, ecx - xor esi, esi - xor edi, edi - xor ebp, ebp - lidt [.idt] - lgdt [.gdt] - jmp 8:@f -align 8 -.gdt: -; selector 0 - not used - dw 23 - dd .gdt - dw 0 -; selector 8 - code from 5000:0000 to 1000:FFFF - dw 0FFFFh - dw 0 - db 5 - db 10011011b - db 00000000b - db 0 -; selector 10h - data from 1000:0000 to 1000:FFFF - dw 0FFFFh - dw 0 - db 1 - db 10010011b - db 00000000b - db 0 -.idt: - dw 256*4 - dd 0 -org $ - 0x50000 -use16 -@@: - mov ax, 10h - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - mov eax, cr0 - and eax, not 80000001h - mov cr0, eax - jmp 0x5000:.real_mode - -align 4 -.real_mode: - -; setup stack - - mov ax, (TMP_STACK_TOP and 0xF0000) shr 4 - mov ss, ax - mov esp, TMP_STACK_TOP and 0xFFFF - -;remap IRQs - mov al, 0x11 - out 0x20, al - out 0xA0, al - - mov al, 0x08 - out 0x21, al - mov al, 0x70 - out 0xA1, al - - mov al, 0x04 - out 0x21, al - mov al, 0x02 - out 0xA1, al - - mov al, 0x01 - out 0x21, al - out 0xA1, al - - mov al, 0xB8 - out 0x21, al - mov al, 0xBD - out 0xA1, al - - mov al, 00110100b - out 43h, al - mov al, 0xFF - out 40h, al - out 40h, al - - xor ax, ax - mov ds, ax - mov al, [BOOT_LO.shutdown_type] - cmp al, SYSTEM_RESTART - je .restart - - cmp al, SYSTEM_SHUTDOWN - je .APM_PowerOff - - mov word[0x0472], 0x1234 - jmp 0xF000:0xFFF0 - -.APM_PowerOff: - mov ax, 5304h - xor bx, bx - int 15h -;!!!!!!!!!!!!!!!!!!!!!!!! - mov ax, 0x5300 - xor bx, bx - int 0x15 - push ax - - mov ax, 0x5301 - xor bx, bx - int 0x15 - - mov ax, 0x5308 - mov bx, 1 - mov cx, bx - int 0x15 - - mov ax, 0x530E - xor bx, bx - pop cx - int 0x15 - - mov ax, 0x530D - mov bx, 1 - mov cx, bx - int 0x15 - - mov ax, 0x530F - mov bx, 1 - mov cx, bx - int 0x15 - - mov ax, 0x5307 - mov bx, 1 - mov cx, 3 - int 0x15 -;!!!!!!!!!!!!!!!!!!!!!!!! - jmp $ - -.restart: - -; (hint by Black_mirror) -; We must read data from keyboard port, -; because there may be situation when previous keyboard interrupt is lost -; (due to return to real mode and IRQ reprogramming) -; and next interrupt will not be generated (as keyboard waits for handling) - - mov cx, 16 -@@: - in al, 0x64 - test al, 1 - jz @F - in al, 0x60 - loop @B -@@: - -; bootloader interface - push 0x1000 - pop ds - push 0 - pop es - mov si, [es:BOOT_LO.kernel_restart] - mov ax, 'KL' - jmp 0x1000:0000 - -align 4 -org restart_code_start + $ -restart_code_end: - -org $+OS_BASE -use32 diff --git a/kernel/branches/Kolibri-F/bootbios.asm b/kernel/branches/Kolibri-F/bootbios.asm deleted file mode 100644 index 7039a6769..000000000 --- a/kernel/branches/Kolibri-F/bootbios.asm +++ /dev/null @@ -1,124 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; 16 BIT ENTRY FROM BOOTSECTOR ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -include 'macros.inc' -include 'struct.inc' -include 'lang.inc' -include 'encoding.inc' -include 'const.inc' - -os_code = code_l - tmp_gdt -PREBOOT_TIMEOUT = 5 ; seconds - -use16 - org 0x0 - jmp start_of_code - -if lang eq sp -include "kernelsp.inc" ; spanish kernel messages -else if lang eq et -version db 'Kolibri OS versioon 0.7.7.0+ ',13,10,13,10,0 -else -version db 'Kolibri OS version 0.7.7.0+ ',13,10,13,10,0 -end if - -include "boot/bootstr.inc" ; language-independent boot messages -include "boot/preboot.inc" - -if lang eq ge -include "boot/bootge.inc" ; german system boot messages -else if lang eq sp -include "boot/bootsp.inc" ; spanish system boot messages -else if lang eq ru -include "boot/bootru.inc" ; russian system boot messages -include "boot/ru.inc" ; Russian font -else if lang eq et -include "boot/bootet.inc" ; estonian system boot messages -include "boot/et.inc" ; Estonian font -else -include "boot/booten.inc" ; english system boot messages -end if - -include "boot/bootcode.inc" ; 16 bit system boot code -include "bus/pci/pci16.inc" -include "detect/biosdisk.inc" - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; SWITCH TO 32 BIT PROTECTED MODE ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - -; CR0 Flags - Protected mode and Paging - - mov ecx, CR0_PE+CR0_AM - -; Enabling 32 bit protected mode - - sidt [cs:old_ints_h] - - cli ; disable all irqs - cld - mov al, 255 ; mask all irqs - out 0xa1, al - out 0x21, al - l.5: - in al, 0x64 ; Enable A20 - test al, 2 - jnz l.5 - mov al, 0xD1 - out 0x64, al - l.6: - in al, 0x64 - test al, 2 - jnz l.6 - mov al, 0xDF - out 0x60, al - l.7: - in al, 0x64 - test al, 2 - jnz l.7 - mov al, 0xFF - out 0x64, al - - lgdt [cs:tmp_gdt] ; Load GDT - mov eax, cr0 ; protected mode - or eax, ecx - and eax, 10011111b *65536*256 + 0xffffff ; caching enabled - mov cr0, eax - jmp pword os_code:B32 ; jmp to enable 32 bit mode - -align 8 -tmp_gdt: - - dw 23 - dd tmp_gdt+0x10000 - dw 0 -code_l: - dw 0xffff - dw 0x0000 - db 0x00 - dw 11011111b *256 +10011010b - db 0x00 - - dw 0xffff - dw 0x0000 - db 0x00 - dw 11011111b *256 +10010010b - db 0x00 - -include "data16.inc" - -if ~ lang eq sp -diff16 "end of bootcode",0,$+0x10000 -end if - -use32 -org $+0x10000 - -align 4 -B32: diff --git a/kernel/branches/Kolibri-F/bootloader/Tupfile.lua b/kernel/branches/Kolibri-F/bootloader/Tupfile.lua deleted file mode 100644 index 087b72253..000000000 --- a/kernel/branches/Kolibri-F/bootloader/Tupfile.lua +++ /dev/null @@ -1,3 +0,0 @@ -if tup.getconfig("NO_FASM") ~= "" then return end -tup.rule("echo lang fix " .. ((tup.getconfig("LANG") == "") and "en" or tup.getconfig("LANG")) .. " > %o", {"lang.inc"}) -tup.rule({"boot_fat12.asm", extra_inputs = {"lang.inc"}}, "fasm %f %o", "boot_fat12.bin") diff --git a/kernel/branches/Kolibri-F/bootloader/boot_fat12.asm b/kernel/branches/Kolibri-F/bootloader/boot_fat12.asm deleted file mode 100644 index 6ad4ef1d7..000000000 --- a/kernel/branches/Kolibri-F/bootloader/boot_fat12.asm +++ /dev/null @@ -1,304 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; FAT12 boot sector for Kolibri OS -; -; Copyright (C) Alex Nogueira Teixeira -; Copyright (C) Diamond -; Copyright (C) Dmitry Kartashov aka shurf -; -; Distributed under GPL, see file COPYING for details -; -; Version 1.0 - -include "lang.inc" - -lf = 0ah -cr = 0dh - -pos_read_tmp = 0700h ;position for temporary read -boot_program = 07c00h ;position for boot code -seg_read_kernel = 01000h ;segment to kernel read - - jmp start_program - nop - -; Boot Sector and BPB Structure -include 'floppy1440.inc' -;include 'floppy2880.inc' -;include 'floppy1680.inc' -;include 'floppy1743.inc' - -start_program: -; - cld ;clear direction flag for Phoenix BIOS, see next "lodsb" - xor ax, ax - cli - mov ss, ax - mov sp, boot_program - sti -; <\Efremenkov S.V.> - push ss - pop ds - - ; print loading string - mov si, loading+boot_program -loop_loading: - lodsb - or al, al - jz read_root_directory - mov ah, 0eh - mov bx, 7 - int 10h - jmp loop_loading - -read_root_directory: - push ss - pop es - - ; calculate some disk parameters - ; - beginning sector of RootDir - mov ax, word [BPB_FATSz16+boot_program] - xor cx, cx - mov cl, byte [BPB_NumFATs+boot_program] - mul cx - add ax, word [BPB_RsvdSecCnt+boot_program] - mov word [FirstRootDirSecNum+boot_program], ax ; 19 - mov si, ax - - ; - count of sectors in RootDir - mov bx, word [BPB_BytsPerSec+boot_program] - mov cl, 5 ; divide ax by 32 - shr bx, cl ; bx = directory entries per sector - mov ax, word [BPB_RootEntCnt+boot_program] - xor dx, dx - div bx - mov word [RootDirSecs+boot_program], ax ; 14 - - ; - data start - add si, ax ; add beginning sector of RootDir and count sectors in RootDir - mov word [data_start+boot_program], si ; 33 - ; reading root directory - ; al=count root dir sectrors !!!! TODO: al, max 255 sectors !!!! - mov ah, 2 ; read - push ax - - mov ax, word [FirstRootDirSecNum+boot_program] - call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) - pop ax - mov bx, pos_read_tmp ; es:bx read buffer - call read_sector - - mov si, bx ; read buffer address: es:si - mov ax, [RootDirSecs+boot_program] - mul word [BPB_BytsPerSec+boot_program] - add ax, si ; AX = end of root dir. in buffer pos_read_tmp - - ; find kernel file in root directory -loop_find_dir_entry: - push si - mov cx, 11 - mov di, kernel_name+boot_program - rep cmpsb ; compare es:si and es:di, cx bytes long - pop si - je found_kernel_file - add si, 32 ; next dir. entry - cmp si, ax ; end of directory - jb loop_find_dir_entry - -file_error_message: - mov si, error_message+boot_program - -loop_error_message: - lodsb - or al, al - jz freeze_pc - mov ah, 0eh - mov bx, 7 - int 10h - jmp loop_error_message - -freeze_pc: - jmp $ ; endless loop - - ; === KERNEL FOUND. LOADING... === - -found_kernel_file: - mov bp, [si+01ah] ; first cluster of kernel file - ; - mov [cluster1st+boot_program], bp ; starting cluster of kernel file - ; <\diamond> - - ; reading first FAT table - mov ax, word [BPB_RsvdSecCnt+boot_program] ; begin first FAT abs sector number - call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) - mov bx, pos_read_tmp ; es:bx read position - mov ah, 2 ; ah=2 (read) - mov al, byte [BPB_FATSz16+boot_program] ; FAT size in sectors (TODO: max 255 sectors) - call read_sector - jc file_error_message ; read error - - mov ax, seg_read_kernel - mov es, ax - xor bx, bx ; es:bx = 1000h:0000h - - - ; reading kernel file -loop_obtains_kernel_data: - ; read one cluster of file - call obtain_cluster - jc file_error_message ; read error - - ; add one cluster length to segment:offset - push bx - mov bx, es - mov ax, word [BPB_BytsPerSec+boot_program] ;\ - movsx cx, byte [BPB_SecPerClus+boot_program] ; | !!! TODO: !!! - mul cx ; | out this from loop !!! - shr ax, 4 ;/ - add bx, ax - mov es, bx - pop bx - - mov di, bp - shr di, 1 - pushf - add di, bp ; di = bp * 1.5 - add di, pos_read_tmp - mov ax, [di] ; read next entry from FAT-chain - popf - jc move_4_right - and ax, 0fffh - jmp verify_end_sector -move_4_right: - mov cl, 4 - shr ax, cl -verify_end_sector: - cmp ax, 0ff8h ; last cluster - jae execute_kernel - mov bp, ax - jmp loop_obtains_kernel_data - -execute_kernel: - ; - mov ax, 'KL' - push 0 - pop ds - mov si, loader_block+boot_program - ; - push word seg_read_kernel - push word 0 - retf ; jmp far 1000:0000 - - -;------------------------------------------ - ; loading cluster from file to es:bx -obtain_cluster: - ; bp - cluster number to read - ; carry = 0 -> read OK - ; carry = 1 -> read ERROR - - ; print one dot - push bx - mov ax, 0e2eh ; ah=0eh (teletype), al='.' - xor bh, bh - int 10h - pop bx - -writesec: - ; convert cluster number to sector number - mov ax, bp ; data cluster to read - sub ax, 2 - xor dx, dx - mov dl, byte [BPB_SecPerClus+boot_program] - mul dx - add ax, word [data_start+boot_program] - - call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) -patchhere: - mov ah, 2 ; ah=2 (read) - mov al, byte [BPB_SecPerClus+boot_program] ; al=(one cluster) - call read_sector - retn -;------------------------------------------ - -;------------------------------------------ - ; read sector from disk -read_sector: - push bp - mov bp, 20 ; try 20 times -newread: - dec bp - jz file_error_message - push ax bx cx dx - int 13h - pop dx cx bx ax - jc newread - pop bp - retn -;------------------------------------------ - ; convert abs. sector number (AX) to BIOS T:H:S - ; sector number = (abs.sector%BPB_SecPerTrk)+1 - ; pre.track number = (abs.sector/BPB_SecPerTrk) - ; head number = pre.track number%BPB_NumHeads - ; track number = pre.track number/BPB_NumHeads - ; Return: cl - sector number - ; ch - track number - ; dl - drive number (0 = a:) - ; dh - head number -conv_abs_to_THS: - push bx - mov bx, word [BPB_SecPerTrk+boot_program] - xor dx, dx - div bx - inc dx - mov cl, dl ; cl = sector number - mov bx, word [BPB_NumHeads+boot_program] - xor dx, dx - div bx - ; !!!!!!! ax = track number, dx = head number - mov ch, al ; ch=track number - xchg dh, dl ; dh=head number - mov dl, 0 ; dl=0 (drive 0 (a:)) - pop bx - retn -;------------------------------------------ - -if lang eq sp -loading db cr,lf,'Iniciando el sistema ',00h -else -loading db cr,lf,'Starting system ',00h -end if -error_message db 13,10 -kernel_name db 'KERNEL MNT ?',cr,lf,00h -FirstRootDirSecNum dw ? -RootDirSecs dw ? -data_start dw ? - -; -write1st: - push cs - pop ds - mov byte [patchhere+1+boot_program], 3 ; change ah=2 to ah=3 - mov bp, [cluster1st+boot_program] - push 1000h - pop es - xor bx, bx - call writesec - mov byte [patchhere+1+boot_program], 2 ; change back ah=3 to ah=2 - retf -cluster1st dw ? -loader_block: - db 1 - dw 0 - dw write1st+boot_program - dw 0 -; <\diamond> - -times 0x1fe-$ db 00h - - db 55h,0aah ;boot signature diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/Tupfile.lua b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/Tupfile.lua deleted file mode 100644 index 1f704dfbf..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/Tupfile.lua +++ /dev/null @@ -1,2 +0,0 @@ -if tup.getconfig("NO_FASM") ~= "" then return end -tup.rule("kordldr.win.asm", "fasm %f %o", "kordldr.win.bin") diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/build.bat b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/build.bat deleted file mode 100644 index 5419e0d68..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/build.bat +++ /dev/null @@ -1,2 +0,0 @@ -@fasm -m 65535 kordldr.win.asm kordldr.win -@pause \ No newline at end of file diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/fat.inc b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/fat.inc deleted file mode 100644 index 3f4ccda09..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/fat.inc +++ /dev/null @@ -1,509 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -; in: ss:bp = 0:dat -; in: es:bx = address to load file -; in: ds:si -> ASCIIZ name -; in: cx = limit in sectors -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file has been loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) -load_file_fat: - mov eax, [bp + root_clus - dat] - mov [bp + cur_obj - dat], root_string - push es - push bx - push cx -.parse_dir_loop: -; convert name to FAT name - push [bp + cur_obj - dat] - push ax - mov [bp + cur_obj - dat], si - push ss - pop es -; convert ASCIIZ filename to FAT name - mov di, fat_filename - push di - mov cx, 8+3 - mov al, ' ' - rep stosb - pop di - mov cl, 8 ; 8 symbols per name - mov bl, 1 -.nameloop: - lodsb - test al, al - jz .namedone - cmp al, '/' - jz .namedone - cmp al, '.' - jz .namedot - dec cx - js .badname - cmp al, 'a' - jb @f - cmp al, 'z' - ja @f - sub al, 'a'-'A' -@@: - stosb - jmp .nameloop -.namedot: - inc bx - jp .badname - add di, cx - mov cl, 3 - jmp .nameloop -.badname: - mov si, badname_msg - jmp find_error_si -.namedone: -; scan directory - pop ax ; eax = cluster of directory - ; high word of eax is preserved by operations above - push ds - push si -; read a folder sector-by-sector and scan -; first, try to use the cache - push ss - pop ds - mov bx, -2 - mov cx, [bp + rootcache_size - dat] - cmp [bp + root_clus - dat], eax - jz .lookcache_root - mov di, foldcache_mark - xor bx, bx - mov cx, [bp + cachelimit - dat] -@@: - lea si, [di+bx] - mov edx, dword [foldcache_clus+si-foldcache_mark+bx] - cmp edx, eax - jz .cacheok - test edx, edx - jz .cacheadd ; the cache has place for new entry - inc bx - inc bx - dec cx - js @b -; the folder is not present in the cache, so add it -; the cache is full; find the oldest entry and replace it with the new one - mov bx, -2 - mov dx, [bp + cachelimit - dat] -@@: - inc bx - inc bx - cmp word [di+bx], dx ; marks have values 0 through [cachelimit] - jnz @b -.cacheadd: - or word [di+bx], 0xFFFF ; very big value, it will be changed soon - and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet - lea si, [di+bx] - mov dword [foldcache_clus+si-foldcache_mark+bx], eax -.cacheok: -; update cache marks - mov dx, [di+bx] - mov cx, [foldcache_size+di-foldcache_mark+bx] - mov di, [bp + cachelimit - dat] - add di, di -.cacheupdate: - cmp [foldcache_mark+di], dx - adc [foldcache_mark+di], 0 - dec di - dec di - jns .cacheupdate - and [foldcache_mark+bx], 0 -; done, bx contains (position in cache)*2 -.lookcache_root: -; bx = (position in cache)*2 for non-root folders; bx = -2 for root folder - ;mov dx, bx - ;shl dx, 8 - ;add dx, 0x9200 - lea dx, [bx + 0x92] - xchg dl, dh - mov ds, dx - mov si, fat_filename ; ss:si -> filename in FAT style - call fat_scan_for_filename - jz .lookup_done -; cache miss, read folder data from disk -; we are reading parent directory, it can result in disk read errors; restore [cur_obj] - mov di, sp - mov bx, [bp + cur_obj - dat] - xchg bx, [ss:di+4] - mov [bp + cur_obj - dat], bx - mov bx, cx - add bx, 0xF - shr bx, 4 - shl cx, 5 - mov di, cx ; es:di -> free space in cache entry -; external loop: scan clusters -.folder_next_cluster: -; internal loop: scan sectors in cluster - movzx ecx, byte [ss:0x320D] ; BPB_SecPerClus - push eax -; FAT12/16 root - special handling - test eax, eax - jnz .folder_notroot - mov cx, [ss:0x3211] ; BPB_RootEntCnt - mov dx, cx - add cx, 0xF - rcr cx, 1 - shr cx, 3 - mov eax, [bp + root_start - dat] - jmp .folder_next_sector -.folder_notroot: - mul ecx - add eax, [bp + data_start - dat] -.folder_next_sector: - sub dx, 0x10 -; skip first bx sectors - dec bx - jns .folder_skip_sector - push cx - push es di - push 0x8000 - pop es - xor bx, bx - mov cx, 1 - push es - call read - jc ..found_disk_error -; copy data to the cache... - pop ds - pop di es - cmp di, 0x2000 ; ...if there is free space, of course - jae @f - pusha - mov cx, 0x100 - xor si, si - rep movsw - mov di, es - shr di, 8 - cmp di, 0x90 - jz .update_rootcache_size - add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache - jmp .updated_cachesize -.update_rootcache_size: - mov cl, 0x10 - cmp cx, dx - jb @f - mov cx, dx -@@: - add [bp + rootcache_size - dat], cx -.updated_cachesize: - popa -@@: - push es - mov cl, 0x10 ; ch=0 at this point - cmp cx, dx - jb @f - mov cx, dx -@@: - call fat_scan_for_filename - pop es - pop cx - jz .lookup_done_pop -.folder_skip_sector: - inc eax - loop .folder_next_sector - pop eax ; eax = current cluster - test eax, eax - jz @f - call [bp + get_next_cluster_ptr - dat] - jc .folder_next_cluster -@@: - stc - push eax -.lookup_done_pop: - pop eax -.lookup_done: - pop si -; CF=1 <=> failed - jnc .found - pop ds - pop [bp + cur_obj - dat] - mov si, error_not_found - jmp find_error_si -.found: - mov eax, [di+20-2] - mov edx, [di+28] - mov ax, [di+26] ; get cluster - test byte [di+11], 10h ; directory? - pop ds - pop [bp + cur_obj - dat] ; forget old [cur_obj] - jz .regular_file - cmp byte [si-1], 0 - jnz .parse_dir_loop -..directory_error: - mov si, directory_string - jmp find_error_si -.regular_file: - cmp byte [si-1], 0 - jz @f -..notdir_error: - mov si, notdir_string - jmp find_error_si -@@: -; ok, we have found a regular file and the caller requested it -; parse FAT chunk - push ss - pop es - push ss - pop ds - mov di, 0x4005 - mov byte [di-5], 1 ; non-resident attribute - mov dword [di-4], 1 - stosd - pop cx - push cx -.parsefat: - call [bp + get_next_cluster_ptr - dat] - jnc .done - mov esi, [di-8] - add esi, [di-4] - cmp eax, esi - jz .contc - mov dword [di], 1 - scasd - stosd - jmp @f -.contc: - inc dword [di-8] -@@: - sub cl, [0x320D] - sbb ch, 0 - ja .parsefat -.done: - xor eax, eax - stosd - mov si, 0x4000 -load_file_common_end: - xor ecx, ecx - pop cx - pop bx - pop es - mov [bp + filesize - dat], edx - mov [bp + sectors_read - dat], ecx - add edx, 0x1FF - shr edx, 9 - mov [bp + filesize_sectors - dat], edx - cmp edx, ecx - seta al - mov ah, 0 - push ax - call read_file_chunk -continue_load_common_end: - mov [bp + cur_chunk_ptr - dat], si - pop bx - mov ax, word [bp + filesize - dat] - mov dx, word [bp + filesize+2 - dat] - jnc @f - mov bl, 3 ; read error -@@: - ret - -continue_load_file: -; es:bx -> buffer for output, ecx = cx = number of sectors - mov si, [bp + cur_chunk_ptr - dat] - push ecx - add ecx, [bp + sectors_read - dat] - mov [bp + sectors_read - dat], ecx - cmp [bp + filesize_sectors - dat], ecx - pop ecx - seta al - mov ah, 0 - push ax - push continue_load_common_end - push ss - pop ds - cmp [bp + cur_chunk_resident - dat], ah - jnz .nonresident -.resident: - mov ax, word [bp + num_sectors - dat] - jmp read_file_chunk.resident.continue -.nonresident: - mov eax, [bp + cur_cluster - dat] - mov edx, [bp + num_sectors - dat] - add eax, [bp + cur_delta - dat] - jmp read_file_chunk.nonresident.continue - -fat_scan_for_filename: -; in: ss:si -> 11-bytes FAT name -; in: ds:0 -> part of directory data -; in: cx = number of entries -; out: if found: CF=0, ZF=1, es:di -> directory entry -; out: if not found, but continue required: CF=1 and ZF=0 -; out: if not found and zero item reached: CF=1 and ZF=1 - push ds - pop es - xor di, di - push cx - jcxz .noent -.loop: - cmp byte [di], 0 - jz .notfound - test byte [di+11], 8 ; volume label? - jnz .cont ; ignore volume labels - pusha - mov cx, 11 - repz cmps byte [ss:si], byte [es:di] - popa - jz .done -.cont: - add di, 0x20 - loop .loop -.noent: - inc cx ; clear ZF flag -.notfound: - stc -.done: - pop cx - ret - -fat12_get_next_cluster: -; in: ax = cluster (high word of eax is zero) -; out: if there is next cluster: CF=1, ax = next cluster -; out: if there is no next cluster: CF=0 - push si - push ds - push 0x6000 - pop ds - mov si, ax - shr si, 1 - add si, ax - test al, 1 - lodsw - jz @f - shr ax, 4 -@@: - and ax, 0xFFF - cmp ax, 0xFF7 - pop ds si - ret - -fat16_get_next_cluster: -; in: ax = cluster (high word of eax is zero) -; out: if there is next cluster: CF=1, ax = next cluster -; out: if there is no next cluster: CF=0 -; each sector contains 200h bytes = 100h FAT entries -; so ah = # of sector, al = offset in sector - push si - mov si, ax - shr si, 8 -; calculate segment for this sector of FAT table -; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si) -; segment = 6000 + 20*si, offset = 0 - push es - push si - shl si, 5 - add si, 0x6000 - mov es, si - pop si - cmp byte [ss:0x3400+si], 0 ; sector already loaded? - jnz .noread -; load corresponding sector, try all FATs if disk read error detected - pusha - movzx di, byte [ss:0x3210] ; BPB_NumFATs - xor bx, bx - mov ax, [ss:0x320E] ; BPB_RsvdSecCnt - xor dx, dx - add ax, si - adc dx, bx -@@: - push es - push dx ax - pop eax - mov cx, 1 ; read 1 sector - call read - pop es - jnc @f - add ax, [ss:0x3216] ; BPB_FATSz16 - adc dx, bx - dec di - jnz @b -..found_disk_error: - mov si, disk_error_msg - jmp find_error_si -@@: - popa -.noread: - mov si, ax - and si, 0xFF - add si, si - mov ax, [es:si] - pop es - cmp ax, 0xFFF7 - pop si - ret - -fat32_get_next_cluster: -; in: eax = cluster -; out: if there is next cluster: CF=1, eax = next cluster -; out: if there is no next cluster: CF=0 - push di - push ax - shr eax, 7 -; eax = FAT sector number; look in cache - push si - mov si, cache1head - call cache_lookup - pop si - jnc .noread -; read FAT, try all FATs if disk read error detected - push es - pushad - movzx edx, word [ss:0x320E] ; BPB_RsvdSecCnt - add eax, edx - movzx si, byte [ss:0x3210] ; BPB_NumFATs -@@: - lea cx, [di - 0x3400 + (0x6000 shr (9-3))] - shl cx, 9-3 - mov es, cx - xor bx, bx - mov cx, 1 - call read - jnc @f - add eax, [ss:0x3224] ; BPB_FATSz32 - dec si - jnz @b - jmp ..found_disk_error -@@: - popad - pop es -.noread: -; get requested item - lea ax, [di - 0x3400 + (0x6000 shr (9-3))] - pop di - and di, 0x7F - shl di, 2 - shl ax, 9-3 - push ds - mov ds, ax - and byte [di+3], 0x0F - mov eax, [di] - pop ds - pop di - ;and eax, 0x0FFFFFFF - cmp eax, 0x0FFFFFF7 - ret diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/kordldr.win.asm b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/kordldr.win.asm deleted file mode 100644 index 460e3b7c3..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/kordldr.win.asm +++ /dev/null @@ -1,924 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -; KordOS bootloader, based on mtldr, KolibriOS bootloader, by diamond -; It is used when main bootloader is Windows loader. - -; this code is loaded: -; NT/2k/XP: by ntldr to 0D00:0000 -; 9x: by io.sys from config.sys to xxxx:0100 -; Vista: by bootmgr to 0000:7C00 - format binary - use16 - -; in any case, we relocate this code to 0000:0600 - org 0x600 -; entry point for 9x and Vista booting - call @f - db 'NTFS' -@@: - pop si - sub si, 3 - cmp si, 100h - jnz boot_vista - mov si, load_question + 100h - 600h - call out_string -; mov si, answer + 100h - 0600h ; already is -xxy: - mov ah, 0 - int 16h - or al, 20h - mov [si], al - cmp al, 'y' - jz xxz - cmp al, 'n' - jnz xxy -; continue load Windows -; call out_string -; ret -out_string: - push bx -@@: - lodsb - test al, al - jz @f - mov ah, 0Eh - mov bx, 7 - int 10h - jmp @b -@@: - pop bx - ret -xxz: -; boot KordOS - call out_string -; 9x bootloader has already hooked some interrupts; to correctly remove all DOS handlers, -; issue int 19h (reboot interrupt) and trace its DOS handler until original BIOS handler is reached - xor di, di - mov ds, di - mov word [di+4], new01handler + 100h - 600h - mov [di+6], cs - pushf - pop ax - or ah, 1 - push ax - popf -; we cannot issue INT 19h directly, because INT command clears TF -; int 19h ; don't issue it directly, because INT command clears TF -; so instead we use direct call -; pushf ; there will be no IRET - call far [di + 19h*4] -xxt: - xor di, di - mov ds, di - cmp word [di + 8*4+2], 0F000h - jz @f - les bx, [di + 8*4] - mov eax, [es:bx+1] - mov [di + 8*4], eax -@@: - mov si, 100h -boot_vista: -; relocate cs:si -> 0000:0600 - push cs - pop ds - xor ax, ax - mov es, ax - mov di, 0x600 - mov cx, 2000h/2 - rep movsw - jmp 0:real_entry - -load_question db 'Load KordOS? [y/n]: ',0 -answer db ? - db 13,10,0 - -new01handler: -; [sp]=ip, [sp+2]=cs, [sp+4]=flags - push bp - mov bp, sp - push ds - lds bp, [bp+2] - cmp word [ds:bp], 19cdh - jz xxt - pop ds - pop bp - iret - -; read from hard disk -; in: eax = absolute sector -; cx = number of sectors -; es:bx -> buffer -; out: CF=1 if error -read: - pushad - add eax, [bp + partition_start - dat] - cmp [bp + use_lba - dat], 0 - jz .chs -; LBA read - push ds -.lbado: - push ax - push cx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F -@@: -; create disk address packet on the stack -; dq starting LBA - push 0 - push 0 - push eax -; dd buffer - push es - push bx -; dw number of blocks to transfer (no more than 0x7F) - push cx -; dw packet size in bytes - push 10h -; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [bp + boot_drive - dat] - mov ah, 42h - int 13h - jc .disk_error_lba - add sp, 10h ; restore stack -; increase current sector & buffer; decrease number of sectors - movzx esi, cx - mov ax, es - shl cx, 5 - add ax, cx - mov es, ax - pop cx - pop ax - add eax, esi - sub cx, si - jnz .lbado - pop ds - popad - ret -.disk_error_lba: - add sp, 14h - pop ds - popad - stc - ret - -.chs: - pusha - pop edi ; loword(edi) = di, hiword(edi) = si - push bx - -; eax / (SectorsPerTrack) -> eax, remainder bx - movzx esi, [bp + sectors - dat] - xor edx, edx - div esi - mov bx, dx ; bx = sector-1 - -; eax -> dx:ax - push eax - pop ax - pop dx -; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx - div [bp + heads - dat] - -; number of sectors: read no more than to end of track - sub si, bx - cmp cx, si - jbe @f - mov cx, si -@@: - - inc bx -; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector -; convert to int13 format - movzx edi, cx - mov dh, dl - mov dl, [bp + boot_drive - dat] - shl ah, 6 - mov ch, al - mov al, cl - mov cl, bl - or cl, ah - pop bx - mov si, 3 - mov ah, 2 -@@: - push ax - int 13h - jnc @f - xor ax, ax - int 13h ; reset drive - pop ax - dec si - jnz @b - add sp, 12 - popad - stc - ret -@@: - pop ax - mov ax, es - mov cx, di - shl cx, 5 - add ax, cx - mov es, ax - push edi - popa - add eax, edi - sub cx, di - jnz .chs - popad - ret - -disk_error2 db 'Fatal: cannot read partitions info: ' -disk_error_msg db 'disk read error',0 -disk_params_msg db 'Fatal: cannot get drive parameters',0 -start_msg db 2,' KordOS bootloader',13,10,0 -part_msg db 'looking at partition ' -part_char db '0' ; will be incremented before writing message - db ' ... ',0 -errfs_msg db 'unknown filesystem',13,10,0 -fatxx_msg db 'FATxx' -newline db 13,10,0 -ntfs_msg db 'NTFS',13,10,0 -error_msg db 'Error' -colon db ': ',0 -root_string db '\',0 -nomem_msg db 'No memory',0 -filesys_string db '(filesystem)',0 -directory_string db 'is a directory',0 -notdir_string db 'not a directory',0 - -; entry point for NT/2k/XP booting -; ntldr loads our code to 0D00:0000 and jumps to 0D00:0256 - repeat 600h + 256h - $ - db 1 ; any data can be here; 1 in ASCII is a nice face :) - end repeat -; cs=es=0D00, ds=07C0, ss=0 -; esi=edi=ebp=0, esp=7C00 - xor si, si - jmp boot_vista - -real_entry: -; ax = 0 - mov ds, ax - mov es, ax -; our stack is 4 Kb: memory range 2000-3000 - mov ss, ax - mov sp, 3000h - mov bp, dat - sti ; just for case -; say hi to user - mov si, start_msg - call out_string -; we are booting from hard disk identified by [boot_drive] - mov dl, [bp + boot_drive - dat] -; is LBA supported? - mov [bp + use_lba - dat], 0 - mov ah, 41h - mov bx, 55AAh - int 13h - jc .no_lba - cmp bx, 0AA55h - jnz .no_lba - test cl, 1 - jz .no_lba - inc [bp + use_lba - dat] - jmp disk_params_ok -.no_lba: -; get drive geometry - mov ah, 8 - mov dl, [bp + boot_drive - dat] - int 13h - jnc @f - mov si, disk_params_msg - call out_string - jmp $ -@@: - movzx ax, dh - inc ax - mov [bp + heads - dat], ax - and cx, 3Fh - mov [bp + sectors - dat], cx -disk_params_ok: -; determine size of cache for folders - int 12h ; ax = size of available base memory in Kb - sub ax, 94000h / 1024 - jc nomem - shr ax, 3 - mov [bp + cachelimit - dat], ax ; size of cache - 1 -; scan all partitions -new_partition_ex: - xor eax, eax ; read first sector of current disk area - mov [bp + extended_part_cur - dat], eax ; no extended partition yet - mov [bp + cur_partition_ofs - dat], 31BEh ; start from first partition - push es - mov cx, 1 - mov bx, 3000h - call read - pop es - jnc new_partition - mov si, disk_error2 - call out_string - jmp $ -new_partition: - mov bx, [bp + cur_partition_ofs - dat] - mov al, [bx+4] ; partition type - test al, al - jz next_partition - cmp al, 5 - jz @f - cmp al, 0xF - jnz not_extended -@@: -; extended partition - mov eax, [bx+8] ; partition start - add eax, [bp + extended_part_start - dat] - mov [bp + extended_part_cur - dat], eax -next_partition: - add [bp + cur_partition_ofs - dat], 10h - cmp [bp + cur_partition_ofs - dat], 31FEh - jb new_partition - mov eax, [bp + extended_part_cur - dat] - test eax, eax - jz partitions_done - cmp [bp + extended_part_start - dat], 0 - jnz @f - mov [bp + extended_part_start - dat], eax -@@: - mov [bp + extended_parent - dat], eax - mov [bp + partition_start - dat], eax - jmp new_partition_ex -partitions_done: - mov si, total_kaput - call out_string - jmp $ -not_extended: - mov eax, [bx+8] - add eax, [bp + extended_parent - dat] - mov [bp + partition_start - dat], eax -; try to load from current partition -; inform user - mov si, part_msg - inc [si + part_char - part_msg] - call out_string -; read bootsector - xor eax, eax - mov [bp + cur_obj - dat], filesys_string - push es - mov cx, 1 - mov bx, 3200h - call read - pop es - mov si, disk_error_msg - jc find_error_si - movzx si, byte [bx+13] - mov word [bp + sect_per_clust - dat], si - test si, si - jz unknown_fs - lea ax, [si-1] - test si, ax - jnz unknown_fs -; determine file system -; Number of bytes per sector == 0x200 (this loader assumes that physical sector size is 200h) - cmp word [bx+11], 0x200 - jnz unknown_fs -; is it NTFS? - cmp dword [bx+3], 'NTFS' - jnz not_ntfs - cmp byte [bx+16], bl - jz ntfs -not_ntfs: -; is it FAT? FAT12/FAT16/FAT32? -; get count of sectors to dword in cx:si - mov si, [bx+19] - xor cx, cx - test si, si - jnz @f - mov si, [bx+32] - mov cx, [bx+34] -@@: - xor eax, eax -; subtract size of system area - sub si, [bx+14] ; BPB_ResvdSecCnt - sbb cx, ax - mov ax, [bx+17] ; BPB_RootEntCnt - add ax, 0xF - rcr ax, 1 - shr ax, 3 - sub si, ax - sbb cx, 0 - push cx - push si - mov ax, word [bx+22] - test ax, ax - jnz @f - mov eax, [bx+36] -@@: - movzx ecx, byte [bx+16] - imul ecx, eax - pop eax - sub eax, ecx -; now eax = count of sectors in the data region - xor edx, edx - div [bp + sect_per_clust - dat] -; now eax = count of clusters in the data region - mov si, fatxx_msg - cmp eax, 0xFFF5 - jae test_fat32 -; test magic value in FAT bootsector - FAT12/16 bootsector has it at the offset +38 - cmp byte [bx+38], 0x29 - jnz not_fat - cmp ax, 0xFF5 - jae fat16 -fat12: - mov [bp + get_next_cluster_ptr - dat], fat12_get_next_cluster - mov di, cx ; BPB_NumFATs - mov ax, '12' - push ax ; save for secondary loader - mov word [si+3], ax - call out_string - movzx ecx, word [bx+22] ; BPB_FATSz16 -; FAT12: read entire FAT table (it is no more than 0x1000*3/2 = 0x1800 bytes) -.fatloop: -; if first copy is not readable, try to switch to other copies - push 0x6000 - pop es - xor bx, bx - movzx eax, word [0x320E] ; BPB_RsvdSecCnt - push cx - cmp cx, 12 - jb @f - mov cx, 12 -@@: - call read - pop cx - jnc fat1x_common - add eax, ecx ; switch to next copy of FAT - dec di - jnz .fatloop - mov si, disk_error_msg - jmp find_error_si -fat16: - mov [bp + get_next_cluster_ptr - dat], fat16_get_next_cluster - mov ax, '16' - push ax ; save for secondary loader - mov word [si+3], ax - call out_string -; FAT16: init FAT cache - no sectors loaded - mov di, 0x3400 - xor ax, ax - mov cx, 0x100/2 - rep stosw -fat1x_common: - mov bx, 0x3200 - movzx eax, word [bx+22] ; BPB_FATSz16 - xor esi, esi ; no root cluster - jmp fat_common -test_fat32: -; FAT32 bootsector has it at the offset +66 - cmp byte [bx+66], 0x29 - jnz not_fat - mov [bp + get_next_cluster_ptr - dat], fat32_get_next_cluster - mov ax, '32' - push ax ; save for secondary loader - mov word [si+3], ax - call out_string -; FAT32 - init cache for FAT table: no sectors loaded - lea si, [bp + cache1head - dat] - mov [si], si ; no sectors in cache: - mov [si+2], si ; 'prev' & 'next' links point to self - mov [bp + cache1end - dat], 3400h ; first free item = 3400h - mov [bp + cache1limit - dat], 3C00h - mov eax, [bx+36] ; BPB_FATSz32 - mov esi, [bx+44] ; BPB_RootClus - jmp fat_common -not_fat: -unknown_fs: - mov si, errfs_msg - call out_string - jmp next_partition -fat_common: - push ss - pop es - movzx edx, byte [bx+16] ; BPB_NumFATs - mul edx - mov [bp + root_start - dat], eax ; this is for FAT1x -; eax = total size of all FAT tables, in sectors - movzx ecx, word [bx+17] ; BPB_RootEntCnt - add ecx, 0xF - shr ecx, 4 - add eax, ecx - mov cx, word [bx+14] ; BPB_RsvdSecCnt - add [bp + root_start - dat], ecx ; this is for FAT1x - add eax, ecx -; cluster 2 begins from sector eax - movzx ebx, byte [bx+13] ; BPB_SecPerClus - sub eax, ebx - sub eax, ebx - mov [bp + data_start - dat], eax -; no clusters in folders cache - mov di, foldcache_clus - 2 - xor ax, ax - mov cx, 7*8/2 + 1 - rep stosw - mov [bp + root_clus - dat], esi -; load secondary loader - mov [bp + load_file_ptr - dat], load_file_fat -load_secondary: - push 0x1000 - pop es - xor bx, bx - mov si, kernel_name - mov cx, 0x30000 / 0x200 - call [bp + load_file_ptr - dat] -; say error if needed - mov si, error_too_big - dec bx - js @f - jz find_error_si - mov si, disk_error_msg - jmp find_error_si -@@: -; fill loader information and jump to secondary loader - mov al, 'h' ; boot device: hard drive - mov ah, [bp + boot_drive - dat] - sub ah, 80h ; boot device: identifier - pop bx ; restore file system ID ('12'/'16'/'32'/'nt') - mov si, callback - jmp 1000h:0000h - -nomem: - mov si, nomem_msg - call out_string - jmp $ - -ntfs: - push 'nt' ; save for secondary loader - mov si, ntfs_msg - call out_string - xor eax, eax - mov [bp + data_start - dat], eax - mov ecx, [bx+40h] ; frs_size - cmp cl, al - jg .1 - neg cl - inc ax - shl eax, cl - jmp .2 -.1: - mov eax, ecx - shl eax, 9 -.2: - mov [bp + frs_size - dat], ax -; standard value for frs_size is 0x400 bytes = 1 Kb, and it cannot be set different -; (at least with standard tools) -; we allow extra size, but no more than 0x1000 bytes = 4 Kb - mov si, invalid_volume_msg - cmp eax, 0x1000 - ja find_error_si -; must be multiple of sector size - test ax, 0x1FF - jnz find_error_si - shr ax, 9 - xchg cx, ax -; initialize cache - no data loaded - lea si, [bp + cache1head - dat] - mov [si], si - mov [si+2], si - mov word [si+4], 3400h ; first free item = 3400h - mov word [si+6], 3400h + 8*8 ; 8 items in this cache -; read first MFT record - description of MFT itself - mov [bp + cur_obj - dat], mft_string - mov eax, [bx+30h] ; mft_cluster - mul [bp + sect_per_clust - dat] - push 0x8000 - pop es - xor bx, bx - push es - call read - pop ds - call restore_usa -; scan for unnamed $DATA attribute - mov [bp + freeattr - dat], 4000h - mov ax, 80h - call load_attr - push ss - pop ds - mov si, nodata_string - jc find_error_si -; load secondary loader - mov [bp + load_file_ptr - dat], load_file_ntfs - jmp load_secondary - -find_error_si: - push si -find_error_sp: - cmp [bp + in_callback - dat], 0 - jnz error_in_callback - push ss - pop ds - push ss - pop es - mov si, error_msg - call out_string - mov si, [bp + cur_obj - dat] -@@: - lodsb - test al, al - jz @f - cmp al, '/' - jz @f - mov ah, 0Eh - mov bx, 7 - int 10h - jmp @b -@@: - mov si, colon - call out_string - pop si - call out_string - mov si, newline - call out_string - mov sp, 0x3000 - jmp next_partition -error_in_callback: -; return status: file not found, except for read errors - mov bx, 2 - cmp si, disk_error_msg - jnz @f - inc bx -@@: - mov ax, 0xFFFF - mov dx, ax - mov sp, 3000h - 6 - ret - -callback: -; in: ax = function number; only functions 1 and 2 are defined for now -; save caller's stack - mov dx, ss - mov cx, sp -; set our stack (required because we need ss=0) - xor si, si - mov ss, si - mov sp, 3000h - mov bp, dat - mov [bp + in_callback - dat], 1 - push dx - push cx -; set ds:si -> ASCIIZ name - lea si, [di+6] -; set cx = limit in sectors; 4Kb = 8 sectors - movzx ecx, word [di+4] - shl cx, 3 -; set es:bx = pointer to buffer - les bx, [di] -; call our function - stc ; unsupported function - dec ax - jz callback_readfile - dec ax - jnz callback_ret - call continue_load_file - jmp callback_ret_succ -callback_readfile: -; function 1: read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error -; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call [bp + load_file_ptr - dat] -callback_ret_succ: - clc -callback_ret: -; restore caller's stack - pop cx - pop ss - mov sp, cx -; return to caller - retf - -read_file_chunk.resident: -; auxiliary label for read_file_chunk procedure - mov di, bx - lodsw -read_file_chunk.resident.continue: - mov dx, ax - add dx, 0x1FF - shr dx, 9 - cmp dx, cx - jbe @f - mov ax, cx - shl ax, 9 -@@: - xchg ax, cx - rep movsb - xchg ax, cx - clc ; no disk error if no disk requests - mov word [bp + num_sectors - dat], ax - ret - -read_file_chunk: -; in: ds:si -> file chunk -; in: es:bx -> buffer for output -; in: ecx = maximum number of sectors to read (high word must be 0) -; out: CF=1 <=> disk read error - lodsb - mov [bp + cur_chunk_resident - dat], al - test al, al - jz .resident -; normal case: load (non-resident) attribute from disk -.read_block: - lodsd - xchg eax, edx - test edx, edx - jz .ret - lodsd -; eax = start cluster, edx = number of clusters, cx = limit in sectors - imul eax, [bp + sect_per_clust - dat] - add eax, [bp + data_start - dat] - mov [bp + cur_cluster - dat], eax - imul edx, [bp + sect_per_clust - dat] - mov [bp + num_sectors - dat], edx - and [bp + cur_delta - dat], 0 -.nonresident.continue: - cmp edx, ecx - jb @f - mov edx, ecx -@@: - test dx, dx - jz .read_block - add [bp + cur_delta - dat], edx - sub [bp + num_sectors - dat], edx - sub ecx, edx - push cx - mov cx, dx - call read - pop cx - jc .ret - test cx, cx - jnz .read_block -.ret: - ret - -cache_lookup: -; in: eax = value to look, si = pointer to cache structure -; out: di->cache entry; CF=1 <=> the value was not found - push ds bx - push ss - pop ds - mov di, [si+2] -.look: - cmp di, si - jz .not_in_cache - cmp eax, [di+4] - jz .in_cache - mov di, [di+2] - jmp .look -.not_in_cache: -; cache miss -; cache is full? - mov di, [si+4] - cmp di, [si+6] - jnz .cache_not_full -; yes, delete the oldest entry - mov di, [si] - mov bx, [di] - mov [si], bx - push word [di+2] - pop word [bx+2] - jmp .cache_append -.cache_not_full: -; no, allocate new item - add word [si+4], 8 -.cache_append: - mov [di+4], eax - stc - jmp @f -.in_cache: -; delete this sector from the list - push si - mov si, [di] - mov bx, [di+2] - mov [si+2], bx - mov [bx], si - pop si -@@: -; add new sector to the end of list - mov bx, di - xchg bx, [si+2] - push word [bx] - pop word [di] - mov [bx], di - mov [di+2], bx - pop bx ds - ret - -include 'fat.inc' -include 'ntfs.inc' - -total_kaput db 13,10,'Fatal error: cannot load the secondary loader',0 -error_too_big db 'file is too big',0 -nodata_string db '$DATA ' -error_not_found db 'not found',0 -noindex_string db '$INDEX_ROOT not found',0 -badname_msg db 'bad name for FAT',0 -invalid_volume_msg db 'invalid volume',0 -mft_string db '$MFT',0 -fragmented_string db 'too fragmented file',0 -invalid_read_request_string db 'cannot read attribute',0 - -kernel_name db 'kernel.mnt',0 - -align 4 -dat: - -extended_part_start dd 0 ; start sector for main extended partition -extended_part_cur dd ? ; start sector for current extended child -extended_parent dd 0 ; start sector for current extended parent -partition_start dd 0 ; start sector for current logical disk -cur_partition_ofs dw ? ; offset in MBR data for current partition -sect_per_clust dd 0 -; change this variable if you want to boot from other physical drive -boot_drive db 80h -in_callback db 0 - -; uninitialized data -use_lba db ? -cur_chunk_resident db ? -align 2 -heads dw ? -sectors dw ? -cache1head rw 2 -cache1end dw ? -cache1limit dw ? -data_start dd ? -cachelimit dw ? -load_file_ptr dw ? -cur_obj dw ? -missing_slash dw ? -root_clus dd ? -root_start dd ? -get_next_cluster_ptr dw ? -frs_size dw ? -freeattr dw ? -index_root dw ? -index_alloc dw ? -cur_index_seg dw ? -cur_index_cache dw ? -filesize dd ? -filesize_sectors dd ? -cur_cluster dd ? -cur_delta dd ? -num_sectors dd ? -sectors_read dd ? -cur_chunk_ptr dw ? - -rootcache_size dw ? ; must be immediately before foldcache_clus -if $-dat >= 0x80 -warning: - unoptimal data displacement! -end if -foldcache_clus rd 7 -foldcache_mark rw 7 -foldcache_size rw 7 -fat_filename rb 11 - -if $ > 2000h -error: - file is too big -end if - -; for NT/2k/XP, file must be 16 sectors = 0x2000 bytes long -repeat 0x2600 - $ - db 2 ; any data can be here; 2 is another nice face in ASCII :) -end repeat diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/kordldr.win.txt b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/kordldr.win.txt deleted file mode 100644 index 3affd3f39..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/kordldr.win.txt +++ /dev/null @@ -1,391 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - Нет повести печальнее на свете, - Чем повесть о заклинившем Reset'е... - -Загрузчик для FAT- и NTFS-томов для случаев, когда основной бутсектор загружает -Windows, для носителей с размером сектора 512 байт. - -===================================================================== - -Требования для работы: -1) Все используемые файлы должны быть читабельны. -2) Минимальный процессор - 80386. -3) В системе должно быть как минимум 592K свободной базовой памяти. -4) Пути к используемым файлам не должны содержать символических ссылок NTFS - (жёсткие ссылки допускаются). -5) Используемые файлы не должны быть сжатыми или разреженными файлами - (актуально для NTFS, для FAT выполнено автоматически). - -===================================================================== - -Документация в тему (ссылки проверялись на валидность 08.08.2008): - официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx - в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf - русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip - спецификация NTFS: file://C:/windows/system32/drivers/ntfs.sys - и file://C:/ntldr либо file://C:/bootmgr - неофициальное описание NTFS: http://sourceforge.net/project/showfiles.php?group_id=13956&package_id=16543 - официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf - то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf - описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html - официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf - официальное описание bcdedit для Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcdedit_reff.mspx - официальное описание работы с базой данных загрузчика Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcd.mspx - формат таблицы разделов жёсткого диска: http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/prork/prcb_dis_qxql.mspx - -===================================================================== - -Схема используемой памяти: - 600-2000 код загрузчика (и данные) - 2000-3000 стек - 3000-3200 сектор MBR - 3200-3400 бутсектор логического диска - 3400-3C00 информация о кэше для таблиц FAT16/FAT32: - для FAT16 - массив на 0x100 байт, каждый байт равен - 0 или 1 в зависимости от того, загружен ли - соответствующий сектор таблицы FAT16; - для FAT32 - 100h входов по 8 байт: 4 байта - (две ссылки - вперёд и назад) для организации L2-списка - всех прочитанных секторов в порядке возрастания - последнего времени использования + 4 байта для номера - сектора; при переполнении кэша выкидывается элемент из - головы списка, то есть тот, к которому дольше всех - не было обращений - 3400-3440 информация о кэше для файловых записей NTFS в - таком же формате, как и кэш для FAT32, но на 8 входов - 3480-34C0 заголовки для кэшей записей индекса NTFS - 3500-3D00 информация о кэшах записей индекса NTFS: с каждой - файловой записью связан свой кэш для - соответствующего индекса - 4000-8000 место для информации об атрибутах для NTFS - 60000-80000 таблица FAT12 / место под таблицу FAT16 / - кэш для таблицы FAT32 / кэш для структур NTFS - 80000-90000 текущий рассматриваемый кластер - 90000-92000 FAT: кэш для корневой папки - 92000-... FAT: кэш для некорневых папок (каждой папке отводится - 2000h байт = 100h входов, одновременно в кэше - может находиться не более 7 папок; - точный размер определяется размером доступной - физической памяти - как правило, непосредственно - перед A0000 размещается EBDA, Extended BIOS Data Area) - -===================================================================== - -Основной процесс загрузки. -0a. Загрузка из-под DOS и Win9x: установка kordldr.win осуществляется - размещением команды install=c:\kordldr.win в первой строке config.sys; - при этом основной загрузчик системы загружает kordldr.win как обычный - com-файл, в какой-то сегмент по смещению 100h и передаёт управление - в начало кода (xxxx:0100). -0б. Загрузка из-под WinNT/2000/XP: установка kordldr.win осуществляется - добавлением строки наподобие c:\kordldr.win="KordOS" в секцию - [operating systems] файла boot.ini; если загружаемый файл имеет размер - не менее 8 Кб (0x2000 байт) и по смещению 3 содержит сигнатуру 'NTFS' - (в случае kordldr.win так и есть), то основной загрузчик каждой из - этих систем загружает kordldr.win по адресу 0D00:0000 и передаёт - управление на адрес 0D00:0256. -0в. Загрузка из-под Vista: установка kordldr.win осуществляется манипуляциями - с базой данных основного загрузчика через bcdedit и подробно описана в - инструкции к kordldr.win; основной загрузчик загружает целиком - kordldr.win по адресу 0000:7C00 и передаёт управление в начало кода. -1. При загрузке из-под DOS/9x основной загрузчик не ожидает, что загруженная - им программа окажется в свою очередь загрузчиком, и в этом случае - kordldr.win оказывается в условиях, когда основной загрузчик уже - установил какое-то окружение, в частности, перехватил некоторые - прерывания. Поэтому перед остальными действиями загрузчик должен - восстановить систему в начальное состояние. (При загрузке под - NT-линейкой такой проблемы не возникает, поскольку там основной - загрузчик ничего в системе не трогает.) Поэтому перед собственно - инициализацией KordOS при работе из-под DOS/9x производятся - дополнительные действия. Первым делом kordldr проверяет, какой из - случаев 0а и 0в имеет место (случай 0б отличается тем, что передаёт - управление не на начало кода): определяет значение ip (команда call - помещает в стек адрес следующей после call инструкции, команда pop si - выталкивает его в регистр si), и если оно равно 100h, то kordldr - загружен как com-файл из-под DOS/9x. Тогда он спрашивает подтверждения - у пользователя (поскольку в этой схеме kordldr загружается всегда, - он должен оставить возможность продолжить загрузку DOS/9x). Если - пользователь хочет продолжить обычную загрузку, kordldr завершается. - Иначе используется тот факт, что при выдаче прерывания перезагрузки - int 19h система предварительно снимает все свои перехваты BIOSовских - прерываний, а потом в свою очередь выдаёт int 19h уже BIOSу. Так что - kordldr устанавливает свой обработчик трассировочного прерывания, - устанавливает флаг трассировки и передаёт управление DOSовскому - обработчику. Обработчик трассировочного прерывания ничего не делает - до тех пор, пока следующей инструкцией не оказывается int 19h, а - в этот момент отбирает управление и продолжает загрузку KordOS. - При этом BIOSовские обработчики восстановлены за исключением, - быть может, прерывания таймера int 8, которое, возможно, восстановлено - до команды jmp far на оригинальный обработчик. В последнем случае его - нужно восстановить явно. -2. Загрузчик перемещает свой код на адрес 0000:0600. -3. (метка real_entry) Загрузчик устанавливает сегментные регистры ds = es = 0, - настраивает стек ss:sp = 0000:3000 и устанавливает bp так, чтобы - все данные можно было адресовать через [bp+N] с однобайтовым N - (в дальнейшем они так и будут адресоваться для освобождения ds и - экономии на размере кода). Разрешает прерывания на случай, если - они были запрещены. Выдаёт сообщение о начале загрузки, начинающееся - с весёлой рожицы (символ с ASCII-кодом 2). -4. Определяет характеристики жёсткого диска, указанного в качестве - загрузочного: проверяет поддержку LBA (функция 41h прерывания 13h), - если LBA не поддерживается, то определяет геометрию - число дорожек - и число секторов на дорожке (функция 8 прерывания 13h), эти параметры - нужны функции чтения с диска. -5. (метка new_partition_ex) Устраивает цикл по разделам жёсткого диска. - Цель цикла - для каждого логического диска попытаться загрузиться с - него (действия по загрузке с конкретного логического диска начинаются - с метки not_extended), при ошибке загрузки управление передаётся - назад этому циклу (метка next_partition), и поиск подходящего раздела - продолжается. На выходе заполняется одна переменная partition_start, - имеющая смысл начала текущего рассматриваемого логического диска, - но по ходу дела из-за приколов таблиц разделов используются ещё четыре - переменных. cur_partition_ofs - фактически счётчик цикла, формально - указатель на текущий вход в текущей загрузочной записи. Сама - загрузочная запись считывается в память начиная с адреса 3000h. - Три оставшихся нужны для правильной работы с расширенными разделами. - В каждой загрузочной записи помещается не более 4 записей о разделах. - Поэтому главной загрузочной записи, размещающейся в первом физическом - секторе диска, может не хватить, и обычно создаётся так называемый - расширенный раздел с расширенными загрузочными записями, формат - которых почти идентичен главной. Расширенный раздел может быть только - один, но в нём может быть много логических дисков и расширенных - загрузочных записей. Расширенные загрузочные записи организованы - в односвязный список, в каждой такой записи первый вход указывает - на соответствующий логический диск, а второй - на следующую расширенную - загрузочную запись. - При этом в главной загрузочной записи все адреса разделов являются - абсолютными номерами секторов. В расширенных же записях адреса разделов - относительны, причём с разными базами: адрес логического диска - указывается относительно расширенной записи, а адрес следующей - расширенной записи указывается относительно начала расширенного - раздела. Такой разнобой выглядит несколько странно, но имеет место - быть. Три оставшихся переменных содержат: extended_part_start - - начало расширенного раздела; extended_parent - текущая рассматриваемая - расширенная загрузочная запись; extended_part_cur - следующая - загрузочная запись для рассмотрения. - Цикл выглядит так: просматриваются все разделы, указанные в текущей - (главной или расширенной) загрузочной записи; для нормальных разделов - (они же логические диски) происходит переход на not_extended, где - устанавливается partition_start и начинается собственно загрузка - (последующие шаги); при встрече с разделом, тип которого указывает - на расширенность (5 или 0xF), код запоминает начало этого раздела - (в главной загрузочной записи такой тип означает расширенный раздел, - в расширенной - только указатель на следующую расширенную запись, - в обоих случаях он может встретиться только один раз в данной записи); - когда код доходит до конца списка, все нормальные разделы, описываемые - в этой записи, уже просмотрены, так что код с чистой совестью переходит - к следующей расширенной записи. Если он её не встретил, значит, уже - все логические разделы были подвергнуты попыткам загрузиться, и все - безрезультатно, так что выводится ругательство и работа останавливается - (jmp $). - Может возникнуть вопрос, зачем нужна такая сложная схема и почему - нельзя узнать нужный логический диск заранее или хотя бы ограничиться - первым попавшимся логическим диском, не крутя цикл. Так вот, вариант - с предварительным определением нужного раздела в данном случае не - используется, поскольку повлёк бы за собой нетривиальные лишние - действия по установке (в текущем виде установку можно провести вручную, - и она сводится к указанию системному загрузчику на существование - kordldr); кстати, в альтернативной версии загрузки после - Windows-загрузчика, когда установка осуществляется не вручную, а - специальной программой под Windows, используется модифицированная - версия, в которой как раз начальный физический сектор нужного раздела - прописывается установщиком. Сам kordldr не может установить, с какого - раздела его загрузил Windows-загрузчик (и вообще под NT/2000/XP обязан - быть файлом на диске C:\). Вариант с первым попавшимся логическим - диском был реализован в первой версии загрузчика, но по ходу дела - обнаружилось, что таки нужно крутить цикл: во-вторых, может быть - приятным, что сама система может стоять вовсе не на системном C:\, а и - на других дисках; во-первых, диск C: может и не быть первым логическим - разделом - Vista любит создавать скрытый первичный раздел перед - системным, и тогда диск C: становится вторым логическим. -6. Извещает пользователя о том, что происходит попытка загрузки с очередного - логического диска. -7. Читает первый сектор логического диска и определяет файловую систему. - И в FAT, и в NTFS поле со смещением +11 содержит число байт в секторе - и должно совпадать с характеристикой физического носителя, то есть - 200h байт. И в FAT, и в NTFS поле со смещением +13 содержит число - секторов в кластере и должно быть степенью двойки. - Критерий NTFS: поле со смещением +3 содержит строку NTFS и поле со - смещением +16 нулевое (в FAT оно содержит число таблиц FAT и обязано - быть ненулевым). - Критерий FAT: загрузчик вычисляет число кластеров, определяет - предположительный тип (FAT12/FAT16/FAT32) и проверяет байт по смещению - +38 для FAT12/16, +66 для FAT32 (он должен быть равен 0x29). - После определения типа файловой системы извещает пользователя об - определённом типе. Если файловая система не распознана, выдаёт - соответствующее сообщение и переходит к следующему логическому диску. -8a. Для FAT12-томов: засовывает в стек идентификатор файловой системы - - константу '12'; устанавливает указатель на функцию получения следующего - в цепочке FAT кластера на FAT12-обработчик; считывает в память всю - таблицу FAT12 (она не превосходит 0x1800 байт = 6 Кб), при ошибке - чтения пытается использовать другие копии FAT. -8б. Для FAT16-томов: засовывает в стек идентификатор файловой системы - - константу '16'; устанавливает указатель на функцию получения следующего - в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию - о кэше секторов FAT (массив байт с возможными значениями 0 и 1, - означающими, был ли уже загружен соответствующий сектор - всего в - таблице FAT16 не более 0x100 секторов) - ни один сектор ещё не - загружен, все байты нулевые. -8в. Для FAT32-томов: засовывает в стек идентификатор файловой системы - - константу '32'; устанавливает указатель на функцию получения следующего - в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию - о кэше секторов FAT (формат информации описан выше, в распределении - используемой загрузчиком памяти) - ни один сектор ещё не загружен. -8г. Общее для FAT-томов: определяет значения служебных переменных - root_start (первый сектор корневого каталога в FAT12/16, игнорируется - при обработке FAT32-томов), data_start (начало данных с поправкой, - вводимой для того, чтобы кластер N начинался с сектора - N*sectors_per_cluster+data_start), root_clus (первый кластер корневого - каталога в FAT32, 0 в FAT12/16); устанавливает указатель на функцию - загрузки файла на FAT-обработчик. -8д. Для NTFS-томов: засовывает в стек идентификатор файловой системы - - константу 'nt'; определяет значение служебной переменной frs_size - (размер в байтах файловой записи, File Record Segment), для полной - корректности проверяет, что это значение (равное 0x400 байт на всех - реальных NTFS-томах - единственный способ изменить его заключается - в пересоздании всех системных структур вручную) не превосходит 0x1000 - и кратно размеру сектора 0x200 байт; инициализирует кэш файловых - записей - ничего ещё не загружено; считывает первый кластер $MFT - и загружает информацию о расположении на диске всей таблицы $MFT - (атрибут 0x80, $Data); устанавливает указатель на функцию загрузки - файла на NTFS-обработчик. -9. (метка load_secondary) Вызывает функцию загрузки файла для файла вторичного - загрузчика. При обнаружении ошибки переходит на обработчик ошибок с - соответствующим сообщением. -10. Устанавливает регистры для вторичного загрузчика: al='h' (жёсткий диск), - ah=номер диска (для готового бинарника - 0 (BIOS-идентификатор 80h), - может быть изменён путём модификации константы в исходнике или - специальным установщиком), bx=идентификатор файловой системы (берётся - из стека, куда ранее был засунут на шаге 8), ds:si=указатель на - callback-функцию. -11. Передаёт управление вторичному загрузчику дальним переходом на 1000:0000. - -Функция обратного вызова для вторичного загрузчика: - предоставляет возможность чтения файла. -Вход и выход описаны в спецификации на загрузчик. -Чтение файла: -1. Сохраняет стек вызывающего кода и устанавливает свой стек: - ss:sp = 0:3000, bp=dat: пара ss:bp при работе с остальным - кодом должна указывать на 0:dat. -2. Разбирает переданные параметры и вызывает процедуру загрузки файла. -3. Восстанавливает стек вызывающего кода и возвращает управление. - -Вспомогательные процедуры. -Процедура чтения секторов (read): -на входе должно быть установлено: - ss:bp = 0:dat - es:bx = указатель на начало буфера, куда будут прочитаны данные - eax = стартовый сектор (относительно начала логического диска) - cx = число секторов (должно быть больше нуля) -на выходе: es:bx указывает на конец буфера, в который были прочитаны данные, - флаг CF установлен, если возникла ошибка чтения -1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на - устройстве, прибавляя номер первого сектора логического диска, - найденный при переборе дисков. -2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации - CHS-версия: все читаемые секторы были на одной дорожке. - LBA-версия: число читаемых секторов не превосходило 7Fh (требование - спецификации EDD BIOS). -CHS-версия: -3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как - единица плюс остаток от деления абсолютного номера на число секторов - на дорожке; дорожка рассчитывается как остаток от деления частного, - полученного на предыдущем шаге, на число дорожек, а цилиндр - как - частное от этого же деления. Если число секторов для чтения больше, - чем число секторов до конца дорожки, уменьшает число секторов для - чтения. -4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, - dh=головка, (младшие 6 бит cl)=сектор, - (старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска - и повторяет попытку чтения, всего делается не более трёх попыток - (несколько попыток нужно в случае дискеты для гарантии того, что - мотор раскрутился). Если все три раза происходит ошибка чтения, - переходит на код обработки ошибок с сообщением "Read error". -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. -LBA-версия: -3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей - итерации) до 7Fh. -4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами - push, причём в обратном порядке: стек - структура LIFO, и данные в - стеке хранятся в обратном порядке по отношению к тому, как их туда - клали). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки - ошибок с сообщением "Read error". Очищает стек от пакета, - сформированного на предыдущем шаге. -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. - -Процедура обработки ошибок (find_error_si и find_error_sp): -на входе: указатель на сообщение об ошибке в si либо на верхушке стека -0. Если вызывается find_error_si, она помещает переданный указатель в стек. -1. Если ошибка произошла в процессе работы callback-функции, то - (метка error_in_callback) обработчик просто возвращает управление - вызвавшему коду, рапортуя о ненайденном файле. -2. Если же ошибка произошла до передачи управления вторичному загрузчику, - обработчик выводит сообщение типа "Error: <текущий объект>: <ошибка>" - и (восстановив стек) переходит к следующему логическому диску. - -Процедура чтения файла/атрибута по известному размещению на диске - (read_file_chunk): -на входе должно быть установлено: - ds:si = указатель на информацию о размещении - es:bx = указатель на начало буфера, куда будут прочитаны данные - ecx = лимит числа секторов для чтения, старшее слово должно быть 0 -на выходе: es:bx указывает на конец буфера, в который были прочитаны данные, - флаг CF установлен, если возникла ошибка чтения -1. Определяет, является ли атрибут резидентным (возможно только в NTFS - и означает, что данные файла/атрибута уже были целиком прочитаны при - обработке информации о файле) или нерезидентным (означает, что данные - хранятся где-то на диске, и имеется информация о том, где именно). -2. Для резидентных атрибутов (метка read_file_chunk.resident) просто копирует - данные по месту назначения (с учётом указанного лимита). -3. Для нерезидентных атрибутов информация состоит из пар <размер очередного - фрагмента файла в кластерах, стартовый кластер фрагмента>; процедура - читает фрагменты, пока файл не закончится или пока не будет достигнут - указанный лимит. - -Процедура просмотра кэша (cache_lookup): -на входе должно быть установлено: - eax = искомое значение - ss:si = указатель на структуру-заголовок кэша -на выходе: ss:di = указатель на вход в кэше; флаг CF установлен, если значение - было только что добавлено, и сброшен, если оно уже было в кэше. -1. Просматривает кэш в поисках указанного значения. Если значение найдено - (при этом флаг CF оказывается сброшенным), переходит к шагу 4. -2. Если кэш уже заполнен, удаляет из кэша самый старый вход (он находится в - голове двусвязного списка), иначе добавляет к кэшу ещё один вход. -3. Устанавливает в полученном входе указанное значение. Устанавливает флаг - CF, последующие шаги не меняют состояния флагов. Переходит к шагу 5. -4. Удаляет вход из списка. -5. Добавляет сектор в конец списка (самый новый вход). diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/ntfs.inc b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/ntfs.inc deleted file mode 100644 index 413fe9907..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/after_win/ntfs.inc +++ /dev/null @@ -1,587 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -restore_usa: -; Update Sequence Array restore -; in: ds:bx -> USA-protected structure - push bx - lea di, [bx+1feh] - mov cx, [bx+6] - add bx, [bx+4] - dec cx -@@: - mov ax, [bx+2] - mov [di], ax - inc bx - inc bx - add di, 200h - loop @b - pop bx - ret - -find_attr: -; in: ds:di->file record, ax=attribute -; out: ds:di->attribute or di=0 if not found - add di, [di+14h] -.1: -; attributes' codes are formally dwords, but all of them fit in word - cmp word [di], -1 - jz .notfound - cmp word [di], ax - jnz .continue -; for $DATA attribute, scan only unnamed - cmp ax, 80h - jnz .found - cmp byte [di+9], 0 - jz .found -.continue: - add di, [di+4] - jmp .1 -.notfound: - xor di, di -.found: - ret - -process_mcb_nonres: -; in: ds:si->attribute, es:di->buffer -; out: es:di->buffer end - pushad - pop di - add si, [si+20h] - xor ebx, ebx -.loop: - lodsb - test al, al - jz .done - push invalid_read_request_string - movzx cx, al - shr cx, 4 - jz find_error_sp - xchg ax, dx - and dx, 0Fh - jz find_error_sp - add si, cx - add si, dx - pop ax - push si - dec si - movsx eax, byte [si] - dec cx - jz .l1e -.l1: - dec si - shl eax, 8 - mov al, [si] - loop .l1 -.l1e: - xchg ebp, eax - dec si - movsx eax, byte [si] - mov cx, dx - dec cx - jz .l2e -.l2: - dec si - shl eax, 8 - mov al, byte [si] - loop .l2 -.l2e: - pop si - add ebx, ebp -; eax=length, ebx=disk block - stosd - mov eax, ebx - stosd - cmp di, 0x8000 - 12 - jbe .loop -..attr_overflow: - mov si, fragmented_string - jmp find_error_si -.done: - xor ax, ax - stosw - stosw - push di - popad - ret - -load_attr: -; in: ax=attribute, ds:bx->base record -; out: if found: CF=0, attribute loaded to [freeattr], [freeattr] updated, -; edx=size of attribute in bytes -; out: if not found: CF=1 - mov di, [bp + freeattr - dat] - push ss - pop es - mov byte [es:di], 1 - inc di - cmp di, 0x8000 - 12 - ja ..attr_overflow - or edx, -1 ; file size is not known yet -; scan for attribute - push di - mov di, bx - add di, [di+14h] -@@: - call find_attr.1 - test di, di - jz .notfound1 - cmp byte [di+8], 0 - jnz .nonresident - mov si, di - pop di - push ds - jmp .resident -.aux_resident: - mov ax, ds - mov si, di - pop di ds bx ds edx - push ss - pop es - push ds - mov ds, ax -; resident attribute -.resident: - dec di - mov al, 0 - stosb - mov ax, [si+10h] - stosw - push di - add di, ax - cmp di, 0x8000 - 12 - pop di - ja ..attr_overflow - movzx edx, ax ; length of attribute - xchg ax, cx - add si, [si+14h] - rep movsb - mov [bp + freeattr - dat], di - pop ds - ret -.nonresident: -; nonresident attribute - cmp dword [di+10h], 0 - jnz @b -; read start of data - mov si, di - mov edx, [di+30h] ; size of attribute - pop di - call process_mcb_nonres - sub di, 4 - push di -.notfound1: - pop di - push edx -; $ATTRIBUTE_LIST is always in base file record - cmp ax, 20h - jz .nofragmented -; try to load $ATTRIBUTE_LIST = 20h - push ax - mov ax, 20h - push [bp + freeattr - dat] - mov [bp + freeattr - dat], di - push di - call load_attr - pop di - pop [bp + freeattr - dat] - pop ax - jc .nofragmented - push ds bx - pusha - mov si, di - push ss - pop ds - push 0x8100 - pop es - xor ecx, ecx - mov cl, 0x78 - xor bx, bx - push es - call read_file_chunk - pop ds - jc ..found_disk_error - test cx, cx - jz ..attr_overflow - popa - push ss - pop es - xor bx, bx -.1: - cmp [bx], ax - jnz .continue1 -; only unnamed $DATA attributes! - cmp ax, 80h - jnz @f - cmp byte [bx+6], 0 - jnz .continue1 -@@: - cmp dword [bx+10h], 0 - jz .continue1 - cmp dword [bx+8], 0 - jnz @f - dec di - cmp di, [bp + freeattr - dat] - lea di, [di+1] - jnz .continue1 -@@: - push ds di - push ax - mov eax, [bx+10h] - mov ecx, [bx+8] - call read_file_record - pop ax - mov di, [14h] -.2: - call find_attr.1 - cmp byte [di+8], 0 - jz .aux_resident - cmp dword [di+10h], ecx - jnz .2 - mov si, di - mov di, sp - cmp dword [ss:di+8], -1 - jnz @f - push dword [si+30h] ; size of attribute - pop dword [ss:di+8] -@@: - pop di - call process_mcb_nonres - sub di, 4 - pop ds -.continue1: - add bx, [bx+4] - cmp bx, dx - jb .1 - pop bx ds -.nofragmented: - pop edx - dec di - cmp di, [bp + freeattr - dat] - jnz @f - stc - ret -@@: - inc di - xor ax, ax - stosw - stosw - mov [bp + freeattr - dat], di - ret - -read_file_record: -; in: eax = index of record -; out: ds:0 -> record -; find place in cache - push di - push si - mov si, cache1head - call cache_lookup - pop si - pushf - sub di, 3400h - shl di, 10-3 - add di, 0x6000 - mov ds, di - popf - pop di - jnc .noread -; read file record to ds:0 - pushad - push ds - push es - movzx ecx, [bp + frs_size - dat] - shr cx, 9 - mul ecx - push ds - pop es - push ss - pop ds - mov si, 0x4000 - xor bx, bx - push [bp + cur_obj - dat] - mov [bp + cur_obj - dat], mft_string - push es - call read_attr -; initialize cache for $INDEX_ALLOCATION for this record - pop si - push si - sub si, 0x6000 - mov ax, si - shr si, 10-3 - shr ax, 2 - add si, 3480h - add ax, 3500h - mov [si], si - mov [si+2], si - mov [si+4], ax - pop ds - call restore_usa - pop [bp + cur_obj - dat] - pop es - pop ds - popad -.noread: - ret - -read_attr: -; in: eax = offset in sectors, ecx = size in sectors (<10000h), es:bx -> buffer, ds:si -> attribute - push invalid_read_request_string - cmp byte [si], 0 - jnz .nonresident - cmp eax, 10000h shr 9 - jae find_error_sp - shl ax, 9 - shl cx, 9 - cmp ax, [si+2] - jae find_error_sp - cmp cx, [si+2] - ja find_error_sp - add si, 3 - add si, ax - mov di, bx - rep movsb - pop ax - ret -.nonresident: - inc si -.loop: - mov edx, dword [si] - add si, 8 - test edx, edx - jz find_error_sp - imul edx, [bp + sect_per_clust - dat] - sub eax, edx - jnc .loop - add eax, edx - sub edx, eax - push cx - cmp ecx, edx - jb @f - mov cx, dx -@@: - push bx - mov ebx, [si-4] - imul ebx, [bp + sect_per_clust - dat] - add eax, ebx - pop bx - call read - jc ..found_disk_error - mov dx, cx - pop cx - xor eax, eax - sub cx, dx - jnz .loop - pop ax - ret - -load_file_ntfs: -; in: ss:bp = 0:dat -; in: es:bx = address to load file -; in: ds:si -> ASCIIZ name -; in: cx = limit in sectors -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part has been loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) - push es bx cx - mov eax, 5 ; root cluster - mov [bp + cur_obj - dat], root_string -.parse_dir_loop: - push ds si - call read_file_record -; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP - mov ax, [bp + freeattr - dat] - mov [bp + index_root - dat], ax - mov ax, 90h ; $INDEX_ROOT - xor bx, bx - call load_attr - mov si, noindex_string - jc find_error_si - mov ax, [bp + freeattr - dat] - mov [bp + index_alloc - dat], ax - mov ax, 0A0h ; $INDEX_ALLOCATION - call load_attr - jnc @f - mov [bp + index_alloc - dat], bx -@@: - push ds -; search for entry - mov si, [bp + index_root - dat] - push ss - pop ds - push 0x8100 - pop es - xor ecx, ecx - mov cl, 0x78 - xor bx, bx - push es - call read_file_chunk - pop ds - jc ..found_disk_error - test cx, cx - jz ..attr_overflow - mov si, invalid_read_request_string - cmp word [bx+10], 0 - jnz find_error_si -; calculate number of items in cache - mov di, [bx+8] ; subnode_size - mov ax, 0x4000 - sub ax, word [bp + frs_size - dat] - cwd - div di - test ax, ax - jz find_error_si - mov si, invalid_volume_msg - test di, 0x1FF - jnz find_error_si - pop cx - mov [bp + cur_index_seg - dat], cx - shl ax, 3 - sub cx, 6000h - mov si, cx - shr cx, 2 - shr si, 10-3 - add cx, ax - add si, 3480h - mov [bp + cur_index_cache - dat], si - add cx, 3500h - mov [ss:si+6], cx - mov dx, di - add bx, 10h -.scan_record: - add bx, [bx] -.scan: - test byte [bx+0Ch], 2 - jnz .look_child - movzx cx, byte [bx+50h] ; namelen - lea di, [bx+52h] ; name - push ds - pop es - pop si ds - push ds si - xor ax, ax -.1: - lodsb - cmp al, '/' - jnz @f - mov al, 0 -@@: - cmp al, 'A' - jb .nocapital - cmp al, 'Z' - ja .nocapital - or al, 20h -.nocapital: - cmp al, 'a' - jb .notletter - cmp al, 'z' - ja .notletter - or byte [es:di], 20h -.notletter: - scasw - loopz .1 - jb .look_child - ja @f - cmp byte [si], 0 - jz .file_found - cmp byte [si], '/' - jz .file_found -@@: - push es - pop ds - add bx, [bx+8] - jmp .scan -.look_child: - push es - pop ds - test byte [bx+0Ch], 1 - jz .not_found - mov si, [bp + index_alloc - dat] - test si, si - jz .not_found - add bx, [bx+8] - mov eax, [bx-8] - mov es, [bp + cur_index_seg - dat] - push si - mov si, [bp + cur_index_cache - dat] - call cache_lookup - pop si - pushf - mov bx, di - mov bh, 0 - shr bx, 3 - imul bx, dx - add bx, [bp + frs_size - dat] - popf - jnc .noread - push es - push dx - push ss - pop ds - movzx ecx, dx - shr cx, 9 - mul [bp + sect_per_clust - dat] - call read_attr - pop dx - pop es - push es - pop ds - call restore_usa -.noread: - push es - pop ds - add bx, 18h - jmp .scan_record -.not_found: - pop [bp + cur_obj - dat] - mov si, error_not_found - jmp find_error_si -.file_found: - pop [bp + cur_obj - dat] - pop cx - mov ax, [bp + index_root - dat] - mov [bp + freeattr - dat], ax - mov eax, [es:bx] - test byte [es:bx+48h+3], 10h - jz .regular_file - cmp byte [si], 0 - jz ..directory_error - inc si - jmp .parse_dir_loop -.regular_file: - cmp byte [si], 0 - jnz ..notdir_error -; read entry - call read_file_record - xor bx, bx - mov ax, 80h - call load_attr - mov si, nodata_string - jc find_error_si - mov si, [bp + index_root - dat] - mov [bp + freeattr - dat], si - push ss - pop ds - jmp load_file_common_end diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/Tupfile.lua b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/Tupfile.lua deleted file mode 100644 index 75b9668db..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/Tupfile.lua +++ /dev/null @@ -1,2 +0,0 @@ -if tup.getconfig("NO_FASM") ~= "" then return end -tup.rule("bootsect.asm", "fasm %f %o ", "bootsect.bin") diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/bootsect.asm b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/bootsect.asm deleted file mode 100644 index 4694e005e..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/bootsect.asm +++ /dev/null @@ -1,1024 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - jmp far 0:real_start -; special text -org $+0x7C00 -real_start: -; initialize - xor ax, ax - mov ss, ax - mov sp, 0x7C00 - mov ds, ax - mov es, ax - cld - sti - mov [bootdrive], dl -; check LBA support - mov ah, 41h - mov bx, 55AAh - int 13h - mov si, aNoLBA - jc err_ - cmp bx, 0AA55h - jnz err_ - test cl, 1 - jz err_ -; get file system information -; scan for Primary Volume Descriptor - db 66h - push 10h-1 - pop eax -pvd_scan_loop: - mov cx, 1 - inc eax - mov bx, 0x1000 - call read_sectors - jnc @f -fatal_read_err: - mov si, aReadError -err_: - call out_string - mov si, aPressAnyKey - call out_string - xor ax, ax - int 16h - int 18h - jmp $ -@@: - push ds - pop es - cmp word [bx+1], 'CD' - jnz pvd_scan_loop - cmp word [bx+3], '00' - jnz pvd_scan_loop - cmp byte [bx+5], '1' - jnz pvd_scan_loop -; we have found ISO9660 descriptor, look for type - cmp byte [bx], 1 ; Primary Volume Descriptor? - jz pvd_found - cmp byte [bx], 0xFF ; Volume Descriptor Set Terminator? - jnz pvd_scan_loop -; Volume Descriptor Set Terminator reached, no PVD found - fatal error - mov si, no_pvd - jmp err_ -pvd_found: - add bx, 80h - mov ax, [bx] - mov [lb_size], ax -; calculate number of logical blocks in one sector - mov ax, 800h - cwd - div word [bx] - mov [lb_per_sec], ax -; get location of root directory - mov di, root_location - movzx eax, byte [bx+1Dh] - add eax, [bx+1Eh] - stosd -; get memory size - int 12h - mov si, nomem_str - cmp ax, 71000h / 400h - jb err_ - shr ax, 1 - sub ax, 60000h / 800h - mov [size_rest], ax - mov [free_ptr], 60000h / 800h -; load path table -; if size > 62K => it's very strange, avoid using it -; if size > (size of cache)/2 => avoid using it too - mov ecx, [bx+4] - cmp ecx, 0x10000 - 0x800 - ja nopathtable - shr ax, 1 - cmp ax, 0x20 - jae @f - shl ax, 11 - cmp cx, ax - ja nopathtable -@@: -; size is ok, try to load it - mov [pathtable_size], cx - mov eax, [bx+12] - xor edx, edx - div dword [lb_per_sec] - imul dx, [bx] - mov [pathtable_start], dx - add cx, dx - call cx_to_sectors - xor bx, bx - push 6000h - pop es - call read_sectors - jc nopathtable -; path table has been loaded - inc [use_path_table] - sub [size_rest], cx - add [free_ptr], cx -nopathtable: -; init cache - mov ax, [size_rest] - mov [cache_size], ax - mov ax, [free_ptr] - mov [cache_start], ax -; load secondary loader - mov di, secondary_loader_info - call load_file - test bx, bx - jnz noloader -; set registers for secondary loader - mov ah, [bootdrive] - mov al, 'c' - mov bx, 'is' - mov si, callback - jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000 - -noloader: - mov si, aKernelNotFound - jmp err_ - -read_sectors: -; es:bx = pointer to data -; eax = first sector -; cx = number of sectors - pushad - push ds -do_read_sectors: - push ax - push cx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F -@@: -; create disk address packet on the stack -; dq starting LBA - db 66h - push 0 - push eax -; dd buffer - push es - push bx -; dw number of blocks to transfer (no more than 0x7F) - push cx -; dw packet size in bytes - push 10h -; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [cs:bootdrive] - mov ah, 42h - int 13h - jc diskreaderr -; restore stack - add sp, 10h -; increase current sector & buffer; decrease number of sectors - movzx esi, cx - mov ax, es - shl cx, 7 - add ax, cx - mov es, ax - pop cx - pop ax - add eax, esi - sub cx, si - jnz do_read_sectors - pop ds - popad - ret -diskreaderr: - add sp, 10h + 2*2 - pop ds - popad - stc -out_string.ret: - ret - -out_string: -; in: ds:si -> ASCIIZ string - lodsb - test al, al - jz .ret - mov ah, 0Eh - mov bx, 7 - int 10h - jmp out_string - -aNoLBA db 'The drive does not support LBA!',0 -aReadError db 'Read error',0 -no_pvd db 'Primary Volume Descriptor not found!',0 -nomem_str db 'No memory',0 -aPressAnyKey db 13,10,'Press any key...',13,10,0 - -load_file: -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) -; parse path to the file - lea si, [di+6] - mov eax, [cs:root_location] - cmp [cs:use_path_table], 0 - jz parse_dir -; scan for path in path table - push di - push 6000h - pop es - mov di, [cs:pathtable_start] ; es:di = pointer to current entry in path table - mov dx, 1 ; dx = number of current entry in path table, start from 1 - mov cx, [cs:pathtable_size] -pathtable_newparent: - mov bx, dx ; bx = number of current parent in path table: root = 1 -scan_path_table_e: - call is_last_component - jnc path_table_scanned -scan_path_table_i: - cmp word [es:di+6], bx - jb .next - ja path_table_notfound - call test_filename1 - jc .next -@@: - lodsb - cmp al, '/' - jnz @b - jmp pathtable_newparent -.next: -; go to next entry - inc dx - movzx ax, byte [es:di] - add ax, 8+1 - and al, not 1 - add di, ax - sub cx, ax - ja scan_path_table_i -path_table_notfound: - pop di - mov ax, -1 - mov dx, ax - mov bx, 2 ; file not found - ret -path_table_scanned: - movzx eax, byte [es:di+1] - add eax, [es:di+2] - pop di -parse_dir: -; eax = logical block, ds:di -> information structure, ds:si -> file name -; was the folder already read? - push di ds - push cs - pop ds - mov [cur_desc_end], 2000h - mov bx, cachelist -.scan1: - mov bx, [bx+2] - cmp bx, cachelist - jz .notfound - cmp [bx+4], eax - jnz .scan1 -.found: -; yes; delete this item from the list (the following code will append this item to the tail) - mov di, [bx] - push word [bx+2] - pop word [di+2] - mov di, [bx+2] - push word [bx] - pop word [di] - mov di, bx - jmp .scan -.notfound: -; no; load first sector of the folder to get its size - push eax - push si - mov si, 1 - call load_phys_sector_for_lb_force - mov bx, si - pop si - pop eax - jnc @f -; read error - return -.readerr: - pop ds -.readerr2: - pop di - mov ax, -1 - mov dx, ax - mov bx, 3 - ret -@@: -; first item of the folder describes the folder itself -; do not cache too big folders: size < 64K and size <= (total cache size)/2 - cmp word [bx+12], 0 - jnz .nocache - mov cx, [cache_size] ; cx = cache size in sectors - shr cx, 1 ; cx = (cache size)/2 - cmp cx, 0x20 - jae @f - shl cx, 11 - cmp [bx+10], cx - ja .nocache -@@: -; we want to cache this folder; get space for it - mov cx, [bx+10] - call cx_to_sectors - jnz .yescache -.nocache: - push dword [bx+10] - pop dword [cur_nocache_len] - call lb_to_sector - push ds - pop es - pop ds -.nocache_loop: - push eax - mov dx, 1800h - call scan_for_filename_in_sector - mov cx, dx - pop eax - jnc .j_scandone - sub cx, bx - sub word [es:cur_nocache_len], cx - sbb word [es:cur_nocache_len+2], 0 - jb .j_scandone - ja @f - cmp word [es:cur_nocache_len], 0 - jz .j_scandone -@@: - mov cx, 1 - inc eax - push es - mov bx, 1000h - call read_sectors - pop es - jc .readerr2 - jmp .nocache_loop -.j_scandone: - jmp .scandone -.yescache: - push bx - mov bx, [cachelist.head] -.freeloop: - cmp cx, [size_rest] - jbe .sizeok -@@: -; if we are here: there is not enough free space, so we must delete old folders' data -; N.B. We know that after deleting some folders the space will be available (size <= (total cache size)/2). -; one loop iteration: delete data of one folder - pusha - mov dx, [bx+10] - mov es, dx ; es = segment of folder data to be deleted - xor di, di - mov ax, [bx+8] - add ax, 0x7FF - rcr ax, 1 - shr ax, 10 - push ax - shl ax, 11-4 ; get number of paragraphs in folder data to be deleted - mov cx, [cache_size] - add cx, [cache_start] - push ds - push ax - add ax, dx - mov ds, ax - pop ax - shl cx, 11-4 - sub cx, dx ; cx = number of paragraphs to be moved - push si - xor si, si -; move cx paragraphs from ds:si to es:di to get free space in the end of cache -@@: - sub cx, 1000h - jbe @f - push cx - mov cx, 8000h - rep movsw - mov cx, ds - add cx, 1000h - mov ds, cx - mov cx, es - add cx, 1000h - mov es, cx - pop cx - jmp @b -@@: - add cx, 1000h - shl cx, 3 - rep movsw - pop si - pop ds -; correct positions in cache for existing items - mov cx, 80h - mov di, 8400h -.correct: - cmp [di+10], dx - jbe @f - sub [di+10], ax -@@: - add di, 12 - loop .correct -; some additional space is free now - pop ax - add [size_rest], ax - sub [free_ptr], ax -; add cache item to the list of free items - mov dx, [bx] - mov ax, [free_cache_item] - mov [bx], ax - mov [free_cache_item], bx - mov bx, dx -; current iteration done - popa - jmp .freeloop -.sizeok: - mov [cachelist.head], bx - mov word [bx+2], cachelist -; allocate new item in cache - mov di, [free_cache_item] - test di, di - jz .nofree - push word [di] - pop [free_cache_item] - jmp @f -.nofree: - mov di, [last_cache_item] - add [last_cache_item], 12 -@@: - pop bx - push si di -; mov [di+4], eax ; start of folder - scasd - stosd - push ax - mov ax, [free_ptr] - shl ax, 11-4 - mov [di+10-8], ax - mov es, ax - pop ax - add [free_ptr], cx - sub [size_rest], cx -; read folder data -; first sector is already in memory, 0000:bx - pusha - mov cx, [bx+10] - mov [di+8-8], cx ; folder size in bytes - mov si, bx - xor di, di - mov cx, 0x1800 - sub cx, si - rep movsb - pop ax - push di - popa -; read rest of folder - mov esi, dword [lb_per_sec] - add eax, esi - dec si - not si - and ax, si - mov si, word [bx+10] - mov bx, di - pop di - sub si, bx - jbe @f - mov [cur_limit], esi - call read_many_bytes - pop si - jnc .scan - jmp .readerr -@@: - pop si -.scan: -; now we have required cache item; append it to the end of list - mov bx, [cachelist.tail] - mov [cachelist.tail], di - mov [di+2], bx - mov word [di], cachelist - mov [bx], di -; scan for given filename - mov es, [di+10] - mov dx, [di+8] - pop ds - xor bx, bx - call scan_for_filename_in_sector -.scandone: - push cs - pop es - mov bx, 2000h - cmp bx, [es:cur_desc_end] - jnz filefound -j_notfound: - jmp path_table_notfound -filefound: -@@: - lodsb - test al, al - jz @f - cmp al, '/' - jnz @b -@@: - mov cl, [es:bx+8] - test al, al - jz @f -; parse next component of file name - test cl, 2 ; directory? - jz j_notfound - mov eax, [es:bx] - pop di - jmp parse_dir -@@: - test cl, 2 ; directory? - jnz j_notfound ; do not allow read directories as regular files -; ok, now load the file - pop di - les bx, [di] - call normalize - movzx esi, word [di+4] ; esi = limit in 4K blocks - shl esi, 12 ; esi = limit in bytes - push cs - pop ds - mov [cur_limit], esi - mov di, 2000h -loadloop: - and [cur_start], 0 -.loadnew: - mov esi, [cur_limit] - mov eax, [cur_start] - add esi, eax - mov [overflow], 1 - sub esi, [di+4] - jb @f - xor esi, esi - dec [overflow] -@@: - add esi, [di+4] ; esi = number of bytes to read - mov [cur_start], esi - sub esi, eax - jz .loadcontinue - xor edx, edx - div dword [lb_size] ; eax = number of logical blocks to skip, - mov [first_byte], dx; [first_byte] = number of bytes to skip in 1st block - cmp byte [di+10], 0 - jnz .interleaved - add eax, [di] -; read esi bytes from logical block eax to buffer es:bx - call read_many_bytes.with_first - jc .readerr3 -.loadcontinue: - mov [cur_chunk], di - add di, 11 - cmp di, [cur_desc_end] - jae @f - cmp [cur_limit], 0 - jnz loadloop -@@: - mov bx, [overflow] -.calclen: -; calculate length of file - xor ax, ax - xor dx, dx - mov di, 2000h -@@: - add ax, [di+4] - adc dx, [di+6] - add di, 11 - cmp di, [cur_desc_end] - jb @b - ret -.interleaved: - mov [cur_unit_limit], esi - push esi -; skip first blocks - movzx ecx, byte [di+9] ; Unit Size - movzx esi, byte [di+10] ; Interleave Gap - add si, cx - mov edx, [di] -@@: - sub eax, ecx - jb @f - add edx, esi - jmp @b -@@: - add ecx, eax ; ecx = number of logical blocks to skip - lea eax, [ecx+edx] ; eax = first logical block - pop esi -.interleaved_loop: -; get number of bytes in current file unit - push eax - movzx eax, byte [di+9] - sub ax, cx - imul eax, dword [lb_size] - cmp eax, esi - ja .i2 -.i1: - xchg esi, eax -.i2: - pop eax - sub [cur_unit_limit], esi - push eax -; read esi bytes from logical block eax to buffer es:bx - call read_many_bytes.with_first - pop eax - jnc @f -.readerr3: - mov bx, 3 - jmp .calclen -@@: - mov esi, [cur_unit_limit] - test esi, esi - jz .loadcontinue - movzx ecx, byte [di+9] ; add Unit Size - add cl, byte [di+10] ; add Interleave Gap - adc ch, 0 - add eax, ecx - xor cx, cx - mov [first_byte], cx - jmp .interleaved_loop - -cx_to_sectors: - add cx, 7FFh - rcr cx, 1 - shr cx, 10 - ret - -is_last_component: -; in: ds:si -> name -; out: CF set <=> current component is not last (=> folder) - push si -@@: - lodsb - test al, al - jz @f - cmp al, '/' - jnz @b - stc -@@: - pop si - ret - -test_filename1: -; in: ds:si -> filename, es:di -> path table item -; out: CF set <=> no match - pusha - mov cl, [es:di] - add di, 8 - jmp test_filename2.start -test_filename2: -; in: ds:si -> filename, es:bx -> directory item -; out: CF set <=> no match - pusha - mov cl, [es:bx+32] - lea di, [bx+33] -.start: - mov ch, 0 -@@: - lodsb - test al, al - jz .test1 - cmp al, '/' - jz .test1 - call toupper - mov ah, al - mov al, [es:di] - call toupper - inc di - cmp al, ah - loopz @b - jnz .next1 -; if we have reached this point: current name is done - lodsb - test al, al - jz .ret - cmp al, '/' - jz .ret -; if we have reached this point: current name is done, but input name continues -; so they do not match - jmp .next1 -.test1: -; if we have reached this point: input name is done, but current name continues -; "filename.ext;version" in ISO-9660 represents file "filename.ext" -; "filename." and "filename.;version" are also possible for "filename" - cmp byte [es:di], '.' - jnz @f - inc di - dec cx - jz .ret -@@: - cmp byte [es:di], ';' - jnz .next1 - jmp .ret -.next1: - stc -.ret: - popa - ret - -toupper: -; in: al=symbol -; out: al=symbol in uppercase - cmp al, 'a' - jb .ret - cmp al, 'z' - ja .ret - sub al, 'a'-'A' -.ret: - ret - -scan_for_filename_in_sector: -; in: ds:si->filename, es:bx->folder data, dx=limit -; out: CF=0 if found - push bx -.loope: - push bx -.loop: - cmp bx, dx - jae .notfound - cmp byte [es:bx], 0 - jz .loopd - test byte [es:bx+25], 4 ; ignore files with Associated bit - jnz .next - call test_filename2 - jc .next - push ds es di - push es - pop ds - push cs - pop es - mov di, [es:cur_desc_end] - movzx eax, byte [bx+1] - add eax, [bx+2] - stosd ; first logical block - mov eax, [bx+10] - stosd ; length - mov al, [bx+25] - stosb ; flags - mov ax, [bx+26] - stosw ; File Unit size, Interleave Gap size - mov [es:cur_desc_end], di - cmp di, 3000h - pop di es ds - jae .done - test byte [es:bx+25], 80h - jz .done -.next: - add bl, [es:bx] - adc bh, 0 - jmp .loop -.loopd: - mov ax, bx - pop bx -@@: - add bx, [cs:lb_size] - jz .done2 - cmp bx, ax - jb @b - jmp .loope -.notfound: - stc -.done: - pop bx -.done2: - pop bx - ret - -lb_to_sector: - xor edx, edx - div dword [lb_per_sec] - ret - -load_phys_sector_for_lb_force: -; in: eax = logical block, ds=0 -; in: si=0 - accept 0 logical blocks, otherwise force read at least 1 -; out: 0000:1000 = physical sector data; si -> logical block -; out: eax = next physical sector -; out: CF=1 if read error -; destroys cx -; this procedure reads 0-3 or 1-4 logical blocks, up to the end of physical sector - call lb_to_sector - or si, dx - jnz @f - mov si, 1800h - jmp .done -@@: - mov si, 1000h - imul dx, [lb_size] - add si, dx - mov cx, 1 - push es bx - push ds - pop es - mov bx, 1000h - call read_sectors - pop bx es - inc eax -.done: - ret - -normalize: -; in: es:bx = far pointer -; out: es:bx = normalized pointer (i.e. 0 <= bx < 0x10) - push ax bx - mov ax, es - shr bx, 4 - add ax, bx - mov es, ax - pop bx ax - and bx, 0x0F - ret - -read_many_bytes: - and [first_byte], 0 -read_many_bytes.with_first: -; read esi bytes from logical block dx:ax to buffer es:bx -; out: CF=1 <=> disk error - push di -; load first physical sector - push bx si - mov si, [first_byte] - call load_phys_sector_for_lb_force - jnc @f - pop si bx -.ret: - pop di - ret -@@: - add si, [first_byte] - mov ecx, 1800h - sub cx, si - mov ebx, esi - pop bx - sub ebx, ecx - jnc @f - add cx, bx - xor ebx, ebx -@@: - pop di - sub [cur_limit], ecx - rep movsb - mov esi, ebx - mov bx, di - call normalize -; load other physical sectors -; read esi bytes from physical sector eax to buffer es:bx - test esi, esi - jz .ret - push esi - add esi, 0x7FF - and si, not 0x7FF - cmp esi, [cur_limit] - jbe .okplace -.noplace: - sub esi, 800h -.okplace: - shr esi, 11 ; si = number of sectors - mov cx, si - jz @f - call read_sectors -@@: - pop esi - jc .ret - movzx ecx, cx - add eax, ecx - shl ecx, 11 - sub [cur_limit], ecx - sub esi, ecx - jc .big - jz .nopost - push bx es - push ds - pop es - mov bx, 1000h - mov cx, 1 - call read_sectors - pop es di - jc .ret2 - mov cx, si - mov si, 1000h - sub word [cur_limit], cx - sbb word [cur_limit+2], 0 - rep movsb - mov bx, di - call normalize -.nopost: - clc -.ret2: - pop di - ret -.big: - mov ax, es - sub ax, 80h - mov es, ax - add bx, 800h - add bx, si - call normalize - sub [cur_limit], esi - jmp .nopost - -; Callback function for secondary loader -callback: -; in: ax = function number; only function 1 is defined for now - dec ax - jz callback_readfile - dec ax - jz callback_continueread - stc ; unsupported function - retf - -callback_readfile: -; function 1: read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error -; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call load_file - clc ; function is supported - retf - -callback_continueread: -; function 2: continue to read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=3 - read error -; out: dx:ax = file size - les bx, [di] - call normalize - movzx esi, word [di+4] ; si = limit in 4K blocks - shl esi, 12 ; bp:si = limit in bytes - push cs - pop ds - mov [cur_limit], esi - mov di, [cur_chunk] - call loadloop.loadnew - clc ; function is supported - retf - -secondary_loader_info: - dw 0, 0x1000 - dw 0x30000 / 0x1000 - db 'kernel.mnt',0 -aKernelNotFound db 'Fatal error: cannot load the kernel',0 - -align 2 -cachelist: -.head dw cachelist -.tail dw cachelist -free_cache_item dw 0 -last_cache_item dw 0x8400 - -use_path_table db 0 -bootdrive db ? -align 2 -lb_size dw ? ; Logical Block size in bytes - dw 0 ; to allow access dword [lb_size] -lb_per_sec dw ? ; Logical Blocks per physical sector - dw 0 ; to allow access dword [lb_per_sec] -free_ptr dw ? ; first free block in cache (cache block = sector = 0x800 bytes) -size_rest dw ? ; free space in cache (in blocks) -cache_size dw ? -cache_start dw ? -pathtable_size dw ? -pathtable_start dw ? -root_location dd ? -cur_desc_end dw ? -cur_nocache_len dd ? -cur_limit dd ? -cur_unit_limit dd ? -overflow dw ? -cur_chunk dw ? -first_byte dw ? -cur_start dd ? - -times 83FCh-$ db 0 - db 43h -; just to make file 2048 bytes long :) - db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' - - dw 0xAA55 ; this is not required for CD, but to be consistent... diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/bootsect.txt b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/bootsect.txt deleted file mode 100644 index 7fedad177..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/bootsect.txt +++ /dev/null @@ -1,418 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - Sector not found. N. N.N.N. N.N.N.N.N.N.N. N.N. N.N.N.N.N.N.? - -Бутсектор для загрузки с CD/DVD с файловой системой ISO-9660. -(ISO-9660 и её расширения - стандарт для CD; DVD может использовать -либо ISO-9660, либо UDF.) - -===================================================================== - -Требования для работы: -1) Сам бутсектор и все используемые файлы должны быть читабельны. -2) Минимальный процессор - 80386. -3) В системе должно быть как минимум 452K свободной базовой памяти. - -===================================================================== - -Документация в тему (ссылки проверялись на валидность 14.09.2008): - стандарт ISO-9660: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf - стандарт загрузочного CD: http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf - официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf - то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf - описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html - официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf - -===================================================================== - -Схема используемой памяти: - 1000-1800 временный буфер для чтения одиночных секторов - ...-7C00 стек - 7C00-8400 код бутсектора - 8400-8A00 информация о кэше для папок: массив входов следующего - формата: - dw следующий элемент в L2-списке закэшированных папок, - упорядоченном по времени использования - (голова списка - самый старый); - dw предыдущий элемент в том же списке; - dd первый сектор папки; - dw размер папки в байтах; - dw сегмент кэша - 60000-... содержимое Path Table, если она используется - + кэш для папок; - точный размер определяется размером доступной - физической памяти - как правило, непосредственно - перед A0000 размещается EBDA, Extended BIOS Data Area - -===================================================================== - -Основной процесс загрузки. -Точка входа (start): получает управление от BIOS при загрузке, при этом - dl содержит идентификатор диска, с которого идёт загрузка -1. При передаче управления загрузочному коду в случае CD/DVD пара cs:ip - равна не 0:7C00, а на 07C0:0000. Поэтому сначала загрузчик делает - дальний прыжок на самого себя с целью получить cs=0 (в некоторых - местах используется адресация переменных загрузчика через cs, поскольку - и ds, и es могут быть заняты под другие сегменты). -2. Настраивает стек ss:sp = 0:7C00 (непосредственно перед основным кодом) - и сегментные регистры ds=es=0. Форсирует сброшенный флаг направления - и разрешённые прерывания. Сохраняет идентификатор загрузочного диска - в специальную переменную. -3. Проверяет поддержку LBA. Для CD/DVD носителя BIOS обязана предоставлять - LBA-функции. -4. Ищет описатель тома CD (Primary Volume Descriptor, PVD): по стандарту - ISO9660 со смещения 10h начинается цепочка описателей тома, - завершающаяся специальным описателем (Volume Descriptor Set - Terminator). Код по очереди считывает все сектора, пока не наткнётся - либо на искомый описатель, либо на терминатор. Во втором случае - выдаётся соответствующее сообщение, и загрузка прекращается. -Вообще говоря, в случае мультисессионных CD основной каталог содержимого CD - располагается в последней сессии. И спецификация ElTorito загрузочного - CD оперирует также с последней сессией. Однако на практике оказывается, - что: во-первых, реальные BIOSы не понимают мультисессионных CD и - всегда используют первую сессию; во-вторых, BIOSовский int 13h просто - не позволяет получить информацию о последней сессии. В связи с этим - загрузчик также использует первую сессию. (В-третьих, в одной из BIOS - обнаружилась заготовка, которая в случае запроса сектора 10h, в котором - во всех нормальных случаях и располагается PVD, перенаправляет его - на сектор 10h+(начало сессии). Если бы этот BIOS ещё и грузился с - последней сессии, то благодаря заготовке загрузчик без всяких - модификаций также читал бы последнюю сессию.) -5. (метка pvd_found) Считывает из PVD некоторую информацию о томе во - внутренние переменные: размер логического блока (согласно спецификации, - должен быть степенью двойки от 512 до размера логического сектора, - равного 2048 для CD и DVD); положение на диске корневой папки; - вычисляет число блоков в секторе (из предыдущего примечания следует, - что оно всегда целое и само является степенью двойки). -6. Получает размер базовой памяти вызовом int 12h; на его основе вычисляет - размер пространства, которое может использовать загрузчик (от - адреса 6000:0000 до конца доступной памяти). -7. Загружает таблицу путей CD (Path Table) - область данных, которая содержит - базовую информацию обо всех папках на диске. Если таблица слишком - велика (больше 62K или больше половины доступной памяти), то она - игнорируется. Если таблица путей недоступна, то запрос типа - dir1/dir2/dir3/file приведёт к последовательному разбору корневой - папки и папок dir1,dir2,dir3; если доступна, то достаточно разобрать - саму таблицу путей (где записано положение папки dir1/dir2/dir3) - и папку dir3. Если таблица загружена, то соответственно уменьшается - объём оставшейся доступной памяти и увеличивается указатель на - свободную область. -8. Запоминает общий размер и начало кэша для папок (вся оставшаяся после п.7 - доступная память отводится под этот кэш). -9. Выдаёт запрос на чтение файла вторичного загрузчика kord/loader. При ошибке - печатает соответствующее сообщение и прекращает загрузку с CD. -10. Устанавливает регистры для вторичного загрузчика: al='c' идентифицирует - тип устройства - CD/DVD; ah=BIOS-идентификатор диска; bx='is' - идентифицирует файловую систему ISO-9660; ds:si указывает на - callback-функцию, которую может вызывать вторичный загрузчик. -11. Передаёт управление вторичному загрузчику, совершая дальний прыжок - на адрес, куда kord/loader был загружен. - -Функция обратного вызова для вторичного загрузчика (callback): - предоставляет возможность чтения файла. -Вход и выход описаны в спецификации на загрузчик. -Перенаправляет запрос соответствующей локальной процедуре (load_file при - первом запросе на загрузку файла, loadloop.loadnew при последующих - запросах на продолжение загрузки файла). - -Вспомогательные процедуры. -Код обработки ошибок (err): -1. Выводит строку с сообщением об ошибке. -2. Выводит строку "Press any key...". -3. Ждёт нажатия any key. -4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. -5. Для подстраховки зацикливается. - -Процедура чтения секторов (read_sectors): -на входе должно быть установлено: - es:bx = указатель на начало буфера, куда будут прочитаны данные - eax = стартовый сектор - cx = число секторов -на выходе: - es:bx указывает на конец буфера, в который были прочитаны данные - если произошла ошибка чтения, флаг CF установлен -1. В цикле (шаги 2-4) читает секторы, следит за тем, чтобы на каждой итерации - число читаемых секторов не превосходило 7Fh (требование спецификации - EDD BIOS). -2. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей - итерации) до 7Fh. -3. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами - push, причём в обратном порядке: стек - структура LIFO, и данные в - стеке хранятся в обратном порядке по отношению к тому, как их туда - клали). -4. Вызывает BIOS. Если BIOS рапортует об ошибке, очищает стек, - устанавливает CF=1 и выходит из процедуры. - Очищает стек от пакета, сформированного на предыдущем шаге. -5. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 2. - -Процедура вывода на экран ASCIIZ-строки (out_string): -на входе: ds:si -> строка -В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. - -Процедура загрузки файла (load_file): -на входе: - ds:di = указатель на информационную структуру, описанную в спецификации - на загрузчик, а также в комментариях к коду -на выходе: - bx = статус: 0=успех, 1=файл слишком большой, прочитана только часть, - 2=файл не найден, 3=ошибка чтения - dx:ax = размер файла, 0xFFFFFFFF, если файл не найден -1. Если подготовительный код загрузил таблицу путей, то ищет папку в таблице, - иначе переходит сразу к шагу 4, установив eax = начальный блок - корневой папки. -2. Устанавливает es:di на начало таблицы путей. Ограничение на размер - гарантирует, что вся таблица помещается в сегменте 6000h. - Инициализирует dx (в котором будет хранится номер текущего входа в - таблице, считая с 1), cx (размер оставшегося участка таблицы), - bx (номер входа, соответствующего родительской папке для текущего - рассматриваемого участка пути). -3. В цикле ищет вход с нужным родительским элементом и нужным именем. Элементы - таблицы путей упорядочены (подробно о порядке написано в спецификации), - так что если родительский элемент для очередного входа больше нужного, - то нужного входа в таблице нет совсем, и в этом случае происходит - выход из процедуры с bx=2, ax=dx=0xFFFF. Если обнаружился элемент, - соответствующий очередной папке в запрошенном пути, то на рассмотрение - выносится следующая компонента пути. Если эта компонента последняя, - то осталось найти файл в папке, и код переходит к пункту 4, - установив eax = начальный блок этой папки. Если же нет, то эта - компонента должна задавать имя папки, и код возвращается к пункту 3, - скорректировав указатель на имя ds:si и номер родительского входа bx. -4. (parse_dir) На этом шаге заданы начальный логический блок папки в eax - и указатель на имя файла относительно этой папки в ds:si. Если - папку искали по таблице путей, то имя файла уже не содержит подпапок; - если же нет, то подпапки вполне возможны. -5. Файлы в ISO-9660 могут состоять из нескольких кусков (File Section), каждый - из которых задаётся отдельным входом в папке. Информация обо всех - таких кусках при просмотре папки запоминается в области, начинающейся - с адреса 0000:2000. Переменная cur_desc_end содержит указатель на - конец этой области, он же указатель, куда будет помещена информация - при обнаружении следующего входа. (Папки, согласно спецификации, - должны задаваться одним куском.) -6. Код сначала ищет запрошенную папку в кэше папок. -7. (parse_dir.found) Если папка уже есть в кэше, то она удаляется из списка, - отсортированного по давности последнего обращения и код переходит к - п.15. (Следующим действием станет добавление папки в конец списка.) -8. (parse_dir.notfound) Если же папки нет в кэше, то её придётся загружать - с диска. Сначала загружается первый сектор (физический сектор, - содержащий первый логический блок). При ошибке ввода/вывода - происходит немедленный выход из процедуры с bx=3, dx=ax=0xFFFF. - Первый элемент папки содержит информацию о самой этой папке, конкретно - загрузчик интересуется её размером. -9. Если размер папки слишком большой (больше или равен 64K либо больше половины - общего размера кэша), то кэшироваться она не будет. В этом случае код - считывает папку посекторно во временный буфер (0000:1000) и посекторно - сканирует на наличие запрошенного имени, пока не найдёт такого имени - или пока не кончатся данные. (Цикл начинается со сканирования, - поскольку первая часть данных уже прочитана.) В конце код переходит - к п.17. -10. (parse_dir.yescache) Если принято решение о кэшировании папки, то нужно - обеспечить достаточное количество свободного места. Для этого может - понадобиться выкинуть какое-то количество старых данных (цикл - parse_dir.freeloop). Но если просто выкидывать, то, вообще говоря, - свободное пространство окажется разорванным на несколько фрагментов. - Поэтому при выкидывании какой-то папки из кэша загрузчик перемещает - все следующие за ней данные назад по памяти и соответственно - корректирует информацию о местонахождении данных в информации о кэше. - При этом новое пространство всегда добавляется в конец доступной - памяти. Цикл выкидывания продолжается, пока не освободится место, - достаточное для хранения папки. Из-за ограничений на размер кэшируемых - папок в конце концов место найдётся. -11. Выделяется новый элемент кэша. Все удалённые на шаге 10 элементы - организуются в единый список свободных элементов; если он непуст, - то очередной элемент берётся из этого списка; если же пуст, то - берётся совсем новый элемент из области памяти, предназначенной для - элементов кэша. -12. В новом элементе заполняются поля начального блока, сегмента с данными, - размера в байтах. -13. Уже прочитанные данные первого физического сектора пересылаются на - законное место в кэше. -14. Если все данные не исчерпываются первым сектором, то догружаются оставшиеся - данные с диска. При ошибке чтения, как и раньше, происходит выход из - процедуры с bx=3, ax=dx=0xFFFF. -15. (parse_dir.scan) Новый элемент добавляется в конец списка всех элементов - кэша. -16. Загрузчик ищет запрошенное имя в загруженных данных папки. - (Из-за ограничений на размер кэшируемой папки все данные располагаются - в одном сегменте.) -17. (parse_dir.scandone) Если в процессе сканирования папки не было найдено - никаких кусков файла, то cur_desc_end такой же, каким был вначале. - В этом случае процедура рапортует о ненайденном файле и выходит. -18. (filefound) Пропускает текущую компоненту имени. Если она была не последней - (то есть подпапкой, в которой нужно производить дальнейший поиск), - то код проверяет, что найденный вход - действительно подпапка, - устанавливает новый стартовый блок и возвращается к п.4. - Если же последней, то код проверяет, что найденный вход - регулярный - файл и начинает загрузку файла. -19. Нормализует указатель, по которому требуется прочитать файл. Под - нормализацией понимается преобразование типа - 1234:FC08 -> (1234+0FC0):0008, которое не меняет суммарного адреса, - но гарантирует отсутствие переполнений: в приведённом примере попытка - переслать 400h байт по rep movsb приведёт к тому, что последние 8 - байт запишутся не в нужное место, а на 64K раньше. Далее нормализация - будет производиться после каждой пересылки. В cur_limit помещает - предельный размер для чтения в байтах. -20. (loadloop) В цикле по найденным фрагментам файла загружает эти фрагменты - (пункты 21-27). -21. Обнуляет переменную [cur_start], имеющую смысл числа байт, которое - нужно пропустить с начала фрагмента. -22. (loadloop.loadnew) На эту метку управление может попасть либо с предыдущего - шага, либо напрямую из callback-процедуры при запросе на продолжение - чтения. Для этого и нужна вышеупомянутая переменная [cur_start] - - при продолжении чтения, прервавшегося из-за конца буфера посередине - фрагмента, там будет записано соответствующее значение. -23. Определяет текущую длину (хранится в esi) как минимум из длины фрагмента - и максимальной длины остатка. Если второе строго меньше, то - запоминает, что файл слишком большой и прочитан только частично. - Определяет новое значение числа прочитанных байт во фрагменте - для возможных будущих вызовов [cur_start]. -24. Переводит пропускаемое число байт в число логических блоков и байт - в первом блоке, последнее число записывает в переменную [first_byte], - откуда её позднее достанет read_many_bytes.with_first. -25. Если фрагмент записан в обычном режиме (non-interleaved mode), то код - определяет начальный блок фрагмента и вызывает вспомогательную функцию - чтения блоков. При ошибке чтения устанавливает bx=3 (код ошибки чтения) - и выходит из цикла к п.28. -26. Если фрагмент записан в чередуемом режиме (interleaved mode), то сначала - код пропускает нужное количество непрерывных частей, а потом - в цикле загружает непрерывные части с помощью той же функции, - в промежутках между частями увеличивая номер начального блока. - Пока не кончится фрагмент или пока не наберётся запрошенное число байт. - При ошибке чтения делает то же самое, что и в предыдущем случае. -27. (loadloop.loadcontinue) Если фрагменты ещё не кончились и предельный размер - ещё не достигнут, переходит к следующему фрагменту и п.20. В противном - случае устанавливает bx=0 либо bx=1 в зависимости от того, было ли - переполнение в п.23. -28. (loadloop.calclen) Подсчитывает общую длину файла, суммируя длины всех - фрагментов. - -Процедура проверки, является ли текущая компонента имени файла последней - (is_last_component): -на входе: ds:si = указатель на имя -на выходе: флаг CF установлен, если есть последующие компоненты -В цикле загружает символы имени в поисках нулевого и '/'; если нашёлся первый, - то выходит (при этом CF=0); если нашёлся второй, то устанавливает CF - и выходит. - -Процедуры проверки на совпадение текущей компоненты имени файла с именем -текущего элемента (test_filename1 для таблицы путей, test_filename2 для папки): -на входе: ds:si = указатель на имя, es:di = указатель на элемент - таблицы путей для test_filename1, папки для test_filename2 -на выходе: CF установлен, если имена не совпадают -В цикле проверяет совпадение приведённых к верхнему регистру очередных символов - имён файла и элемента. Условия выхода из цикла: закончилось имя файла - в ds:si (то есть, очередной символ - нулевой либо '/') - совпадение - возможно только в ситуации типа имени "filename.ext" и элемента - "filename.ext;1" (в ISO9660 ";1" - версия файла, элементы с одинаковыми - именами в папке отсортированы по убыванию версий); - несовпадение символов - означает, что имена не совпадают; - закончилось имя элемента - нужно проверить, закончилось ли при этом имя - файла, и в зависимости от этого принимать решение о совпадении. - -Процедура приведения символа в верхний регистр (toupper): -на входе: ASCII-символ -на выходе: тот же символ в верхнем регистре (он сам, если понятие регистра к - нему неприменимо) -Из символов в диапазоне 'a' - 'z' включительно вычитает константу 'a'-'A', - остальные символы не трогает. - -Процедура поиска файла в данных папки (scan_for_filename_in_sector): -на входе: - ds:si = указатель на имя файла - es:bx = указатель на начало данных папки - es:dx = указатель на конец данных папки -на выходе: - CF сброшен, если найден финальный фрагмент файла - (и дальше сканировать папку не нужно) - в область для информации о фрагментах файла записывается найденное -В цикле просматривает все входы папки, пропуская те, у которых установлен - бит Associated (это специальные входы, дополняющие основные). Если - имя очередного входа совпадает с именем файла, то запоминает новый - фрагмент. Если фрагмент финальный (не установлен бит Multi-Extent), - то код выходит с CF=0. Если достигнут конец данных, то код выходит - с CF=1. Если очередной вход нулевой (первый байт настоящего входа - содержит длину и не может быть нулём), то процедура переходит к - рассмотрению следующего логического блока. При этом потенциально - возможно переполнение при добавлении размера блока; поскольку такой - сценарий означает, что процедура вызвана для кэшированной папки - с размером почти 64K и началом данных bx=0 (это свойство вызывающего - кода), а размер блока - степень двойки, то после переполнения всегда - bx=0, так что это можно обнаружить по взведённому ZF после сложения; - в этом случае также происходит выход (а после переполнения CF=1). - -Процедура перевода логического блока в номер сектора: -на входе: eax = логический блок -на выходе: eax = физический сектор, dx = номер логического блока в секторе -Осуществляет обычное деление 32-битного числа на 32-битное (число логических - блоков в секторе, хранящееся во внутренней переменной). - -Процедура загрузки физического сектора, содержащего указанный логический блок - (load_phys_sector_for_lb_force): -на входе: eax = логический блок; - si - индикатор, задающий, следует ли читать данные в случае, - если логический блок начинается с начала физического: - si = 0 - не нужно, si ненулевой - нужно -на выходе: - физический сектор загружен по адресу 0000:1000 - si указывает на данные логического блока - CF установлен при ошибке чтения -Преобразует предыдущей процедурой номер логического блока в номер физического - сектора и номер логического блока внутри сектора; если последняя - величина нулевая и никаких действий в этом случае не запрошено (si=0), - то ничего и не делает; иначе устанавливает si в соответствии с ней - и читает сектор. - -Процедуры чтения нужного числа байт из непрерывной цепочки логических блоков - (read_many_bytes и read_many_bytes.with_first): -на входе: - eax = логический блок - esi = число байт для чтения - es:bx = указатель на начало буфера, куда будут прочитаны данные - cur_limit = размер буфера (не меньше esi) -на выходе: - es:bx указывает на конец буфера, в который были прочитаны данные - если произошла ошибка чтения, флаг CF установлен - cur_limit соответствующим образом уменьшен -Отличие двух процедур: вторая дополнительно принимает во внимание переменную - [first_byte], начиная чтение первого блока со смещения [first_byte]; - соответственно, первая читает блок с начала, обнуляя [first_byte] - при входе. -1. Отдельно считывает первый физический сектор во временную область 0000:1000, - если первый логический блок начинается не с начала сектора. При - ошибке чтения выходит из процедуры. -2. Пересылает нужную часть данных (возможно, 0 байт), прочитанных в п.1, - в буфер. Нормализует указатель на буфер. -3. Если все необходимые данные уже прочитаны, выходит из процедуры. -4. Дальнейшие данные находятся в нескольких физических секторах, при этом, - возможно, последний сектор считывать нужно не целиком. -5. Если в буфере есть место для считывания всех секторов, то сразу читаются - все сектора, после чего указатель на буфер нужным образом уменьшается. -6. Если же нет, то считываются все сектора, кроме последнего, после чего - последний сектор считывается отдельно во временную область, и уже - оттуда нужная часть данных копируется в буфер. diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/build.bat b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/build.bat deleted file mode 100644 index 93b242702..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/cdfs/build.bat +++ /dev/null @@ -1,2 +0,0 @@ -@fasm -m 65535 bootsect.asm bootsect.bin -@pause \ No newline at end of file diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/config.ini b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/config.ini deleted file mode 100644 index 1db4d25fa..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/config.ini +++ /dev/null @@ -1,15 +0,0 @@ -; boot time parameters for KolibriOS - -; timeout in seconds for config settings screen -timeout=5 - -; width*height -;resolution=1024*768 - -; where to load ramdisk from -; 2 - /hd0/1/kolibri.img -; 3 - don't load ramdisk -;imgfrom=3 - -; which directory to use as /sys -;syspath=/HD0/1/KOLIBRIOS diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/Tupfile.lua b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/Tupfile.lua deleted file mode 100644 index d9aa6800c..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/Tupfile.lua +++ /dev/null @@ -1,3 +0,0 @@ -if tup.getconfig("NO_FASM") ~= "" then return end -tup.rule("bootsect.asm", "fasm %f %o", "bootsect.bin") -tup.rule("kordldr.f1x.asm", "fasm %f %o", "kordldr.f1x.bin") diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/bootsect.asm b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/bootsect.asm deleted file mode 100644 index 9b84a85e8..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/bootsect.asm +++ /dev/null @@ -1,392 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -use_lba = 0 - org 0x7C00 - jmp start - nop -; FAT parameters, BPB -; note: they can be changed at install, replaced with real values -; these settings are for most typical 1.44M floppies - db 'KOLIBRI ' ; BS_OEMName, ignored - dw 200h ; BPB_BytsPerSec -BPB_SecsPerClus db 1 -BPB_RsvdSecCnt dw 1 -BPB_NumFATs db 2 -BPB_RootEntCnt dw 0xE0 - dw 2880 ; BPB_TotSec16 - db 0xF0 ; BPB_Media -BPB_FATSz16 dw 9 -BPB_SecPerTrk dw 18 -BPB_NumHeads dw 2 -BPB_HiddSec dd 0 - dd 0 ; BPB_TotSec32 -BS_DrvNum db 0 - db 0 ; BS_Reserved1 - db ')' ; BS_BootSig - dd 12344321h ; BS_VolID -filename: - db 'KORD.OS ' ; BS_VolLab - db 'FAT12 ' ; BS_FilSysType -; Used memory map: -; 8000:0000 - current directory -; 9000:0000 - root directory data [cached] -start: - xor ax, ax - mov ss, ax - mov sp, 0x7C00 - mov ds, ax - mov bp, sp - cld - sti - mov [bp+BS_DrvNum-0x7C00], dl -if use_lba - mov ah, 41h - mov bx, 55AAh - int 13h - mov si, aNoLBA - jc err_ - cmp bx, 0AA55h - jnz err_ - test cx, 1 - jz err_ -else - mov ah, 8 - int 13h - jc @f ; on error, assume that BPB geometry is valid - mov al, dh - mov ah, 0 - inc ax - mov [bp+BPB_NumHeads-0x7C00], ax - and cx, 3Fh - mov [bp+BPB_SecPerTrk-0x7C00], cx -@@: -end if -; get FAT parameters - xor bx, bx - mov al, [bp+BPB_NumFATs-0x7C00] - mov ah, 0 - mul [bp+BPB_FATSz16-0x7C00] - add ax, [bp+BPB_RsvdSecCnt-0x7C00] - adc dx, bx - push dx - push ax ; root directory start = dword [bp-4] - mov cx, [bp+BPB_RootEntCnt-0x7C00] - add cx, 0xF - rcr cx, 1 - shr cx, 3 ; cx = size of root directory in sectors - add ax, cx - adc dx, bx - push dx - push ax ; data start = dword [bp-8] -; load start of root directory (no more than 0x2000 bytes = 0x10 sectors) - cmp cx, 0x10 - jb @f - mov cx, 0x10 -@@: - mov ax, [bp-4] - mov dx, [bp-2] - push 0x9000 - pop es - call read_sectors - add word [bp-4], cx ; dword [bp-4] = start of non-cached root data - adc word [bp-2], bx -; load kordldr.f12 - mov si, main_loader - call lookup_in_root_dir - jc noloader - test byte [es:di+11], 10h ; directory? - jz kordldr_ok -noloader: - mov si, aLoaderNotFound -err_: - call out_string - mov si, aPressAnyKey - call out_string - xor ax, ax - int 16h - int 18h - jmp $ -kordldr_ok: - mov ax, [es:di+26] ; get file cluster - mov bx, 0x7E00 - xor cx, cx - mov es, cx - sub ax, 2 - jc noloader - push bx ; save return address: bx = 7E00 - mov cl, [bp+BPB_SecsPerClus-0x7C00] - mul cx -; fall through - 'ret' in read_sectors will return to 7E00 - -read_sectors2: -; same as read_sectors, but dx:ax is relative to start of data - add ax, [bp-8] - adc dx, [bp-6] -read_sectors: -; ss:bp = 0:7C00 -; es:bx = pointer to data -; dx:ax = first sector -; cx = number of sectors - pusha - add ax, word [bp+BPB_HiddSec-0x7C00] - adc dx, word [bp+BPB_HiddSec+2-0x7C00] -if use_lba - push ds -do_read_sectors: - push ax - push cx - push dx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F -@@: -; create disk address packet on the stack -; dq starting LBA - push 0 - push 0 - push dx - push ax -; dd buffer - push es - push bx -; dw number of blocks to transfer (no more than 0x7F) - push cx -; dw packet size in bytes - push 10h -; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [bp+BS_DrvNum-0x7C00] - mov ah, 42h - int 13h - mov si, aReadError - jc err_ -; restore stack - add sp, 10h -; increase current sector & buffer; decrease number of sectors - mov si, cx - mov ax, es - shl cx, 5 - add ax, cx - mov es, ax - pop dx - pop cx - pop ax - add ax, si - adc dx, 0 - sub cx, si - jnz do_read_sectors - pop ds - popa - ret -else -do_read_sectors: - pusha - pop di - push bx - -; (dword in dx:ax) / (SectorsPerTrack) -> (dword in dx:ax), remainder bx - mov si, ax - xchg ax, dx - xor dx, dx - div [bp+BPB_SecPerTrk-0x7C00] - push ax - mov ax, si - div [bp+BPB_SecPerTrk-0x7C00] - mov bx, dx ; bx=sector-1 - pop dx - -; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx - div [bp+BPB_NumHeads-0x7C00] - -; number of sectors: read no more than to end of track - push bx - sub bx, [bp+BPB_SecPerTrk-0x7C00] - neg bx - cmp cx, bx - jbe @f - mov cx, bx -@@: - pop bx - - inc bx -; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format - mov di, cx - mov dh, dl - mov dl, [bp+BS_DrvNum-0x7C00] - shl ah, 6 - mov ch, al - mov al, cl - mov cl, bl - or cl, ah - pop bx - mov si, 3 - mov ah, 2 -@@: - push ax - int 13h - jnc @f - xor ax, ax - int 13h ; reset drive - pop ax - dec si - jnz @b - mov si, aReadError - jmp err_ -@@: - pop ax - mov ax, es - mov cx, di - shl cx, 5 - add ax, cx - mov es, ax - push di - popa - add ax, di - adc dx, 0 - sub cx, di - jnz do_read_sectors - popa - ret -end if - -scan_for_filename: -; in: ds:si -> 11-bytes FAT name -; in: es:0 -> part of directory data -; in: cx = number of entries -; out: if found: CF=0, ZF=1, es:di -> directory entry -; out: if not found, but continue required: CF=1 and ZF=0 -; out: if not found and zero item reached: CF=1 and ZF=1 - xor di, di - push cx -sloop: - cmp byte [es:di], 0 - jz snotfound - test byte [es:di+11], 8 ; volume label? - jnz scont ; ignore volume labels - pusha - mov cx, 11 - repz cmpsb - popa - jz sdone -scont: - add di, 0x20 - loop sloop - inc cx ; clear ZF flag -snotfound: - stc -sdone: - pop cx -lrdret: - ret - -lookup_in_root_dir: -; ss:bp = 0:7C00 -; in: ds:si -> 11-bytes FAT name -; out: if found: CF=0, es:di -> directory entry -; out: if not found: CF=1 - mov cx, [bp+BPB_RootEntCnt-0x7C00] - push cx -; first, look in root directory cache - push 0x9000 - pop es - test ch, ch - jz @f - mov cx, 0x100 -@@: - mov ax, [bp-4] - mov dx, [bp-2] ; dx:ax = starting sector of not cached data of root directory -lrdloop: - call scan_for_filename - pop bx - jz lrdret - sub bx, cx - mov cx, bx - stc - jz lrdret -; read no more than 0x10000 bytes, or 0x10000/0x20 = 0x800 entries - push cx - cmp ch, 0x8 - jb @f - mov cx, 0x800 -@@: - push 0x8000 - pop es - push cx - push es - xor bx, bx - add cx, 0xF - shr cx, 4 - call read_sectors - pop es - add ax, cx - adc dx, bx - pop cx - jmp lrdloop - -out_string: -; in: ds:si -> ASCIIZ string - lodsb - test al, al - jz lrdret - mov ah, 0Eh - mov bx, 7 - int 10h - jmp out_string - -aReadError db 'Read error',0 -if use_lba -aNoLBA db 'The drive does not support LBA!',0 -end if -aLoaderNotFound db 'Loader not found',0 -aPressAnyKey db 13,10,'Press any key...',13,10,0 -main_loader db 'KORDLDR F1X' - -if use_lba - db 0 ; make bootsector 512 bytes in length -end if - -; bootsector signature - dw 0xAA55 - -; display offsets of all procedures used by kordldr.f12.asm -macro show [procedure] -{ - bits = 16 - display `procedure,' = ' - repeat bits/4 - d = '0' + procedure shr (bits - %*4) and 0Fh - if d > '9' - d = d + 'A'-'9'-1 - end if - display d - end repeat - display 13,10 -} - -show read_sectors, read_sectors2, lookup_in_root_dir, scan_for_filename, err_, noloader diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/bootsect.txt b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/bootsect.txt deleted file mode 100644 index c0449aa69..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/bootsect.txt +++ /dev/null @@ -1,360 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - Встречаются вирус и FAT. - - Привет, ты кто? - - Я? Вирус. - - A я AFT, то есть TAF, то есть FTA, черт, совсем запутался... - -Бутсектор для FAT12/FAT16-тома на носителе с размером сектора 0x200 = 512 байт. - -===================================================================== - -Есть две версии в зависимости от того, поддерживает ли носитель LBA, -выбор осуществляется установкой константы use_lba в первой строке исходника. -Требования для работы: -1) Сам бутсектор, первая копия FAT и все используемые файлы -должны быть читабельны. -2) Минимальный процессор - 80186. -3) В системе должно быть как минимум 592K свободной базовой памяти. - -===================================================================== - -Документация в тему (ссылки валидны на момент написания этого файла, 15.05.2008): - официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx - в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf - русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip - официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf - то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf - описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html - официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf - -===================================================================== - -Максимальное количество кластеров на FAT12-томе - 0xFF4 = 4084; каждый кластер -занимает 12 бит в таблице FAT, так что общий размер не превосходит -0x17EE = 6126 байт. Вся таблица помещается в памяти. -Максимальное количество кластеров на FAT16-томе - 0xFFF4 = 65524; каждый -кластер занимает 16 бит в таблице FAT, так что общий размер не превосходит -0x1FFE8 = 131048 байт. Вся таблица также помещается в памяти, однако в -этом случае несколько нецелесообразно считывать всю таблицу, поскольку -на практике нужна только небольшая её часть. Поэтому место в памяти -резервируется, но данные считываются только в момент, когда к ним -действительно идёт обращение. - -Схема используемой памяти: - ...-7C00 стек - 7C00-7E00 код бутсектора - 7E00-8200 вспомогательный файл загрузчика (kordldr.f1x) - 8200-8300 список загруженных секторов таблицы FAT16 - (1 = соответствующий сектор загружен) - 60000-80000 загруженная таблица FAT12 / место для таблицы FAT16 - 80000-90000 текущий кластер текущей рассматриваемой папки - 90000-92000 кэш для корневой папки - 92000-... кэш для некорневых папок (каждой папке отводится - 2000h байт = 100h входов, одновременно в кэше - может находиться не более 7 папок; - точный размер определяется размером доступной - физической памяти - как правило, непосредственно - перед A0000 размещается EBDA, Extended BIOS Data Area) - -===================================================================== - -Основной процесс загрузки. -Точка входа (start): получает управление от BIOS при загрузке, при этом - dl содержит идентификатор диска, с которого идёт загрузка -1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед - кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало - бутсектора (в дальнейшем данные будут адресоваться через [bp+N] - - это освобождает ds и экономит на размере кода). -2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h - прерывания 13h. Если нет, переходит на код обработки ошибок с - сообщением об отсутствии LBA. -CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и - записывает полученные данные поверх BPB. Если вызов завершился ошибкой, - предполагает уже существующие данные корректными. -3. Вычисляет некоторые параметры FAT-тома: начальный сектор корневой папки - и начальный сектор данных. Кладёт их в стек; впоследствии они - всегда будут лежать в стеке и адресоваться через bp. -4. Считывает начало корневой папки по адресу 9000:0000. Число считываемых - секторов - минимум из размера корневой папки, указанного в BPB, и 16 - (размер кэша для корневой папки - 2000h байт = 16 секторов). -5. Ищет в корневой папке элемент kordldr.f1x. Если не находит, или если - он оказывается папкой, или если файл имеет нулевую длину - - переходит на код обработки ошибок с сообщением о - ненайденном загрузчике. - Замечание: на этом этапе загрузки искать можно только в корневой - папке и только имена, заданные в формате файловой системе FAT - (8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны - быть заглавными, при необходимости имя и расширение дополняются - пробелами, разделяющей точки нет, завершающего нуля нет). -6. Загружает первый кластер файла kordldr.f1x по адресу 0:7E00 и передаёт - ему управление. При этом в регистрах dx:ax оказывается абсолютный - номер первого сектора kordldr.f1x, а в cx - число считанных секторов - (равное размеру кластера). - -Вспомогательные процедуры бутсектора. -Код обработки ошибок (err): -1. Выводит строку с сообщением об ошибке. -2. Выводит строку "Press any key...". -3. Ждёт нажатия any key. -4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. -5. Для подстраховки зацикливается. - -Процедура чтения секторов (read_sectors и read_sectors2): -на входе должно быть установлено: - ss:bp = 0:7C00 - es:bx = указатель на начало буфера, куда будут прочитаны данные - dx:ax = стартовый сектор (относительно начала логического диска - для read_sectors, относительно начала данных для read_sectors2) - cx = число секторов (должно быть больше нуля) -на выходе: es:bx указывает на конец буфера, в который были прочитаны данные -0. Если вызывается read_sectors2, она переводит указанный ей номер сектора - в номер относительно начала логического диска, прибавляя номер сектора - начала данных, хранящийся в стеке как [bp-8]. -1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на - устройстве, прибавляя значение соответствующего поля из BPB. -2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации - CHS-версия: все читаемые секторы были на одной дорожке. - LBA-версия: число читаемых секторов не превосходило 7Fh (требование - спецификации EDD BIOS). -CHS-версия: -3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как - единица плюс остаток от деления абсолютного номера на число секторов - на дорожке; дорожка рассчитывается как остаток от деления частного, - полученного на предыдущем шаге, на число дорожек, а цилиндр - как - частное от этого же деления. Если число секторов для чтения больше, - чем число секторов до конца дорожки, уменьшает число секторов для - чтения. -4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, - dh=головка, (младшие 6 бит cl)=сектор, - (старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска - и повторяет попытку чтения, всего делается не более трёх попыток - (несколько попыток нужно в случае дискеты для гарантии того, что - мотор раскрутился). Если все три раза происходит ошибка чтения, - переходит на код обработки ошибок с сообщением "Read error". -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. -LBA-версия: -3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей - итерации) до 7Fh. -4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами - push, причём в обратном порядке: стек - структура LIFO, и данные в - стеке хранятся в обратном порядке по отношению к тому, как их туда - клали). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки - ошибок с сообщением "Read error". Очищает стек от пакета, - сформированного на предыдущем шаге. -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. - -Процедура поиска элемента по имени в уже прочитанных данных папки - (scan_for_filename): -на входе должно быть установлено: - ds:si = указатель на имя файла в формате FAT (11 байт, 8 на имя, - 3 на расширение, все буквы заглавные, если имя/расширение - короче, оно дополняется до максимума пробелами) - es = сегмент данных папки - cx = число элементов в прочитанных данных -на выходе: ZF определяет, нужно ли продолжать разбор данных папки - (ZF=1, если либо найден запрошенный элемент, либо достигнут - конец папки); CF определяет, удалось ли найти элемент с искомым именем - (CF=1, если не удалось); если удалось, то es:di указывает на него. -scan_for_filename считает, что данные папки размещаются начиная с es:0. -Первой командой процедура обнуляет di. Затем просто в цикле по элементам папки -проверяет имена. - -Процедура поиска элемента в корневой папке (lookup_in_root_dir): -на входе должно быть установлено: - ss:bp = 0:7C00 - ds:si = указатель на имя файла в формате FAT (см. выше) -на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то - CF сброшен и es:di указывает на элемент папки -Начинает с просмотра кэшированной (начальной) части корневой папки. В цикле - сканирует элементы; если по результатам сканирования обнаруживает, - что нужно читать папку дальше, то считывает не более 0x10000 = 64K - байт (ограничение введено по двум причинам: во-первых, чтобы заведомо - не вылезти за пределы используемой памяти, во-вторых, сканирование - предполагает, что все обрабатываемые элементы располагаются в одном - сегменте) и продолжает цикл. -Сканирование прекращается в трёх случаях: обнаружен искомый элемент; - кончились элементы в папке (судя по числу элементов, указанному в BPB); - очередной элемент папки сигнализирует о конце (первый байт нулевой). - -Процедура вывода на экран ASCIIZ-строки (out_string): -на входе: ds:si -> строка -В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. - -===================================================================== - -Работа вспомогательного загрузчика kordldr.f1x: -1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора. - В зависимости от этого устанавливает смещения используемых процедур - бутсектора. Критерий проверки: scan_for_filename должна начинаться - с инструкции 'xor di,di' с кодом 31 FF (вообще-то эта инструкция может - с равным успехом ассемблироваться и как 33 FF, но fasm генерирует - именно такую форму). -2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска - адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с - ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента - место должно быть, отсюда ограничение в 592 Kb (94000h байт). - Замечание: этот размер не может превосходить 0A0000h байт и - на практике оказывается немного (на 1-2 килобайта) меньшим из-за - наличия дополнительной области данных BIOS "вверху" базовой памяти. -3. Определяет тип файловой системы: FAT12 или FAT16. Согласно официальной - спецификации от Microsoft (версия 1.03 спецификации датирована, - к слову, 06 декабря 2000 года), разрядность FAT определяется - исключительно числом кластеров: максимальное число кластеров на - FAT12-томе равно 4094 = 0xFF4. Согласно здравому смыслу, на FAT12 - может быть 0xFF5 кластеров, но не больше: кластеры нумеруются с 2, - а число 0xFF7 не может быть корректным номером кластера. - Win95/98/Me следует здравому смыслу: разграничение FAT12/16 делается - по максимуму 0xFF5. Драйвер FAT в WinNT/2k/XP/Vista вообще поступает - явно неверно, считая, что 0xFF6 (или меньше) кластеров означает - FAT12-том, в результате получается, что последний кластер - (в случае 0xFF6) неадресуем. Основной загрузчик osloader.exe - [встроен в ntldr] для NT/2k/XP делает так же. Первичный загрузчик - [бутсектор FAT12/16 загружает первый сектор ntldr, и разбор FAT-таблицы - лежит на нём] в NT/2k подвержен той же ошибке. В XP её таки исправили - в соответствии со спецификацией. Linux при определении FAT12/FAT16 - честно следует спецификации. - Здесь код основан всё же на спецификации. 9x мертва, а в линейке NT - Microsoft если и будет исправлять ошибки, то согласно собственному - описанию. -4. Для FAT12: загружает в память первую копию таблицы FAT по адресу 6000:0000. - Если размер, указанный в BPB, превосходит 12 секторов, - это означает, что заявленный размер слишком большой (это не считается - ошибкой файловой системы), и читаются только 12 секторов (таблица FAT12 - заведомо влезает в такой объём данных). -Для FAT16: инициализирует внутренние данные, указывая, что никакой сектор - FAT не загружен (они будут подгружаться позднее, когда понадобятся - и только те, которые понадобятся). -5. Если кластер равен сектору, то бутсектор загрузил только часть файла - kordldr.f1x, и загрузчик подгружает вторую свою часть, используя - значения регистров на входе в kordldr.f1x. -6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не - найден, или оказался папкой, или оказался слишком большим, то переходит - на код обработки ошибок из бутсектора с сообщением - "Fatal error: cannot load the secondary loader". - Замечание: на этом этапе имя файла уже можно указывать вместе с путём - и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов - по-прежнему нет. -7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err. - Это нужно, чтобы последующие обращения к коду бутсектора в случае - ошибок чтения не выводил соответствующее сообщение с последующей - перезагрузкой, а рапортовал об ошибке чтения, которую мог бы - как-нибудь обработать вторичный загрузчик. -8. Если загрузочный диск имеет идентификатор меньше 0x80, - то устанавливает al='f' ("floppy"), ah=идентификатор диска, - иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска). - Устанавливает bx='12', если тип файловой системы - FAT12, и - bx='16' в случае FAT16. Устанавливает si=смещение функции обратного - вызова. Поскольку в этот момент ds=0, то ds:si образуют полный адрес. -9. Передаёт управление по адресу 1000:0000. - -Функция обратного вызова для вторичного загрузчика: - предоставляет возможность чтения файла. -Вход и выход описаны в спецификации на загрузчик. -1. Сохраняет стек вызывающего кода и устанавливает свой стек: - ss:sp = 0:(7C00-8), bp=7C00: пара ss:bp при работе с остальным - кодом должна указывать на 0:7C00, а -8 берётся от того, что - инициализирующий код бутсектора уже поместил в стек 2 двойных слова, - и они должны сохраняться в неизменности. -2. Разбирает переданные параметры, выясняет, какое действие запрошено, - и вызывает нужную вспомогательную процедуру. -3. Восстанавливает стек вызывающего кода и возвращает управление. - -Вспомогательные процедуры kordldr.f1x. -Процедура получения следующего кластера в FAT (get_next_cluster): -1. Вспоминает разрядность FAT, вычисленную ранее. -Для FAT12: -2. Устанавливает ds = 0x6000 - сегмент, куда ранее была считана - вся таблица FAT. -3. Подсчитывает si = (кластер) + (кластер)/2 - смещение в этом сегменте - слова, задающего следующий кластер. Загружает слово по этому адресу. -4. Если кластер имеет нечётный номер, то соответствующий ему элемент - располагается в старших 12 битах слова, и слово нужно сдвинуть вправо - на 4 бита; в противном случае - в младших 12 битах, и делать ничего не - надо. -5. Выделяет из получившегося слова 12 бит. Сравнивает их с пределом 0xFF7: - номера нормальных кластеров меньше, и флаг CF устанавливается; - специальные значения EOF и BadClus сбрасывают флаг CF. -Для FAT16: -2. Вычисляет адрес памяти, предназначенной для соответствующего сектора данных - в таблице FAT. -3. Если сектор ещё не загружен, то загружает его. -4. Вычисляет смещение данных для конкретного кластера относительно начала - сектора. -5. Загружает слово в ax из адреса, вычисленному на шагах 1 и 3. -6. Сравнивает его с пределом 0xFFF7: номера нормальных кластеров меньше, и флаг - CF устанавливается; специальные значения EOF и BadClus сбрасывают CF. - -Процедура загрузки файла (load_file): -1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4. -2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты - разделяются символом '/') в FAT-формат 8+3. Если это невозможно - (больше 8 символов в имени, больше 3 символов в расширении или - больше одной точки), возвращается с ошибкой. -3. Ищет элемент с таким именем в текущей рассматриваемой папке. Для корневой - папки используется процедура из бутсектора. Для остальных папок: - a) Проверяет, есть ли такая папка в кэше некорневых папок. - (Идентификация папок осуществляется по номеру начального кластера.) - Если такой папки ещё нет, добавляет её в кэш; если тот переполняется, - выкидывает папку, к которой дольше всего не было обращений. (Для - каждого элемента кэша хранится метка от 0 до (размер кэша)-1, - определяющая его номер при сортировке по давности последнего обращения. - При обращении к какому-то элементу его метка становится нулевой, - а те метки, которые меньше старого значения, увеличиваются на единицу.) - б) Просматривает в поисках запрошенного имени все элементы из кэша, - используя процедуру из бутсектора. Если обнаруживает искомый элемент, - переходит к шагу 4. Если обнаруживает конец папки, возвращается из - процедуры с ошибкой. - в) В цикле считывает папку посекторно. При этом пропускает начальные - секторы, которые уже находятся в кэше и уже были просмотрены. Каждый - прочитанный сектор копирует в кэш, если там ещё остаётся место, - и просматривает в нём все элементы. Работает, пока не случится одно из - трёх событий: найден искомый элемент; кончились кластеры (судя по - цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце - (первый байт нулевой). В двух последних случаях возвращается с ошибкой. -4. Проверяет тип найденного элемента (файл/папка): последний элемент в - запрошенном имени должен быть файлом, все промежуточные - папками. - Если текущий компонент имени - промежуточный, продвигает текущую - рассматриваемую папку и возвращается к пункту 2. -5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный - при вызове буфер последовательными вызовами функции бутсектора; - при этом если несколько кластеров файла расположены на диске - последовательно, то их чтение объединяется в одну операцию. - Следит за тем, чтобы не превысить указанный при вызове процедуры - лимит числа секторов для чтения. - -Процедура продолжения загрузки файла (continue_load_file): встроена - внутрь шага 5 load_file; загружает в регистры нужные значения (ранее - сохранённые из load_file) и продолжает шаг 5. diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/build.bat b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/build.bat deleted file mode 100644 index 17c30cac1..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/build.bat +++ /dev/null @@ -1,3 +0,0 @@ -@fasm -m 65535 bootsect.asm bootsect.bin -@fasm -m 65535 kordldr.f1x.asm kordldr.f1x -@pause \ No newline at end of file diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/kordldr.f1x.asm b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/kordldr.f1x.asm deleted file mode 100644 index d5724bc89..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat1x/kordldr.f1x.asm +++ /dev/null @@ -1,689 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - org 0x7E00 -; the KordOS FAT12/FAT16 bootsector loads first cluster of this file to 0:7E00 and transfers control to here -; ss:bp = 0:7C00 -virtual at bp - rb 3 ; BS_jmpBoot - rb 8 ; BS_OEMName, ignored - dw ? ; BPB_BytsPerSec -BPB_SecsPerClus db ? -BPB_RsvdSecCnt dw ? -BPB_NumFATs db ? -BPB_RootEntCnt dw ? -BPB_TotSec16 dw ? - db ? ; BPB_Media -BPB_FATSz16 dw ? -BPB_SecPerTrk dw ? -BPB_NumHeads dw ? -BPB_HiddSec dd ? -BPB_TotSec32 dd ? -BS_DrvNum db ? -fat_type db ? ; this is BS_Reserved1, - ; we use it to save FS type: 0=FAT12, 1=FAT16 - db ? ; BS_BootSig -num_sectors dd ? ; BS_VolID -; rb 11 ; BS_VolLab -; rb 3 ; BS_FilSysType, first 3 bytes -read_sectors dw ? -read_sectors2 dw ? -lookup_in_root_dir dw ? -scan_for_filename dw ? -err_ dw ? -noloader dw ? -cachelimit dw ? -filesize: ; will be used to save file size - rb 5 ; BS_FilSysType, last 5 bytes -; following variables are located in the place of starting code; -; starting code is no more used at this point -sect_per_clus dw ? -cur_cluster dw ? -next_cluster dw ? -flags dw ? -cur_delta dd ? -end virtual - -; procedures from boot sector -; LBA version -lba_read_sectors = 7CE2h -lba_read_sectors2 = 7CDCh -lba_lookup_in_root_dir = 7D4Fh -lba_scan_for_filename = 7D2Dh -lba_err = 7CB5h -lba_noloader = 7CB2h -; CHS version -chs_read_sectors = 7CDEh -chs_read_sectors2 = 7CD8h -chs_lookup_in_root_dir = 7D70h -chs_scan_for_filename = 7D4Eh -chs_err = 7CB1h -chs_noloader = 7CAEh - - push ax cx ; save our position on disk - push ss - pop es -; determine version of bootsector (LBA vs CHS) -; mov [read_sectors], chs_read_sectors -; mov [read_sectors2], chs_read_sectors2 -; mov [lookup_in_root_dir], chs_lookup_in_root_dir -; mov [scan_for_filename], chs_scan_for_filename -; mov [err], chs_err -; mov [noloader], chs_noloader - lea di, [read_sectors] - mov si, chs_proc_addresses - mov cx, 6*2 - cmp word [chs_scan_for_filename], 0xFF31 ; 'xor di,di' - jz @f - add si, cx -; mov [read_sectors], lba_read_sectors -; mov [read_sectors2], lba_read_sectors2 -; mov [lookup_in_root_dir], lba_lookup_in_root_dir -; mov [scan_for_filename], lba_scan_for_filename -; mov [err], lba_err -; mov [noloader], lba_noloader -@@: - rep movsb - mov cl, [BPB_SecsPerClus] - mov [sect_per_clus], cx - xor bx, bx -; determine size of cache for folders - int 12h ; ax = size of available base memory in Kb - sub ax, 94000h / 1024 - jae @f -nomem: - mov si, nomem_str - jmp [err_] -@@: - shr ax, 3 - mov [cachelimit], ax ; size of cache - 1 -; get type of file system - FAT12 or FAT16? -; calculate number of clusters - mov ax, [BPB_TotSec16] - xor dx, dx - test ax, ax - jnz @f - mov ax, word [BPB_TotSec32] - mov dx, word [BPB_TotSec32+2] -@@: - sub ax, [bp-8] ; dword [bp-8] = first data sector - sbb dx, [bp-6] - jb j_noloader - div [sect_per_clus] -; ax = number of clusters -; note: this is loader for FAT12/FAT16, so 'div' does not overflow on correct volumes - mov [fat_type], ch - cmp ax, 0xFF5 - jb init_fat12 - inc [fat_type] -init_fat16: -; no sectors loaded - mov di, 0x8200 - xor ax, ax - mov cx, 0x100/2 - rep stosw - jmp init_fat_done -init_fat12: -; read FAT - push 0x6000 - pop es - mov ax, [BPB_RsvdSecCnt] - mov cx, [BPB_FATSz16] - cmp cx, 12 - jb @f - mov cx, 12 -@@: - xor dx, dx - call [read_sectors] -init_fat_done: -; if cluster = sector, we need to read second part of our file -; (bootsector loads only first cluster of kordldr.f1x) - pop cx ax ; restore our position on disk - cmp cx, 1 - ja kordldr_full - sub ax, [bp-8] - inc ax - inc ax ; ax = first cluster of kordldr.f12 - call get_next_cluster - jc @f -j_noloader: - jmp [noloader] -@@: - dec ax - dec ax - push 0x800 - pop es - call [read_sectors2] -kordldr_full: -; ...continue loading... - mov di, secondary_loader_info - call load_file - test bx, bx - mov bx, [err_] - jz @f - mov si, aKernelNotFound - jmp bx -@@: -; for subsequent calls to callback function, hook error handler -; mov byte [bx], 0xE9 ; 'jmp' opcode -; mov ax, hooked_err - 3 -; sub ax, bx -; mov word [bx+1], ax -; push hooked_err / ret - mov word [bx], 0x68 + ((hooked_err and 0xFF) shl 8) - mov word [bx+2], (hooked_err shr 8) + (0xC3 shl 8) -; set registers for secondary loader - mov ah, [BS_DrvNum] - mov al, 'f' - test ah, ah - jns @f - sub ah, 80h - mov al, 'h' -@@: - mov bx, '12' - cmp [fat_type], 0 - jz @f - mov bh, '6' -@@: - mov si, callback ; ds:si = far pointer to callback procedure - jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000 - -nomem_str db 'No memory',0 - -chs_proc_addresses: - dw chs_read_sectors - dw chs_read_sectors2 - dw chs_lookup_in_root_dir - dw chs_scan_for_filename - dw chs_err - dw chs_noloader -lba_proc_addresses: - dw lba_read_sectors - dw lba_read_sectors2 - dw lba_lookup_in_root_dir - dw lba_scan_for_filename - dw lba_err - dw lba_noloader - -get_next_cluster: -; in: ax = cluster -; out: if there is next cluster: CF=1, ax = next cluster -; out: if there is no next cluster: CF=0 - push si - cmp [fat_type], 0 - jnz gnc16 -; for FAT12 - push ds - push 0x6000 - pop ds - mov si, ax - shr si, 1 - add si, ax - test al, 1 - lodsw - jz @f - shr ax, 4 -@@: - and ax, 0xFFF - cmp ax, 0xFF7 - pop ds si - ret -; for FAT16 -gnc16: -; each sector contains 200h bytes = 100h FAT entries -; so ah = # of sector, al = offset in sector - mov si, ax - mov ah, 0 - shr si, 8 -; calculate segment for this sector of FAT table -; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si) -; segment = 6000 + 20*si, offset = 0 - push es - push si - shl si, 5 - add si, 0x6000 - mov es, si - pop si - cmp byte [ss:0x8200+si], ah ; sector already loaded? - jnz @f -; load corresponding sector - pusha - push es - xor bx, bx - mov ax, [BPB_RsvdSecCnt] - xor dx, dx - add ax, si - adc dx, bx - mov cx, 1 ; read 1 sector - call [read_sectors] - pop es - popa -@@: - mov si, ax - add si, si -; mov ax, [es:si] - lods word [es:si] - pop es - cmp ax, 0xFFF7 - pop si - ret - -if $ > 0x8000 -error 'get_next_cluster must fit in first sector of kordldr.f1x!' -end if - -load_file: -; in: ss:bp = 0:7C00 -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) - xor ax, ax ; start from root directory - mov dx, -1 - mov word [filesize], dx - mov word [filesize+2], dx ; initialize file size with invalid value - lea si, [di+6] -parse_dir_loop: -; convert name to FAT name - push di - push ax - push ss - pop es -; convert ASCIIZ filename to FAT name - mov di, filename - push di - mov cx, 8+3 - mov al, ' ' - rep stosb - pop di - mov cl, 8 ; 8 symbols per name - mov bl, 1 -nameloop: - lodsb - test al, al - jz namedone - cmp al, '/' - jz namedone - cmp al, '.' - jz namedot - dec cx - js badname - cmp al, 'a' - jb @f - cmp al, 'z' - ja @f - sub al, 'a'-'A' -@@: - stosb - jmp nameloop -namedot: - inc bx - jp badname - add di, cx - mov cl, 3 - jmp nameloop -badname: ; do not make direct js/jp to notfound_pop: - ; this generates long forms of conditional jumps and results in longer code - jmp notfound_pop -namedone: -; scan directory - pop ax ; ax = cluster of directory or 0 for root - push ds - push si - push es - pop ds - mov si, filename ; ds:si -> filename in FAT style - test ax, ax - jnz lookup_in_notroot_dir -; for root directory, use the subroutine from bootsector - call [lookup_in_root_dir] - jmp lookup_done -lookup_in_notroot_dir: -; for other directories, read a folder sector-by-sector and scan -; first, try to use the cache - push ds - push cs - pop ds - mov bx, [cachelimit] - add bx, bx - mov di, foldcache_mark -@@: - mov dx, [foldcache_clus+di-foldcache_mark+bx] - cmp dx, ax - jz cacheok - test dx, dx - jz cacheadd ; the cache has place for new entry - dec bx - dec bx - jns @b -; the folder is not present in the cache, so add it -; the cache is full; find the oldest entry and replace it with the new one - mov dx, [cachelimit] -@@: - inc bx - inc bx - cmp word [di+bx], dx ; marks have values 0 through [cachelimit] - jnz @b -cacheadd: - or word [di+bx], 0xFFFF ; very big value, it will be changed soon - mov [foldcache_clus+di-foldcache_mark+bx], ax - and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet -cacheok: -; update cache marks - mov dx, [di+bx] - mov cx, [foldcache_size+di-foldcache_mark+bx] - mov di, [cachelimit] - add di, di -cacheupdate: - cmp [foldcache_mark+di], dx - adc [foldcache_mark+di], 0 - dec di - dec di - jns cacheupdate - and [foldcache_mark+bx], 0 -; done, bx contains (position in cache)*2 - pop ds -; mov dx, bx -; shl dx, 8 ; dx = (position in cache)*0x2000/0x10 -; add dx, 0x9200 - lea dx, [bx+0x92] - xchg dl, dh - mov es, dx - jcxz not_in_cache - call [scan_for_filename] - jz lookup_done -not_in_cache: -; cache miss, read folder data from disk - mov bx, cx - shr bx, 4 - shl cx, 5 - mov di, cx ; es:di -> free space in cache entry -; external loop: scan clusters -folder_next_cluster: -; internal loop: scan sectors in cluster - mov cx, [sect_per_clus] - push ax - dec ax - dec ax - mul cx - add ax, [bp-8] - adc dx, [bp-6] ; dx:ax = absolute sector -folder_next_sector: -; skip first bx sectors - dec bx - jns folder_skip_sector - push cx - push es di - push 0x8000 - pop es - xor bx, bx - mov cx, 1 - push es - call [read_sectors] -; copy data to the cache... - pop ds - pop di es - cmp di, 0x2000 ; ...if there is free space, of course - jae @f - push si di - mov cx, 0x100 - xor si, si - rep movsw - mov di, es - shr di, 8 - add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache - pop di si -@@: - push es - push 0x8000 - pop es - push cs - pop ds - mov cx, 0x10 - call [scan_for_filename] - pop es - pop cx - jz lookup_done_pop -folder_skip_sector: - inc ax - jnz @f - inc dx -@@: - loop folder_next_sector - pop ax ; ax = current cluster - call get_next_cluster - jc folder_next_cluster - stc - push ax -lookup_done_pop: - pop ax -lookup_done: - pop si - pop ds -; CF=1 <=> failed - jnc found -notfound: - pop di - mov bx, 2 ; file not found - mov ax, 0xFFFF - mov dx, ax ; invalid file size - ret -notfound_pop: - pop ax - jmp notfound -found: - mov ax, [es:di+26] ; get cluster - test byte [es:di+11], 10h ; directory? - jz regular_file - cmp byte [si-1], 0 - jz notfound ; don't read directories as a regular files -; ok, we have found a directory and the caller requested a file into it - pop di - jmp parse_dir_loop ; restart with new cluster in ax -regular_file: - cmp byte [si-1], 0 - jnz notfound ; file does not contain another files -; ok, we have found a regular file and the caller requested it -; save file size - mov dx, [es:di+28] - mov [filesize], dx - mov dx, [es:di+30] - mov [filesize+2], dx - pop di - mov si, [di+4] - shl si, 3 - push si ; [ds:di+4] = limit in 4K blocks - les bx, [di] ; es:bx -> buffer -clusloop: -; ax = first cluster, top of stack contains limit in sectors - mov si, ax ; remember current cluster - xor cx, cx ; cx will contain number of consecutive clusters - mov word [cur_delta], cx - mov word [cur_delta+2], cx - mov di, ax -clusfind: - inc di - inc cx - call get_next_cluster - jnc clusread - cmp ax, di - jz clusfind - stc -clusread: - pop di ; limit in sectors - push ax ; save next cluster - pushf ; save flags -; read cx clusters, starting from si -; calculate number of sectors - xchg ax, cx - mul [sect_per_clus] -; dx:ax = number of sectors; compare with limit - mov word [num_sectors], ax - mov word [num_sectors+2], dx - jmp @f -continue_load_file: - les bx, [di] ; es:bx -> buffer - mov di, [di+4] ; ds:di = limit in 4K blocks - shl di, 3 ; now di = limit in sectors - mov ax, word [num_sectors] - mov dx, word [num_sectors+2] - mov si, [cur_cluster] - push [next_cluster] - push [flags] - or ax, dx - jz nextclus -@@: - test dx, dx - jnz clusdecrease - push dx ; limit was not exceeded - cmp ax, di - jbe @f - pop ax -clusdecrease: - push 1 ; limit was exceeded - mov ax, di -@@: - sub di, ax ; calculate new limit - sub word [num_sectors], ax - sbb word [num_sectors+2], 0 -readloop: - push ax -; buffer should not cross a 64K boundary - push bx - shr bx, 4 - mov cx, es - add bx, cx - neg bx - and bh, 0xF - shr bx, 5 - jnz @f - mov bl, 0x80 -@@: - cmp ax, bx - jbe @f - xchg ax, bx -@@: - pop bx - xchg ax, cx -; calculate starting sector - lea ax, [si-2] - mul [sect_per_clus] - add ax, word [cur_delta] - adc dx, word [cur_delta+2] - add word [cur_delta], cx - adc word [cur_delta+2], 0 -; read - call [read_sectors2] - pop ax - sub ax, cx - jnz readloop - pop dx -; next cluster? -nextclus: - popf - pop ax - mov [cur_cluster], si - mov [next_cluster], ax - pushf - pop [flags] - jnc @f ; no next cluster => return - mov dl, 1 ; dh=0 in any case - test di, di - jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded - push di - jmp clusloop ; all is ok, continue -hooked_err: - mov sp, 7C00h-12-2 ; restore stack - mov dx, 3 ; return: read error -@@: - mov bx, dx - mov ax, [filesize] - mov dx, [filesize+2] - ret - -; Callback function for secondary loader -callback: -; in: ax = function number; only functions 1 and 2 are defined for now -; save caller's stack - mov dx, ss - mov cx, sp -; set our stack (required because we need ss=0) - xor si, si - mov ss, si - mov sp, 7C00h-8 - mov bp, 7C00h - push dx - push cx -; call our function - stc ; unsupported function - dec ax - jz callback_readfile - dec ax - jnz callback_ret -; function 2: continue loading file -; can be called only after function 1 returned value bx=1 (only part of file was loaded) -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error -; out: dx:ax = file size - call continue_load_file - jmp callback_ret_succ -callback_readfile: -; function 1: read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error -; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call load_file -callback_ret_succ: - clc ; function is supported -callback_ret: -; restore caller's stack - pop cx - pop ss - mov sp, cx -; return to caller - retf - -secondary_loader_info: - dw 0, 0x1000 - dw 0x30000 / 0x1000 - db 'kernel.mnt',0 -aKernelNotFound db 'Fatal error: cannot load the kernel',0 - -foldcache_clus dw 0,0,0,0,0,0,0 ; start with no folders in cache -foldcache_mark rw 7 -foldcache_size rw 7 -filename rb 11 -if $ > 0x8200 -error: - table overwritten -end if diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/Tupfile.lua b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/Tupfile.lua deleted file mode 100644 index 4b40451ef..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/Tupfile.lua +++ /dev/null @@ -1,3 +0,0 @@ -if tup.getconfig("NO_FASM") ~= "" then return end -tup.rule("bootsect.asm", "fasm %f %o", "bootsect.bin") -tup.rule("kordldr.f32.asm", "fasm %f %o", "kordldr.f32") diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/bootsect.asm b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/bootsect.asm deleted file mode 100644 index d93c7979a..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/bootsect.asm +++ /dev/null @@ -1,358 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -use_lba = 1 - org 0x7C00 - jmp start - nop -; FAT parameters, BPB -; they must be changed at install, replaced with real values - rb 8 ; BS_OEMName, ignored - dw 200h ; BPB_BytsPerSec -BPB_SecsPerClus db ? -BPB_RsvdSecCnt dw ? -BPB_NumFATs db ? -BPB_RootEntCnt dw ? - dw ? ; BPB_TotSec16 - db ? ; BPB_Media - dw ? ; BPB_FATSz16 = 0 for FAT32 -BPB_SecPerTrk dw ? -BPB_NumHeads dw ? -BPB_HiddSec dd ? - dd ? ; BPB_TotSec32 -BPB_FATSz32 dd ? -BPB_ExtFlags dw ? - dw ? ; BPB_FSVer -BPB_RootClus dd ? - dw ? ; BPB_FSInfo -BPB_BkBootSec dw ? - rb 12 ; BPB_Reserved -BS_DrvNum db ? - db ? ; BS_Reserved1 - db ? ; BS_BootSig - dd ? ; BS_VolID - rb 11 ; BS_VolLab - rb 8 ; - -curseg dw 0x8000 - -start: - xor ax, ax - mov ss, ax - mov sp, 0x7C00 - mov ds, ax - mov bp, sp - cld - sti - push dx ; byte [bp-2] = boot drive -if use_lba - mov ah, 41h - mov bx, 55AAh - int 13h - mov si, aNoLBA - jc err_ - cmp bx, 0AA55h - jnz err_ - test cl, 1 - jz err_ -else - mov ah, 8 - int 13h - jc @f - movzx ax, dh - inc ax - mov [bp+BPB_NumHeads-0x7C00], ax - and cx, 3Fh - mov [bp+BPB_SecPerTrk-0x7C00], cx -@@: -end if -; get FAT parameters - xor bx, bx - movzx eax, [bp+BPB_NumFATs-0x7C00] - mul [bp+BPB_FATSz32-0x7C00] - movzx ecx, [bp+BPB_RsvdSecCnt-0x7C00] - push ecx ; FAT start = dword [bp-6] - add eax, ecx - push eax ; data start = dword [bp-10] - ;push dword -1 ; dword [bp-14] = current sector for FAT cache - db 66h - push -1 ; dword [bp-14] = current sector for FAT cache - mov eax, [bp+BPB_RootClus-0x7C00] - mov si, main_loader - call lookup_in_dir - jnc kordldr_ok -noloader: - mov si, aLoaderNotFound -err_: - call out_string - mov si, aPressAnyKey - call out_string - xor ax, ax - int 16h - int 18h - jmp $ -kordldr_ok: - mov eax, [es:di+20-2] ; hiword(eax) = hiword(cluster) - mov ax, [es:di+26] ; loword(eax) = loword(cluster) - mov es, bx ; es = 0 - mov bx, 0x7E00 - push bx ; save return address: bx = 7E00 -; fall through - 'ret' in read_cluster will return to 7E00 - -read_cluster: -; ss:bp = 0:7C00 -; es:bx = pointer to data -; eax = cluster - sub eax, 2 - movzx ecx, [bp+BPB_SecsPerClus-0x7C00] - mul ecx - -read_sectors2: -; same as read_sectors32, but eax is relative to start of data - add eax, [bp-10] -read_sectors32: -; ss:bp = 0:7C00 -; es:bx = pointer to data -; eax = first sector -; cx = number of sectors -; some high words of 32-bit registers are destroyed! - pusha - add eax, [bp+BPB_HiddSec-0x7C00] -if use_lba - push ds -do_read_sectors: - push ax - push cx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F -@@: -; create disk address packet on the stack -; dq starting LBA - push 0 - push 0 - push eax -; dd buffer - push es - push bx -; dw number of blocks to transfer (no more than 0x7F) - push cx -; dw packet size in bytes - push 10h -; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [bp-2] - mov ah, 42h - int 13h - mov si, aReadError - jc err_ -; restore stack - add sp, 10h -; increase current sector & buffer; decrease number of sectors - movzx esi, cx - mov ax, es - shl cx, 5 - add ax, cx - mov es, ax - pop cx - pop ax - add eax, esi - sub cx, si - jnz do_read_sectors - pop ds - popa - ret -else -do_read_sectors: - pusha - pop edi ; loword(edi) = di, hiword(edi) = si - push bx - -; eax / (SectorsPerTrack) -> eax, remainder bx - movzx esi, [bp+BPB_SecPerTrk-0x7C00] - xor edx, edx - div esi - mov bx, dx ; bx=sector-1 - -; eax -> dx:ax - push eax - pop ax - pop dx -; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx - div [bp+BPB_NumHeads-0x7C00] - -; number of sectors: read no more than to end of track - sub si, bx - cmp cx, si - jbe @f - mov cx, si -@@: - - inc bx -; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format - movzx edi, cx - mov dh, dl - mov dl, [bp-2] - shl ah, 6 - mov ch, al - mov al, cl - mov cl, bl - or cl, ah - pop bx - mov si, 3 - mov ah, 2 -@@: - push ax - int 13h - jnc @f - xor ax, ax - int 13h ; reset drive - pop ax - dec si - jnz @b - mov si, aReadError - jmp err_ -@@: - pop ax - mov ax, es - mov cx, di - shl cx, 5 - add ax, cx - mov es, ax - push edi - popa - add eax, edi - sub cx, di - jnz do_read_sectors - popa - ret -end if - -lookup_in_dir: -; in: ds:si -> 11-bytes FAT name -; in: eax = cluster -; in: bx = 0 -; out: if found: CF=0, es:di -> directory entry -; out: if not found: CF=1 -; push 0x8000 -; pop es -; read current cluster: first cluster goes to 8000:0000, others - to 8200:0000 - mov es, [bp-7C00h + curseg] - push es - push eax - call read_cluster - mov ax, es - cmp ah, 82h - jb @f - mov ax, 8200h -@@: - mov [bp-7C00h + curseg], ax - pop eax - pop es -; scan for filename - shl cx, 4 - xor di, di -sloop: - cmp byte [es:di], bl - jz snotfound - test byte [es:di+11], 8 ; volume label? - jnz scont ; ignore volume labels - pusha - mov cx, 11 - repz cmpsb - popa - jz sdone -scont: - add di, 0x20 - loop sloop -; next cluster - push 0x6000 - pop es - push es ax - shr eax, 7 - cmp eax, [bp-14] - mov [bp-14], eax - jz @f - add eax, [bp-6] - mov cx, 1 - call read_sectors32 -@@: - pop di es - and di, 0x7F - shl di, 2 - and byte [es:di+3], 0x0F - mov eax, [es:di] - ;and eax, 0x0FFFFFFF - cmp eax, 0x0FFFFFF7 - jb lookup_in_dir -snotfound: - stc -sdone: - ret - -out_string: -; in: ds:si -> ASCIIZ string - lodsb - test al, al - jz sdone - mov ah, 0Eh - mov bx, 7 - int 10h - jmp out_string - -aReadError db 'Read error',0 -if use_lba -aNoLBA db 'The drive does not support LBA!',0 -end if -aLoaderNotFound db 'Loader not found',0 -aPressAnyKey db 13,10,'Press any key...',13,10,0 -main_loader db 'KORDLDR F32' - - db 56h -; just to make file 512 bytes long :) - db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' - -; bootsector signature - dw 0xAA55 - -; display offsets of all procedures used by kordldr.f12.asm -macro show [procedure] -{ - bits = 16 - display `procedure,' = ' - repeat bits/4 - d = '0' + procedure shr (bits - %*4) and 0Fh - if d > '9' - d = d + 'A'-'9'-1 - end if - display d - end repeat - display 13,10 -} - -show read_sectors32, read_sectors2, err_, noloader diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/bootsect.txt b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/bootsect.txt deleted file mode 100644 index caabcb33f..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/bootsect.txt +++ /dev/null @@ -1,333 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - Читай между строк - там никогда не бывает опечаток. - -Бутсектор для FAT32-тома на носителе с размером сектора 0x200 = 512 байт. - -===================================================================== - -Есть две версии в зависимости от того, поддерживает ли носитель LBA, -выбор осуществляется установкой константы use_lba в первой строке исходника. -Требования для работы: -1) Сам бутсектор, первая копия FAT и все используемые файлы -должны быть читабельны. (Если дело происходит на носителе с разбиением на -разделы и загрузочный код в MBR достаточно умный, то читабельности резервной -копии бутсектора (сектор номер 6 на томе) достаточно вместо читабельности -самого бутсектора). -2) Минимальный процессор - 80386. -3) В системе должно быть как минимум 584K свободной базовой памяти. - -===================================================================== - -Документация в тему (ссылки проверялись на валидность 15.05.2008): - официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx - в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf - русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip - официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf - то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf - описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html - официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf - -===================================================================== - -Схема используемой памяти: - ...-7C00 стек - 7C00-7E00 код бутсектора - 7E00-8200 вспомогательный файл загрузчика (kordldr.f32) - 8400-8C00 информация о кэше для таблицы FAT: 100h входов по 8 - байт: 4 байта (две ссылки - вперёд и назад) для - организации L2-списка всех прочитанных секторов в - порядке возрастания последнего времени использования - + 4 байта для номера сектора; при переполнении кэша - выкидывается элемент из головы списка, то есть тот, - к которому дольше всех не было обращений - 60000-80000 кэш для таблицы FAT (100h секторов) - 80000-90000 текущий кластер текущей рассматриваемой папки - 90000-... кэш для содержимого папок (каждой папке отводится - 2000h байт = 100h входов, одновременно в кэше - может находиться не более 8 папок; - точный размер определяется размером доступной - физической памяти - как правило, непосредственно - перед A0000 размещается EBDA, Extended BIOS Data Area) - -===================================================================== - -Основной процесс загрузки. -Точка входа (start): получает управление от BIOS при загрузке, при этом - dl содержит идентификатор диска, с которого идёт загрузка -1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед - кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало - бутсектора (в дальнейшем данные будут адресоваться через [bp+N] - - это освобождает ds и экономит на размере кода). Сохраняет в стеке - идентификатор загрузочного диска для последующего обращения - через byte [bp-2]. -2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h - прерывания 13h. Если нет, переходит на код обработки ошибок с - сообщением об отсутствии LBA. -CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и - записывает полученные данные поверх BPB. Если вызов завершился ошибкой, - предполагает уже существующие данные корректными. -3. Вычисляет начало данных FAT-тома, сохраняет его в стек для последующего - обращения через dword [bp-10]. В процессе вычисления узнаёт начало - первой FAT, сохраняет и его в стек для последующего обращения через - dword [bp-6]. -4. (Заканчивая тему параметров в стеке) Помещает в стек dword-значение -1 - для последующего обращения через dword [bp-14] - инициализация - переменной, содержащей текущий сектор, находящийся в кэше FAT - (-1 не является валидным значением для номера сектора FAT). -5. Ищет в корневой папке элемент kordldr.f32. Если не находит - переходит на - код обработки ошибок с сообщением о ненайденном загрузчике. - Замечание: на этом этапе загрузки искать можно только в корневой - папке и только имена, заданные в формате файловой системе FAT - (8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны - быть заглавными, при необходимости имя и расширение дополняются - пробелами, разделяющей точки нет, завершающего нуля нет). -6. Загружает первый кластер файла kordldr.f32 по адресу 0:7E00 и передаёт - ему управление. При этом в регистре eax оказывается абсолютный - номер первого сектора kordldr.f32, а в cx - число считанных секторов - (равное размеру кластера). - -Вспомогательные процедуры бутсектора. -Код обработки ошибок (err): -1. Выводит строку с сообщением об ошибке. -2. Выводит строку "Press any key...". -3. Ждёт нажатия any key. -4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. -5. Для подстраховки зацикливается. - -Процедура чтения кластера (read_cluster): -на входе должно быть установлено: - ss:bp = 0:7C00 - es:bx = указатель на начало буфера, куда будут прочитаны данные - eax = номер кластера -на выходе: ecx = число прочитанных секторов (размер кластера), - es:bx указывает на конец буфера, в который были прочитаны данные, - eax и старшие слова других 32-битных регистров разрушаются -Загружает в ecx размер кластера, перекодирует номер кластера в номер сектора -и переходит к следующей процедуре. - -Процедура чтения секторов (read_sectors32 и read_sectors2): -на входе должно быть установлено: - ss:bp = 0:7C00 - es:bx = указатель на начало буфера, куда будут прочитаны данные - eax = стартовый сектор (относительно начала логического диска - для read_sectors32, относительно начала данных - для read_sectors2) - cx = число секторов (должно быть больше нуля) -на выходе: es:bx указывает на конец буфера, в который были прочитаны данные - старшие слова 32-битных регистров могут разрушиться -0. Если вызывается read_sectors2, она переводит указанный ей номер сектора - в номер относительно начала логического диска, прибавляя номер сектора - начала данных, хранящийся в стеке как [bp-10]. -1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на - устройстве, прибавляя значение соответствующего поля из BPB. -2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации - CHS-версия: все читаемые секторы были на одной дорожке. - LBA-версия: число читаемых секторов не превосходило 7Fh (требование - спецификации EDD BIOS). -CHS-версия: -3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как - единица плюс остаток от деления абсолютного номера на число секторов - на дорожке; дорожка рассчитывается как остаток от деления частного, - полученного на предыдущем шаге, на число дорожек, а цилиндр - как - частное от этого же деления. Если число секторов для чтения больше, - чем число секторов до конца дорожки, уменьшает число секторов для - чтения. -4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, - dh=головка, (младшие 6 бит cl)=сектор, - (старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска - и повторяет попытку чтения, всего делается не более трёх попыток - (несколько попыток нужно в случае дискеты для гарантии того, что - мотор раскрутился). Если все три раза происходит ошибка чтения, - переходит на код обработки ошибок с сообщением "Read error". -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. -LBA-версия: -3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей - итерации) до 7Fh. -4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами - push, причём в обратном порядке: стек - структура LIFO, и данные в - стеке хранятся в обратном порядке по отношению к тому, как их туда - клали). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки - ошибок с сообщением "Read error". Очищает стек от пакета, - сформированного на предыдущем шаге. -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. - -Процедура поиска элемента в папке (lookup_in_dir): -на входе должно быть установлено: - ss:bp = 0:7C00 - ds:si = указатель на имя файла в формате FAT (см. выше) - eax = начальный кластер папки - bx = 0 -на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то - CF сброшен и es:di указывает на элемент папки -В цикле считывает кластеры папки и ищет запрошенный элемент в прочитанных -данных. Для чтения кластера использует уже описанную процедуру read_clusters, -для продвижения по цепочке кластеров - описанную далее процедуру -get_next_clusters. Данные читаются в область памяти, начинающуюся с адреса -8000:0000, при этом первые 2000h байт из данных папки (может быть, меньше, -если чтение прервётся раньше) не перекрываются последующими чтениями -(это будет использовано позднее, в системе кэширования из kordldr.f32). -Выход осуществляется в любом из следующих случаев: найден запрошенный элемент; -кончились элементы в папке (первый байт очередного элемента нулевой); -кончились данные папки в соответствии с цепочкой кластеров из FAT. - -Процедура вывода на экран ASCIIZ-строки (out_string): -на входе: ds:si -> строка -В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. - -===================================================================== - -Работа вспомогательного загрузчика kordldr.f32: -1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора. - В зависимости от этого устанавливает смещения используемых процедур - бутсектора. Критерий проверки: в CHS-версии по адресу err находится - байт 0xE8 (машинная команда call), в LBA-версии по тому же адресу - находится байт 0x14, а адрес процедуры err другой. -2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска - адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с - ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента - место должно быть, отсюда ограничение в 592 Kb (94000h байт). - Замечание: этот размер не может превосходить 0A0000h байт и - на практике оказывается немного (на 1-2 килобайта) меньшим из-за - наличия дополнительной области данных BIOS "вверху" базовой памяти. -3. Инициализирует кэширование папок. Бутсектор уже загрузил какую-то часть - данных корневой папки; копирует загруженные данные в кэш и запоминает, - что в кэше есть корневая папка. -4. Инициализирует кэширование FAT. Бутсектор имеет дело с FAT в том и только - том случае, когда ему приходится загружать данные корневой папки, - не поместившиеся в один кластер. В этом случае в памяти присутствует - один сектор FAT (если было несколько обращений - последний из - использованных). -5. Если кластер равен сектору, то бутсектор загрузил только часть файла - kordldr.f32, и загрузчик подгружает вторую свою часть, используя - значения регистров на входе в kordldr.f32. -6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не - найден, или оказался папкой, или оказался слишком большим, то переходит - на код обработки ошибок из бутсектора с сообщением - "Fatal error: cannot load the secondary loader". - Замечание: на этом этапе имя файла уже можно указывать вместе с путём - и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов - по-прежнему нет. -7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err. - Это нужно, чтобы последующие обращения к коду бутсектора в случае - ошибок чтения не выводил соответствующее сообщение с последующей - перезагрузкой, а рапортовал об ошибке чтения, которую могло бы - как-нибудь обработать ядро. -8. Если загрузочный диск имеет идентификатор меньше 0x80, - то устанавливает al='f' ("floppy"), ah=идентификатор диска, - иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска). - (Говорите, дискеток с FAT32 не бывает? В чём-то Вы правы... но - уверены ли Вы, что нет загрузочных устройств, подобных дискетам, - но большего размера, и для которых BIOS-идентификатор меньше 0x80?) - Устанавливает bx='32' (тип файловой системы - FAT32). - Устанавливает si=смещение функции обратного вызова. Поскольку в этот - момент ds=0, то ds:si образуют полный адрес. -9. Передаёт управление по адресу 1000:0000. - -Функция обратного вызова для вторичного загрузчика: - предоставляет возможность чтения файла. -Вход и выход описаны в спецификации на загрузчик. -1. Сохраняет стек вызывающего кода и устанавливает свой стек: - ss:sp = 0:(7C00-10), bp=7C00: пара ss:bp при работе с остальным - кодом должна указывать на 0:7C00, а -10 берётся от того, что - инициализирующий код бутсектора уже поместил в стек 10 байт параметров, - и они должны сохраняться в неизменности. (Значение [ebp-14], - "текущий сектор, находящийся в кэше FAT", не используется после - инициализации кэширования в kordldr.f32.) -2. Разбирает переданные параметры и вызывает нужную из вспомогательных - процедур (загрузки файла либо продолжения загрузки файла). -3. Восстанавливает стек вызывающего кода и возвращает управление. - -Вспомогательные процедуры kordldr.f32. -Процедура получения следующего кластера в FAT (get_next_cluster): -1. Вычисляет номер сектора в FAT, в котором находится запрошенный элемент. - (В секторе 0x200 байт, каждый вход занимает 4 байта.) -2. Проверяет, есть ли сектор в кэше. Если есть, пропускает шаги 3 и 4. -3. Если нет, то в кэш нужно вставить новый элемент. Если кэш ещё не заполнен, - выделяет очередной элемент в конце кэша. Если заполнен, удаляет - самый старый элемент (тот, к которому дольше всего не было обращений); - для того, чтобы отслеживать порядок элементов по времени последнего - обращения, все (выделенные) элементы кэша связаны в двусвязный список, - в котором первым элементом является самый старый, а ссылки вперёд - указывают на следующий по времени последнего обращения. -4. Читает соответствующий сектор FAT с диска. -5. Корректирует список: текущий обрабатываемый элемент удаляется с той позиции, - где он находится, и добавляется в конец. (В случае со свежедобавленными - в кэш элементами удаления не делается, поскольку их в списке ещё нет.) -6. Считывает нужный вход в FAT, сбрасывая старшие 4 бита. -7. Сравнивает прочитанное значение с пределом: если оно строго меньше - 0x0FFFFFF7, то оно задаёт номер следующего кластера в цепочке; - в противном случае цепочка закончилась. - -Процедура загрузки файла (load_file): -1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4. -2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты - разделяются символом '/') в FAT-формат 8+3. Если это невозможно - (больше 8 символов в имени, больше 3 символов в расширении или - больше одной точки), возвращается с ошибкой. -3. Ищет элемент с таким именем в текущей рассматриваемой папке. - а) Проверяет, есть ли такая папка в кэше папок. (Идентификация папок - осуществляется по номеру начального кластера.) Если такой папки ещё - нет, добавляет её в кэш; если тот переполняется, выкидывает папку, - к которой дольше всего не было обращений. (Для каждого элемента кэша - хранится метка от 0 до (размер кэша)-1, определяющая его номер при - сортировке по давности последнего обращения. При обращении к какому-то - элементу его метка становится нулевой, а те метки, которые меньше - старого значения, увеличиваются на единицу.) - б) Просматривает в поисках запрошенного имени все элементы из кэша, - используя процедуру из бутсектора. Если обнаруживает искомый элемент, - переходит к шагу 4. Если обнаруживает конец папки, возвращается из - процедуры с ошибкой. - в) В цикле считывает папку посекторно. При этом пропускает начальные - секторы, которые уже находятся в кэше и уже были просмотрены. Каждый - прочитанный сектор копирует в кэш, если там ещё остаётся место, - и просматривает в нём все элементы. Работает, пока не случится одно из - трёх событий: найден искомый элемент; кончились кластеры (судя по - цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце - (первый байт нулевой). В двух последних случаях возвращается с ошибкой. -4. Проверяет тип найденного элемента (файл/папка): последний элемент в - запрошенном имени должен быть файлом, все промежуточные - папками. - Если текущий компонент имени - промежуточный, продвигает текущую - рассматриваемую папку и возвращается к пункту 2. -5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный - при вызове буфер последовательными вызовами функции бутсектора; - при этом если несколько кластеров файла расположены на диске - последовательно, то их чтение объединяется в одну операцию. - Следит за тем, чтобы не превысить указанный при вызове процедуры - лимит числа секторов для чтения. - -Процедура продолжения загрузки файла (continue_load_file): встроена - внутрь шага 5 load_file; загружает в регистры нужные значения (ранее - сохранённые из load_file) и продолжает шаг 5. diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/build.bat b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/build.bat deleted file mode 100644 index 267c29375..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/build.bat +++ /dev/null @@ -1,3 +0,0 @@ -@fasm -m 65535 bootsect.asm bootsect.bin -@fasm -m 65535 kordldr.f32.asm kordldr.f32 -@pause \ No newline at end of file diff --git a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/kordldr.f32.asm b/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/kordldr.f32.asm deleted file mode 100644 index 36bfa6475..000000000 --- a/kernel/branches/Kolibri-F/bootloader/extended_primary_loader/fat32/kordldr.f32.asm +++ /dev/null @@ -1,673 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - org 0x7E00 -; the KordOS FAT32 bootsector loads first cluster of this file to 0:7E00 and transfers control to here -; ss:bp = 0:7C00 -; ds = 0 -virtual at bp - rb 3 ; BS_jmpBoot - rb 8 ; BS_OEMName, ignored - dw ? ; BPB_BytsPerSec -BPB_SecsPerClus db ? -BPB_RsvdSecCnt dw ? -BPB_NumFATs db ? -BPB_RootEntCnt dw ? - dw ? ; BPB_TotSec16 - db ? ; BPB_Media - dw ? ; BPB_FATSz16 = 0 for FAT32 -BPB_SecPerTrk dw ? -BPB_NumHeads dw ? -BPB_HiddSec dd ? - dd ? ; BPB_TotSec32 -BPB_FATSz32 dd ? -BPB_ExtFlags dw ? - dw ? ; BPB_FSVer -BPB_RootClus dd ? -filesize: - dw ? ; BPB_FSInfo - dw ? ; BPB_BkBootSec - rb 12 ; BPB_Reserved -BS_DrvNum db ? - db ? ; BS_Reserved1 - db ? ; BS_BootSig - dd ? ; BS_VolID -; rb 11 ; BS_VolLab -; rb 5 ; BS_FilSysType, first 5 bytes -read_sectors32 dw ? -read_sectors2 dw ? -err_ dw ? -noloader dw ? -cachelimit dw ? -fatcachehead rw 2 -fatcacheend dw ? - rb 3 ; BS_FilSysType, last 3 bytes -curseg dw ? -num_sectors dd ? -cur_cluster dd ? -next_cluster dd ? -flags dw ? -cur_delta dd ? -end virtual - -; procedures from boot sector -; LBA version -lba_read_sectors2 = 7CD6h -lba_err = 7CAAh -lba_noloader = 7CA7h ; = lba_err - 3 -; CHS version -chs_read_sectors2 = 7CD2h -chs_err = 7CA6h -chs_noloader = 7CA3h ; = chs_err - 3 - - push eax cx ; save our position on disk -; determine version of bootsector (LBA vs CHS) - mov [read_sectors2], chs_read_sectors2 - mov bx, chs_err - mov [err_], bx -; mov [noloader], chs_noloader - cmp byte [bx], 0xE8 ; [chs_err] = 0xE8 for CHS version, 0x14 for LBA version - jz @f - add [read_sectors2], lba_read_sectors2 - chs_read_sectors2 - add [err_], lba_err - chs_err -; mov [noloader], lba_noloader -@@: - xor bx, bx -; determine size of cache for folders - int 12h ; ax = size of available base memory in Kb - sub ax, 92000h / 1024 - jae @f -nomem: - mov si, nomem_str - jmp [err_] -@@: - shr ax, 3 - mov [cachelimit], ax ; size of cache - 1 - mov es, bx -; no folders in cache yet - mov di, foldcache_clus - mov cx, 8*4/2 + 1 - xor ax, ax - rep stosw -; bootsector code caches one FAT sector, [bp-14], in 6000:0000 -; initialize our (more advanced) FAT caching from this - mov di, 8400h - mov cx, di - lea si, [fatcachehead] - mov [si], si ; no sectors in cache: - mov [si+2], si ; 'prev' & 'next' links point to self - mov [fatcacheend], di ; first free item = 8400h - stosw ; 'next cached sector' link - stosw ; 'prev cached sector' link - mov eax, [bp-14] - stosd ; first sector number in cache - test eax, eax - js @f - mov [si], cx ; 'first cached sector' link = 8400h - mov [si+2], cx ; 'next cached sector' link = 8400h - mov [fatcacheend], di ; first free item = 8406h -@@: -; if cluster = sector, we need to read second part of our file -; (bootsector loads only first cluster of kordldr.f32) - pop cx eax ; restore our position on disk - cmp cx, 1 - ja kordldr_full - sub eax, [bp-10] - inc eax - inc eax ; eax = first cluster of kordldr.f32 - call get_next_cluster - jc @f -; jmp [noloader] - mov ax, [err_] - sub ax, 3 - jmp ax -@@: - dec eax - dec eax - push 0x800 - pop es - call [read_sectors2] -kordldr_full: -; bootsector code has read some data of root directory to 8000:0000 -; initialize our folder caching from this - mov eax, [BPB_RootClus] - mov [foldcache_clus], eax - mov cx, [curseg] - mov ax, 8000h - sub cx, ax ; cx = size of data read in paragraphs (0x10 bytes) - shr cx, 1 ; cx = size of folder data read in entries (0x20 bytes) - mov [foldcache_size], cx - shl cx, 4 - push ds - mov ds, ax - push 0x9000 - pop es - xor si, si - xor di, di - rep movsw - pop ds -; ...continue loading... - mov di, secondary_loader_info - call load_file - test bx, bx - mov bx, [err_] - jz @f - mov si, aKernelNotFound - jmp bx -@@: -; for subsequent calls to callback function, hook error handler -; push hooked_err / ret - mov dword [bx], 0x68 + (hooked_err shl 8) + (0xC3 shl 24) -; set registers for secondary loader - mov ah, [bp-2] ; drive id - mov al, 'f' - btr ax, 15 - jnc @f - mov al, 'h' -@@: - mov bx, '32' - mov si, callback - jmp far [si+secondary_loader_info-callback] - -nomem_str db 'No memory',0 - -cluster2sector: - sub eax, 2 -clustersz2sectorsz: - movzx ecx, [BPB_SecsPerClus] - mul ecx - ret - -get_next_cluster: -; in: eax = cluster -; out: if there is next cluster: CF=1, eax = next cluster -; out: if there is no next cluster: CF=0 - push di bx - push ds es - push ss - pop ds - push ss - pop es - push ax - shr eax, 7 -; eax = FAT sector number; look in cache - mov di, 8400h -.cache_lookup: - cmp di, [fatcacheend] - jae .not_in_cache - scasd - scasd - jnz .cache_lookup -.in_cache: - sub di, 8 -; delete this sector from the list - push si - mov si, [di] - mov bx, [di+2] - mov [si+2], bx - mov [bx], si - pop si - jmp @f -.not_in_cache: -; cache miss -; cache is full? - mov di, [fatcacheend] - cmp di, 8C00h - jnz .cache_not_full -; yes, delete the oldest entry - mov di, [fatcachehead] - mov bx, [di] - mov [fatcachehead], bx - push word [di+2] - pop word [bx+2] - jmp .cache_append -.cache_not_full: -; no, allocate new sector - add [fatcacheend], 8 -.cache_append: -; read FAT - mov [di+4], eax - pushad - lea cx, [di + 0x10000 - 0x8400 + (0x6000 shr (9-4-3))] ; +0x10000 - for FASM - shl cx, 9-4-3 - mov es, cx - xor bx, bx - mov cx, 1 - add eax, [bp-6] ; FAT start - sub eax, [bp-10] - call [read_sectors2] - popad -@@: -; add new sector to the end of list - mov bx, di - xchg bx, [fatcachehead+2] - push word [bx] - pop word [di] - mov [bx], di - mov [di+2], bx -; get requested item - lea ax, [di + 0x10000 - 0x8400 + (0x6000 shr (9-4-3))] - pop di - and di, 0x7F - shl di, 2 - shl ax, 9-4-3 - mov ds, ax - and byte [di+3], 0x0F - mov eax, [di] - pop es ds - pop bx di - ;and eax, 0x0FFFFFFF - cmp eax, 0x0FFFFFF7 - ret - -if $ > 0x8000 -error 'get_next_cluster must fit in first sector of kordldr.f32!' -end if - -load_file: -; in: ss:bp = 0:7C00 -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) - mov eax, [BPB_RootClus] ; start from root directory - or dword [filesize], -1 ; initialize file size with invalid value - lea si, [di+6] -parse_dir_loop: -; convert name to FAT name - push di - push ax - push ss - pop es -; convert ASCIIZ filename to FAT name -filename equ bp - mov di, filename - push di - mov cx, 8+3 - mov al, ' ' - rep stosb - pop di - mov cl, 8 ; 8 symbols per name - mov bl, 1 -nameloop: - lodsb - test al, al - jz namedone - cmp al, '/' - jz namedone - cmp al, '.' - jz namedot - dec cx - js badname - cmp al, 'a' - jb @f - cmp al, 'z' - ja @f - sub al, 'a'-'A' -@@: - stosb - jmp nameloop -namedot: - inc bx - jp badname - add di, cx - mov cl, 3 - jmp nameloop -badname: ; do not make direct js/jp to notfound_pop: - ; this generates long forms of conditional jumps and results in longer code - jmp notfound_pop -namedone: -; scan directory - pop ax ; eax = cluster of directory - ; high word of eax is preserved by operations above - push ds - push si -; read a folder sector-by-sector and scan -; first, try to use the cache - push ss - pop ds - mov di, foldcache_mark - xor bx, bx - mov cx, [cachelimit] -@@: - lea si, [di+bx] - mov edx, dword [foldcache_clus+si-foldcache_mark+bx] - cmp edx, eax - jz cacheok - test edx, edx - jz cacheadd ; the cache has place for new entry - inc bx - inc bx - dec cx - jns @b -; the folder is not present in the cache, so add it -; the cache is full; find the oldest entry and replace it with the new one - mov bx, -2 - mov dx, [cachelimit] -@@: - inc bx - inc bx - cmp word [di+bx], dx ; marks have values 0 through [cachelimit] - jnz @b - lea si, [di+bx] -cacheadd: - or word [di+bx], 0xFFFF ; very big value, it will be changed soon - and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet - mov dword [foldcache_clus+si-foldcache_mark+bx], eax -cacheok: -; update cache marks - mov dx, [di+bx] - mov cx, [foldcache_size+di-foldcache_mark+bx] - mov di, [cachelimit] - add di, di -cacheupdate: - cmp [foldcache_mark+di], dx - adc [foldcache_mark+di], 0 - dec di - dec di - jns cacheupdate - and [foldcache_mark+bx], 0 -; done, bx contains (position in cache)*2 - ;mov dx, bx - ;shl dx, 8 ; dx = (position in cache)*0x2000/0x10 - ;add dx, 0x9000 - lea dx, [bx + 0x90] - xchg dl, dh - mov ds, dx - mov si, filename ; ss:si -> filename in FAT style - call scan_for_filename - jz lookup_done -; cache miss, read folder data from disk - mov bx, cx - shr bx, 4 - shl cx, 5 - mov di, cx ; es:di -> free space in cache entry -; external loop: scan clusters -folder_next_cluster: -; internal loop: scan sectors in cluster - push eax - call cluster2sector -folder_next_sector: -; skip first bx sectors - dec bx - jns folder_skip_sector - push cx - push es di - push 0x8000 - pop es - xor bx, bx - mov cx, 1 - push es - push eax - call [read_sectors2] - pop eax -; copy data to the cache... - pop ds - pop di es - cmp di, 0x2000 ; ...if there is free space, of course - jae @f - pusha - mov cx, 0x100 - xor si, si - rep movsw - mov di, es - shr di, 8 - add [ss:foldcache_size+di-0x90], 0x10 ; 0x10 new entries in the cache - popa -@@: - push es - mov cl, 0x10 ; ch=0 at this point - call scan_for_filename - pop es - pop cx - jz lookup_done_pop -folder_skip_sector: - inc eax - loop folder_next_sector - pop eax ; eax = current cluster - call get_next_cluster - jc folder_next_cluster - stc - push eax -lookup_done_pop: - pop eax -lookup_done: - pop si -; CF=1 <=> failed - jnc found - pop ds -notfound: - pop di -notfound2: - mov bx, 2 ; file not found - mov ax, 0xFFFF - mov dx, ax ; invalid file size - ret -notfound_pop: - pop ax - jmp notfound -found: - mov eax, [di+20-2] - mov edx, [di+28] - mov ax, [di+26] ; get cluster - test byte [di+11], 10h ; directory? - pop ds - pop di - jz regular_file - cmp byte [si-1], 0 - jz notfound2 ; don't read directories as regular files -; ok, we have found a directory and the caller requested a file into it - jmp parse_dir_loop ; restart with new cluster in ax -regular_file: - cmp byte [si-1], 0 - jnz notfound2 ; file does not contain another files -; ok, we have found a regular file and the caller requested it -; save file size - mov [filesize], edx - mov si, [di+4] ; [ds:di+4] = limit in 4K blocks - shl si, 3 - push si - les bx, [di] ; es:bx -> buffer -clusloop: -; eax = first cluster, top of stack contains limit in sectors - mov esi, eax ; remember current cluster - xor ecx, ecx ; ecx will contain number of consecutive clusters - mov [cur_delta], ecx - mov edi, eax -clusfind: - inc edi - inc ecx - call get_next_cluster - jnc clusread - cmp eax, edi - jz clusfind - stc -clusread: - pop di ; limit in sectors - movzx edi, di - push eax ; save next cluster - pushf ; save flags -; read cx clusters, starting from si -; calculate number of sectors - xchg eax, ecx - call clustersz2sectorsz - mov [num_sectors], eax - jmp @f -continue_load_file: - les bx, [di] ; es:bx -> buffer - movzx edi, word [di+4] ; di = limit in 4K blocks - shl di, 3 ; now di = limit in sectors - mov eax, [num_sectors] - mov esi, [cur_cluster] - push [next_cluster] - push [flags] - test eax, eax - jz nextclus -@@: -; eax = number of sectors; compare with limit - cmp eax, edi - seta dl - push dx ; limit was exceeded? - jbe @f - mov eax, edi -@@: - sub di, ax ; calculate new limit - sub [num_sectors], eax - mov [cur_cluster], esi -; calculate starting sector - push ax - xchg eax, esi - call cluster2sector - pop cx - add eax, [cur_delta] - add [cur_delta], ecx -; read - call [read_sectors2] - pop dx -; next cluster? -nextclus: - popf - pop eax - mov [next_cluster], eax - pushf - pop [flags] - jnc @f ; no next cluster => return - mov dl, 1 - test di, di - jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded - push di - jmp clusloop ; all is ok, continue -hooked_err: - mov sp, 7C00h-14-2 ; restore stack - mov dl, 3 ; return: read error -@@: - mov bl, dl - mov bh, 0 - mov ax, [filesize] - mov dx, [filesize+2] - ret - -scan_for_filename: -; in: ss:si -> 11-bytes FAT name -; in: ds:0 -> part of directory data -; in: cx = number of entries -; in: bh = 0 -; out: if found: CF=0, ZF=1, es:di -> directory entry -; out: if not found, but continue required: CF=1 and ZF=0 -; out: if not found and zero item reached: CF=1 and ZF=1 - push ds - pop es - xor di, di - push cx - jcxz snoent -sloop: - cmp byte [di], bh - jz snotfound - test byte [di+11], 8 ; volume label? - jnz scont ; ignore volume labels - pusha - mov cx, 11 - repz cmps byte [ss:si], byte [es:di] - popa - jz sdone -scont: - add di, 0x20 - loop sloop -snoent: - inc cx ; clear ZF flag -snotfound: - stc -sdone: - pop cx -lrdret: - ret - -; Callback function for secondary loader -callback: -; in: ax = function number; only functions 1 and 2 are defined for now -; save caller's stack - mov dx, ss - mov cx, sp -; set our stack (required because we need ss=0) - xor si, si - mov ss, si - mov sp, 7C00h-10 - mov bp, 7C00h - push dx - push cx -; call our function - stc ; unsupported function - dec ax - jz callback_readfile - dec ax - jnz callback_ret -; function 2: continue loading file -; can be called only after function 1 returned value bx=1 (only part of file was loaded) -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error -; out: dx:ax = file size - call continue_load_file - jmp callback_ret_succ -callback_readfile: -; function 1: read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error -; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call load_file -callback_ret_succ: - clc ; function is supported -callback_ret: -; restore caller's stack - pop cx - pop ss - mov sp, cx -; return to caller - retf - -secondary_loader_info: - dw 0, 0x1000 - dw 0x30000 / 0x1000 - db 'kernel.mnt',0 -aKernelNotFound db 'Fatal error: cannot load the kernel',0 - -;if $ > 0x8200 -;error 'total size of kordldr.f32 must not exceed 1024 bytes!' -;end if - -;foldcache_clus dd 0,0,0,0,0,0,0,0 ; start with no folders in cache -;foldcache_mark dw 0 -; rw 7 -;foldcache_size rw 8 -foldcache_clus rd 8 -foldcache_mark rw 8 -foldcache_size rw 8 diff --git a/kernel/branches/Kolibri-F/bootloader/floppy1440.inc b/kernel/branches/Kolibri-F/bootloader/floppy1440.inc deleted file mode 100644 index aaa247a3d..000000000 --- a/kernel/branches/Kolibri-F/bootloader/floppy1440.inc +++ /dev/null @@ -1,26 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - BS_OEMName db 'KOLIBRI ' ; db 8 - BPB_BytsPerSec dw 512 ; bytes per sector - BPB_SecPerClus db 1 ; sectors per cluster - BPB_RsvdSecCnt dw 1 ; number of reserver sectors - BPB_NumFATs db 2 ; count of FAT data structures - BPB_RootEntCnt dw 224 ; count of 32-byte dir. entries (224*32 = 14 sectors) - BPB_TotSec16 dw 2880 ; count of sectors on the volume (2880 for 1.44 mbytes disk) - BPB_Media db 0f0h ; f0 - used for removable media - BPB_FATSz16 dw 9 ; count of sectors by one copy of FAT - BPB_SecPerTrk dw 18 ; sectors per track - BPB_NumHeads dw 2 ; number of heads - BPB_HiddSec dd 0 ; count of hidden sectors - BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) - BS_DrvNum db 0 ; int 13h drive number - BS_Reserved db 0 ; reserved - BS_BootSig db 29h ; Extended boot signature - BS_VolID dd 0 ; Volume serial number - BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) - BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/branches/Kolibri-F/bootloader/floppy1680.inc b/kernel/branches/Kolibri-F/bootloader/floppy1680.inc deleted file mode 100644 index b0c561f3e..000000000 --- a/kernel/branches/Kolibri-F/bootloader/floppy1680.inc +++ /dev/null @@ -1,26 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - BS_OEMName db 'KOLIBRI ' ; db 8 - BPB_BytsPerSec dw 512 ; bytes per sector - BPB_SecPerClus db 1 ; sectors per cluster - BPB_RsvdSecCnt dw 1 ; number of reserver sectors - BPB_NumFATs db 2 ; count of FAT data structures - BPB_RootEntCnt dw 112 ; count of 32-byte dir. entries (112*32 = 7 sectors) - BPB_TotSec16 dw 3360 ; count of sectors on the volume (3360 for 1.68 mbytes disk) - BPB_Media db 0f0h ; f0 - used for removable media - BPB_FATSz16 dw 10 ; count of sectors by one copy of FAT - BPB_SecPerTrk dw 21 ; sectors per track - BPB_NumHeads dw 2 ; number of heads - BPB_HiddSec dd 0 ; count of hidden sectors - BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) - BS_DrvNum db 0 ; int 13h drive number - BS_Reserved db 0 ; reserved - BS_BootSig db 29h ; Extended boot signature - BS_VolID dd 0 ; Volume serial number - BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) - BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/branches/Kolibri-F/bootloader/floppy1743.inc b/kernel/branches/Kolibri-F/bootloader/floppy1743.inc deleted file mode 100644 index 148e966b0..000000000 --- a/kernel/branches/Kolibri-F/bootloader/floppy1743.inc +++ /dev/null @@ -1,26 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - BS_OEMName db 'KOLIBRI ' ; db 8 - BPB_BytsPerSec dw 512 ; bytes per sector - BPB_SecPerClus db 1 ; sectors per cluster - BPB_RsvdSecCnt dw 1 ; number of reserver sectors - BPB_NumFATs db 2 ; count of FAT data structures - BPB_RootEntCnt dw 224 ; count of 32-byte dir. entries (224*32 = 14 sectors) - BPB_TotSec16 dw 3486 ; count of sectors on the volume (3486 for 1.74 mbytes disk) - BPB_Media db 0f0h ; f0 - used for removable media - BPB_FATSz16 dw 11 ; count of sectors by one copy of FAT - BPB_SecPerTrk dw 21 ; sectors per track - BPB_NumHeads dw 2 ; number of heads - BPB_HiddSec dd 0 ; count of hidden sectors - BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) - BS_DrvNum db 0 ; int 13h drive number - BS_Reserved db 0 ; reserved - BS_BootSig db 29h ; Extended boot signature - BS_VolID dd 0 ; Volume serial number - BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) - BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/branches/Kolibri-F/bootloader/floppy2880.inc b/kernel/branches/Kolibri-F/bootloader/floppy2880.inc deleted file mode 100644 index 48a205788..000000000 --- a/kernel/branches/Kolibri-F/bootloader/floppy2880.inc +++ /dev/null @@ -1,26 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - BS_OEMName db 'KOLIBRI ' ; db 8 - BPB_BytsPerSec dw 512 ; bytes per sector - BPB_SecPerClus db 2 ; sectors per cluster - BPB_RsvdSecCnt dw 1 ; number of reserver sectors - BPB_NumFATs db 2 ; count of FAT data structures - BPB_RootEntCnt dw 240 ; count of 32-byte dir. entries (240*32 = 15 sectors) - BPB_TotSec16 dw 5760 ; count of sectors on the volume (5760 for 2.88 mbytes disk) - BPB_Media db 0f0h ; f0 - used for removable media - BPB_FATSz16 dw 9 ; count of sectors by one copy of FAT - BPB_SecPerTrk dw 36 ; sectors per track - BPB_NumHeads dw 2 ; number of heads - BPB_HiddSec dd 0 ; count of hidden sectors - BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) - BS_DrvNum db 0 ; int 13h drive number - BS_Reserved db 0 ; reserved - BS_BootSig db 29h ; Extended boot signature - BS_VolID dd 0 ; Volume serial number - BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) - BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/branches/Kolibri-F/bootloader/grub4kos.asm b/kernel/branches/Kolibri-F/bootloader/grub4kos.asm deleted file mode 100644 index 7d81ab0a7..000000000 --- a/kernel/branches/Kolibri-F/bootloader/grub4kos.asm +++ /dev/null @@ -1,296 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2014-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; Kolibri OS support loader for GRUB -; -; Copyright (C) Alex Nogueira Teixeira -; Copyright (C) Diamond -; Copyright (C) Dmitry Kartashov aka shurf -; Copyright (C) Serge -; -; Distributed under GPL, see file COPYING for details -; -; Version 1.0 - -lf = 0x0A -cr = 0x0D - -use32 - - -org 0x100000 - -mboot: - dd 0x1BADB002 - dd 0x00010003 - dd -(0x1BADB002 + 0x00010003) - dd mboot - dd 0x100000 - dd __edata - dd __end - dd __start - -align 16 -__start: - -virtual at ebp+3 -.BS_OEMName rb 8 -.BPB_BytsPerSec rw 1 ; bytes per sector -.BPB_SecPerClus rb 1 ; sectors per cluster -.BPB_RsvdSecCnt rw 1 ; number of reserver sectors -.BPB_NumFATs rb 1 ; count of FAT data structures -.BPB_RootEntCnt rw 1 ; count of 32-byte dir. entries (224*32 = 14 sectors) -.BPB_TotSec16 rw 1 ; count of sectors on the volume (2880 for 1.44 mbytes disk) -.BPB_Media rb 1 ; f0 - used for removable media -.BPB_FATSz16 rw 1 ; count of sectors by one copy of FAT -.BPB_SecPerTrk rw 1 ; sectors per track -.BPB_NumHeads rw 1 ; number of heads -.BPB_HiddSec rd 1 ; count of hidden sectors -.BPB_TotSec32 rd 1 ; count of sectors on the volume (if > 65535) -end virtual - - cld - mov esi, mboot - mov edi, 0x80000 - mov ecx, 624/4 ;magic value - rep movsd - jmp .check_mbi - -org $-0x80000 -align 4 -.check_mbi: - cmp eax, 0x2BADB002 - mov esi, sz_invboot - jne .panic - - bt dword [ebx], 3 - mov esi, sz_nomods - jnc .panic - - mov edx, [ebx+20] ;mods_count - mov edi, [ebx+24] ;mods_addr - cmp edx, 1 - mov esi, sz_nomods - jne .panic - -.scan_mod: - mov ebp, [edi] ;image start - mov ecx, [edi+4] ;image end - sub ecx, ebp ;image size - cmp ecx, 512*18*80*2 ;1.44 floppy - mov esi, sz_image - jne .panic - - mov [_image_start], ebp - mov [_image_size], ecx - -; calculate some disk parameters -; - beginning sector of RootDir - - movzx eax, word [.BPB_FATSz16] - movzx ecx, byte [.BPB_NumFATs] - mul ecx - add ax, [.BPB_RsvdSecCnt] - mov [FirstRootDirSecNum], eax - mov esi, eax - -; - count of sectors in RootDir - movzx ebx, word [.BPB_BytsPerSec] - mov cl, 5 ; divide ax by 32 - shr ebx, cl ; bx = directory entries per sector - movzx eax, word [.BPB_RootEntCnt] - xor edx, edx - div ebx - mov [RootDirSecs], eax - - ; - data start - add esi, eax ; add beginning sector of RootDir and count sectors in RootDir - mov [data_start], esi - -; reading root directory -; al=count root dir sectrors !!!! TODO: al, max 255 sectors !!!! - - mov eax, [FirstRootDirSecNum] - mul word [.BPB_BytsPerSec] - lea esi, [ebp+eax] - - mov eax, [RootDirSecs] - mul word [.BPB_BytsPerSec] - add eax, esi ; EAX = end of root dir. in buffer pos_read_tmp - -; find kernel file in root directory - -.loop_find_dir_entry: - push esi - mov ecx, 11 - mov edi, kernel_name - rep cmpsb ; compare es:si and es:di, cx bytes long - pop esi - je .found_kernel_file - add esi, 32 ; next dir. entry - cmp esi, eax ; end of directory - jb .loop_find_dir_entry - - mov esi, sz_kernel - jmp .panic - - ; === KERNEL FOUND. LOADING... === - -.found_kernel_file: - - movzx ecx, word [esi+01ah] ; first cluster of kernel file - - ; reading first FAT table - movzx eax, word [.BPB_RsvdSecCnt] ; begin first FAT abs sector number - mul word [.BPB_BytsPerSec] - lea ebx, [ebp+eax] ; FAT address - -;ebx = FAT -;ecx = cluster -;esi = src -;edi = dst -;ebp = image - -; copy kernel file - - movzx eax, word [.BPB_BytsPerSec] - movsx edx, byte [.BPB_SecPerClus] - mul edx - shr eax, 2 - mov [cluster_size], eax - - mov edi, 0x10000 ;kernel base address - -.copy_kernel: - - ; convert cluster number to sector number - mov eax, ecx ; data cluster to read - sub eax, 2 - movzx edx, byte [.BPB_SecPerClus] - mul edx - add eax, [data_start] - movzx edx, word [.BPB_BytsPerSec] - mul edx - - lea esi, [ebp+eax] - mov edx, ecx - mov ecx, [cluster_size] - rep movsd - mov ecx, edx - - shr edx, 1 - pushf - add edx, ecx ; di = bp * 1.5 - mov ax, word [ebx+edx] ; read next entry from FAT-chain - popf - jc .move_4_right - and ax, 0fffh - jmp .verify_end_sector -.move_4_right: - shr ax, 4 -.verify_end_sector: - cmp ax, 0ff8h ; last cluster - jae .execute_kernel - movzx ecx, ax - jmp .copy_kernel - -.execute_kernel: - - mov edi, 0x100000 - mov esi, [_image_start] - mov ecx, [_image_size] - shr ecx, 2 - rep movsd - xor eax, eax - mov ecx, 1024 - rep stosd - - xor ebx, ebx - xor ecx, ecx - xor edx, edx - xor esi, esi - xor edi, edi - xor ebp, ebp - xor esp, esp - - lgdt [.tmp_gdt] - jmp far 0x08:.mode_16 and 0xFFFF - -.panic: - mov ebx, sz_halt - mov edx, 0xb8000+160*10+2 - mov ah, 0x07 -.line: - mov edi, edx -.print: - lodsb - test al, al - jz .print_next - stosw - jmp .print - -.print_next: - test ebx, ebx - jz ._hlt - - mov esi, ebx - xor ebx, ebx - add edx, 160 - jmp .line - -._hlt: - hlt - jmp ._hlt - -align 8 -.tmp_gdt: dw 15 - dd .tmp_gdt - dw 0 - -.code16: dw 0xFFFF - dw 0 - db 8 - db 10011010b - dw 0 - -use16 -.mode_16: - mov eax, cr0 - and eax, not 0x80000001 - mov cr0, eax - jmp far 0x8000:.real_mode and 0xFFFF - -.real_mode: - xor eax, eax - mov ds, ax - mov es, ax - mov ss, ax - mov gs, ax - mov fs, ax - jmp far 0x1000:0000 - - -sz_invboot db 'Invalid multiboot loader magic value',0 -sz_nomods db 'No image loaded',0 -sz_image db 'Image size invalid',0 -sz_halt db 'Halted',0 - -sz_kernel db cr -kernel_name db 'KERNEL MNT ?',0 - -org $+0x80000 -__edata: - -align 4 -_image_start rd 1 -_image_size rd 1 - -FirstRootDirSecNum rd 1 -RootDirSecs rd 1 -data_start rd 1 -cluster_size rd 1 -__end: diff --git a/kernel/branches/Kolibri-F/bootloader/readme b/kernel/branches/Kolibri-F/bootloader/readme deleted file mode 100644 index b68c8bac0..000000000 --- a/kernel/branches/Kolibri-F/bootloader/readme +++ /dev/null @@ -1,50 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -Загрузочный сектор для ОС Колибри (FAT12, дискета) - -- Описание - Позволяет загружать KERNEL.MNT с дискет/образов - объёмом 1.44M, 1.68M, 1.72M и 2.88M - Для выбора объёма диска, для которого надо собрать - загрузочный сектор, необходимо в файле boot_fat12.asm - раскомментировать строку вида: - include 'floppy????.inc' - для необходимого объёма диска. Доступные варианты: - floppy1440.inc, - floppy1680.inc, - floppy1743.inc и floppy2880.inc - -- Сборка - fasm boot_fat12.asm - -- Для записи загрузочного сектора на диск/образ под Linux - можно воспользоваться следующей командой: - dd if=boot_fat12.bin of=288.img bs=512 count=1 conv=notrunc - ---------------------------------------------------------------------- - -Floppy FAT12 boot sector for KolibriOS. - -- Description - Allows booting KERNEL.MNT floppies/images - with volumes of 1.44M, 1.68M, 1.72M and 2.88M - To select the volume of the disk, which should gather - boot sector, it was necessary in file boot_fat12.asm - uncomment line: - include 'floppy????. inc' - for the necessary disk volume. Available options is: - floppy1440.inc, - floppy1680.inc, - floppy1743.inc and floppy2880.inc - -- Compile - fasm boot_fat12.asm - -- To write boot sector to the floppy/image under Linux - you can use the following command: - dd if=boot_fat12.bin of=288.img bs=512 count=1 conv=notrunc diff --git a/kernel/branches/Kolibri-F/bootloader/uefi4kos/Tupfile.lua b/kernel/branches/Kolibri-F/bootloader/uefi4kos/Tupfile.lua deleted file mode 100644 index ef45904ae..000000000 --- a/kernel/branches/Kolibri-F/bootloader/uefi4kos/Tupfile.lua +++ /dev/null @@ -1,3 +0,0 @@ -if tup.getconfig("NO_FASM") ~= "" then return end -tup.rule("uefi64kos.asm", "fasm -dUEFI=1 -dextended_primary_loader=1 %f %o", "bootx64.efi") -tup.rule("uefi32kos.asm", "fasm -dUEFI=1 -dextended_primary_loader=1 %f %o", "bootia32.efi") diff --git a/kernel/branches/Kolibri-F/bootloader/uefi4kos/kolibri.ini b/kernel/branches/Kolibri-F/bootloader/uefi4kos/kolibri.ini deleted file mode 100644 index aa023f9b7..000000000 --- a/kernel/branches/Kolibri-F/bootloader/uefi4kos/kolibri.ini +++ /dev/null @@ -1,21 +0,0 @@ -; Screen resolution -resolution=1024x768 - -; Duplicate debug output to the screen -debug_print=0 - -; Start LAUNCHER app after kernel is loaded -launcher_start=1 - -; Configure MTRR's -mtrr=1 - -; 3: use ramdisk loaded from kolibri.img -; 5: don't use ramdisk, use /sys directory -imgfrom=3 - -; Path to /sys directory, only internal -; disk drives are alowed (no usbdisk). -; Example: syspath=/HD0/1/KOLIBRIOS -syspath=/rd/1 - diff --git a/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi.inc b/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi.inc deleted file mode 100644 index edb37bdfb..000000000 --- a/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi.inc +++ /dev/null @@ -1,272 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2020. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; Version 2, or (at your option) any later version. ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Based on UEFI library for fasm by bzt, Public Domain. ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -EFI_LOCATE_SEARCH_TYPE: -.AllHandles = 0 -.ByRegisterNotify = 1 -.ByProtocol = 2 - -; EFI_MEMORY_TYPE -EFI_RESERVED_MEMORY_TYPE = 0 -EFI_LOADER_CODE = 1 -EFI_LOADER_DATA = 2 -EFI_BOOT_SERVICES_CODE = 3 -EFI_BOOT_SERVICES_DATA = 4 -EFI_RUNTIME_SERVICES_CODE = 5 -EFI_RUNTIME_SERVICES_DATA = 6 -EFI_CONVENTIONAL_MEMORY = 7 -EFI_UNUSABLE_MEMORY = 8 -EFI_ACPI_RECLAIM_MEMORY = 9 -EFI_ACPI_MEMORY_NVS = 10 -EFI_MEMORY_MAPPED_IO = 11 -EFI_MEMORY_MAPPED_IO_PORT_SPACE = 12 -EFI_PAL_CODE = 13 -EFI_PERSISTENT_MEMORY = 14 -EFI_MAX_MEMORY_TYPE = 15 - -; EFI_ALLOCATE_TYPE -EFI_ALLOCATE_ANY_PAGES = 0 -EFI_ALLOCATE_MAX_ADDRESS = 1 -EFI_ALLOCATE_ADDRESS = 2 - -EFI_MEMORY_UC = 0x00000001 -EFI_MEMORY_WC = 0x00000002 -EFI_MEMORY_WT = 0x00000004 -EFI_MEMORY_WB = 0x00000008 -EFI_MEMORY_UCE = 0x00000010 -EFI_MEMORY_WP = 0x00001000 -EFI_MEMORY_RP = 0x00002000 -EFI_MEMORY_XP = 0x00004000 -EFI_MEMORY_NV = 0x00008000 -EFI_MEMORY_MORE_RELIABLE = 0x00010000 -EFI_MEMORY_RO = 0x00020000 - -EFI_SUCCESS = 0 -EFI_LOAD_ERROR = EFIERR or 1 -EFI_INVALID_PARAMETER = EFIERR or 2 -EFI_UNSUPPORTED = EFIERR or 3 -EFI_BAD_BUFFER_SIZE = EFIERR or 4 -EFI_BUFFER_TOO_SMALL = EFIERR or 5 -EFI_NOT_READY = EFIERR or 6 -EFI_DEVICE_ERROR = EFIERR or 7 -EFI_WRITE_PROTECTED = EFIERR or 8 -EFI_OUT_OF_RESOURCES = EFIERR or 9 -EFI_VOLUME_CORRUPTED = EFIERR or 10 -EFI_VOLUME_FULL = EFIERR or 11 -EFI_NO_MEDIA = EFIERR or 12 -EFI_MEDIA_CHANGED = EFIERR or 13 -EFI_NOT_FOUND = EFIERR or 14 -EFI_ACCESS_DENIED = EFIERR or 15 -EFI_NO_RESPONSE = EFIERR or 16 -EFI_NO_MAPPING = EFIERR or 17 -EFI_TIMEOUT = EFIERR or 18 -EFI_NOT_STARTED = EFIERR or 19 -EFI_ALREADY_STARTED = EFIERR or 20 -EFI_ABORTED = EFIERR or 21 -EFI_ICMP_ERROR = EFIERR or 22 -EFI_TFTP_ERROR = EFIERR or 23 -EFI_PROTOCOL_ERROR = EFIERR or 24 - - -EFI_FILE_SYSTEM_INFO_ID equ 0x93,0x6e,0x57,0x09,0x3f,0x6d,0xd2,0x11, \ - 0x39,0x8e,0x00,0xa0,0xc9,0x69,0x72,0x3b - -EFI_SYSTEM_TABLE_SIGNATURE equ 0x49,0x42,0x49,0x20,0x53,0x59,0x53,0x54 - -EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID equ 0x22,0x5b,0x4e,0x96, \ - 0x59,0x64,0xd2,0x11, \ - 0x8e,0x39,0x00,0xa0, \ - 0xc9,0x69,0x72,0x3b - -EFI_LOADED_IMAGE_PROTOCOL_GUID equ 0xA1,0x31,0x1b,0x5b,0x62,0x95,0xd2,0x11, \ - 0x8E,0x3F,0x00,0xA0,0xC9,0x69,0x72,0x3B - -EFI_BLOCK_IO_PROTOCOL_GUID equ 0x21,0x5b,0x4e,0x96,0x59,0x64,0xd2,0x11, \ - 0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b - -EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID equ 0xde,0xa9,0x42,0x90,0xdc,0x23,0x38,0x4a, \ - 0x96,0xfb,0x7a,0xde,0xd0,0x80,0x51,0x6a - -EFI_FILE_MODE_READ = 1 -EFI_FILE_MODE_WRITE = 2 -EFI_FILE_MODE_CREATE = 0x8000000000000000 - -struct EFI_MEMORY_DESCRIPTOR - Type dd ? - dd ? ; align - PhysicalStart DQ ? - VirtualStart DQ ? - NumberOfPages DQ ? - Attribute DQ ? -ends - -struct EFI_FILE_SYSTEM_INFO - Size DQ ? - ReadOnly db ? - rb 7 - VolumeSize DQ ? - FreeSpace DQ ? - BlockSize dd ? - VolumeLabel rw 32 -ends - -struct EFI_TABLE_HEADER - Signature DQ ? - Revision dd ? - HeaderSize dd ? - CRC32 dd ? - Reserved dd ? -ends - -struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL - Reset DN ? - OutputString DN ? - TestString DN ? - QueryMode DN ? - SetMode DN ? - SetAttribute DN ? - ClearScreen DN ? - SetCursorPosition DN ? - EnableCursor DN ? - Mode DN ? -ends - - -struct SIMPLE_INPUT_INTERFACE - Reset DN ? - ReadKeyStroke DN ? - WaitForKey DN ? -ends - -struct EFI_BOOT_SERVICES - Hdr EFI_TABLE_HEADER - RaisePriority DN ? - RestorePriority DN ? - AllocatePages DN ? - FreePages DN ? - GetMemoryMap DN ? - AllocatePool DN ? - FreePool DN ? - CreateEvent DN ? - SetTimer DN ? - WaitForEvent DN ? - SignalEvent DN ? - CloseEvent DN ? - CheckEvent DN ? - InstallProtocolInterface DN ? - ReInstallProtocolInterface DN ? - UnInstallProtocolInterface DN ? - HandleProtocol DN ? - Reserved DN ? - RegisterProtocolNotify DN ? - LocateHandle DN ? - LocateDevicePath DN ? - InstallConfigurationTable DN ? - ImageLoad DN ? - ImageStart DN ? - Exit DN ? - ImageUnLoad DN ? - ExitBootServices DN ? - GetNextMonotonicCount DN ? - Stall DN ? - SetWatchdogTimer DN ? - ConnectController DN ? - DisConnectController DN ? - OpenProtocol DN ? - CloseProtocol DN ? - OpenProtocolInformation DN ? - ProtocolsPerHandle DN ? - LocateHandleBuffer DN ? - LocateProtocol DN ? - InstallMultipleProtocolInterfaces DN ? - UnInstallMultipleProtocolInterfaces DN ? - CalculateCrc32 DN ? - CopyMem DN ? - SetMem DN ? -ends - -struct EFI_RUNTIME_SERVICES - Hdr EFI_TABLE_HEADER - GetTime DN ? - SetTime DN ? - GetWakeUpTime DN ? - SetWakeUpTime DN ? - SetVirtualAddressMap DN ? - ConvertPointer DN ? - GetVariable DN ? - GetNextVariableName DN ? - SetVariable DN ? - GetNextHighMonoCount DN ? - ResetSystem DN ? -ends - -struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL - Revision DQ ? - OpenVolume DN ? -ends - -struct EFI_FILE_PROTOCOL - Revision DQ ? - Open DN ? - Close DN ? - Delete DN ? - Read DN ? - Write DN ? - GetPosition DN ? - SetPosition DN ? - GetInfo DN ? - SetInfo DN ? - Flush DN ? - OpenEx DN ? - ReadEx DN ? - WriteEx DN ? - FlushEx DN ? -ends - -struct EFI_GRAPHICS_OUTPUT_PROTOCOL - QueryMode DN ? - SetMode DN ? - Blt DN ? - Mode DN ? -ends - -struct EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE - MaxMode dd ? - Mode dd ? - Info DN ? - SizeOfInfo DN ? - FrameBufferBase DQ ? - FrameBufferSize DN ? -ends - -EFI_GRAPHICS_PIXEL_FORMAT: -.PixelRedGreenBlueReserved8BitPerColor = 0 -.PixelBlueGreenRedReserved8BitPerColor = 1 -.PixelBitMask = 2 -.PixelBltOnly = 3 -.PixelFormatMax = 4 - -struct EFI_PIXEL_BITMASK - RedMask dd ? - GreenMask dd ? - BlueMask dd ? - ReservedMask dd ? -ends - -struct EFI_GRAPHICS_OUTPUT_MODE_INFORMATION - Version dd ? - HorizontalResolution dd ? - VerticalResolution dd ? - PixelFormat dd ? - PixelInformation EFI_PIXEL_BITMASK - PixelsPerScanLine dd ? -ends diff --git a/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi32.inc b/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi32.inc deleted file mode 100644 index 7b55a6b56..000000000 --- a/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi32.inc +++ /dev/null @@ -1,58 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2020. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; Version 2, or (at your option) any later version. ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Based on UEFI library for fasm by bzt, Public Domain. ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -DN fix dd ; native - -include "uefi.inc" - -EFIERR = 0x80000000 - -struct EFI_SYSTEM_TABLE - Hdr EFI_TABLE_HEADER - FirmwareVendor dd ? - FirmwareRevision dd ? - ConsoleInHandle dd ? - ConIn dd ? - ConsoleOutHandle dd ? - ConOut dd ? - StandardErrorHandle dd ? - StdErr dd ? - RuntimeServices dd ? - BootServices dd ? - NumberOfTableEntries dd ? - ConfigurationTable dd ? -ends - -struct EFI_CONFIGURATION_TABLE - VendorGUID rd 4 - VendorTable dd ? -ends - -struct EFI_LOADED_IMAGE_PROTOCOL - Revision dd ? - ParentHandle dd ? - SystemTable dd ? - DeviceHandle dd ? - FilePath dd ? - Reserved dd ? - LoadOptionsSize dd ? - ImageBase dd ? - ImageSize DQ ? - ImageCodeType dd ? - ImageDataType dd ? - UnLoad dd ? -ends - -section '.text' code executable readable - -uefifunc: - ret diff --git a/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi32kos.asm b/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi32kos.asm deleted file mode 100644 index a4be7bf01..000000000 --- a/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi32kos.asm +++ /dev/null @@ -1,990 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2020. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; Version 2, or (at your option) any later version. ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -format pe efi -entry main - -section '.text' code executable readable - -include '../../struct.inc' -include '../../macros.inc' -include '../../proc32.inc' -include '../../const.inc' -include 'uefi32.inc' - -MEMORY_MAP_SIZE = 0x4000 -GOP_BUFFER_SIZE = 0x100 -LIP_BUFFER_SIZE = 0x100 -FILE_BUFFER_SIZE = 0x1000 - -KERNEL_BASE = 0x10000 -RAMDISK_BASE = 0x100000 -MAX_FILE_SIZE = 0x10000000 - -CODE_32_SELECTOR = 8 -DATA_32_SELECTOR = 16 - -; linux/arch/x86/include/uapi/asm/e820.h -E820_RAM = 1 -E820_RESERVED = 2 -E820_ACPI = 3 -E820_NVS = 4 -E820_UNUSABLE = 5 -E820_PMEM = 7 - -proc load_file stdcall uses ebx esi edi, _root, _name, _buffer, _size, _fatal - mov eax, [_root] - ccall [eax+EFI_FILE_PROTOCOL.Open], eax, file_handle, [_name], \ - EFI_FILE_MODE_READ, 0 - test eax, eax - jz @f - xor eax, eax - cmp [_fatal], 1 - jnz .done - mov ebx, [efi_table] - mov ebx, [ebx+EFI_SYSTEM_TABLE.ConOut] - ccall [ebx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], ebx, \ - msg_error_open_file - ccall [ebx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], ebx, \ - [_name] - jmp $ -@@: - mov eax, [file_handle] - lea ecx, [_size] - ccall [eax+EFI_FILE_PROTOCOL.Read], eax, ecx, [_buffer] - mov eax, [file_handle] - ccall [eax+EFI_FILE_PROTOCOL.Close], eax - mov eax, [_size] -.done: - ret -endp - -proc skip_whitespace -.next_char: - cmp byte[esi], 0 - jz .done - cmp byte[esi], 0x20 ; ' ' - jz .whitespace - cmp byte[esi], 9 ; '\t' - jz .whitespace - jmp .done -.whitespace: - inc esi - jmp .next_char -.done: - ret -endp - -proc skip_until_newline -.next_char: - cmp byte[esi], 0 - jz .done - cmp byte[esi], 0xd ; '\r' - jz .done - cmp byte[esi], 0xa ; '\n' - jz .done - inc esi - jmp .next_char -.done: - ret -endp - -proc skip_newline -.next_char: - cmp byte[esi], 0xd ; '\r' - jz .newline - cmp byte[esi], 0xa ; '\n' - jz .newline - jmp .done -.newline: - inc esi - jmp .next_char -.done: - ret -endp - -proc skip_line - call skip_until_newline - call skip_newline - ret -endp - -proc dec2bin - mov edx, 0 -.next_char: - movzx eax, byte[esi] - test eax, eax - jz .done - sub eax, '0' - jb .done - cmp eax, 9 - ja .done - inc esi - imul edx, 10 - add edx, eax - jmp .next_char -.done: - mov eax, edx - ret -endp - -proc parse_option - mov ebx, config_options-3*4 -.try_next_option: - add ebx, 3*4 - mov edi, esi - mov edx, [ebx] ; option name - test edx, edx - jz .done -.next_char: - cmp byte[edx], 0 - jnz @f - cmp byte[edi], '=' - jz .opt_name_ok -@@: - cmp byte[edi], 0 - jz .done - movzx eax, byte[edi] - cmp [edx], al - jnz .try_next_option - inc edi - inc edx - jmp .next_char -.opt_name_ok: - inc edi - mov esi, edi - call dword[ebx+4] -.done: - ret -endp - -proc parse_line -.next_line: - cmp byte[esi], 0 - jz .done - cmp byte[esi], 0xd ; '\r' - jz .skip - cmp byte[esi], 0xa ; '\n' - jz .skip - cmp byte[esi], '#' - jz .skip - call parse_option - call skip_line - jmp .next_line -.skip: - call skip_line - jmp .next_line -.done: - ret -endp - -proc cfg_opt_func_resolution - call dec2bin - xor edx, edx - mov [edx+BOOT_LO.x_res], ax - cmp byte[esi], 'x' - jz @f - cmp byte[esi], '*' - jz @f - jmp .done -@@: - inc esi - call dec2bin - xor edx, edx - mov [edx+BOOT_LO.y_res], ax - mov [cfg_opt_used_resolution], 1 -.done: - ret -endp - -proc cfg_opt_func_acpi - call dec2bin - mov [cfg_opt_used_acpi], 1 - mov [cfg_opt_value_acpi], al - ret -endp - -proc cfg_opt_func_debug_print - call dec2bin - mov [cfg_opt_used_debug_print], 1 - mov [cfg_opt_value_debug_print], al - ret -endp - -proc cfg_opt_func_launcher_start - call dec2bin - mov [cfg_opt_used_launcher_start], 1 - mov [cfg_opt_value_launcher_start], al - ret -endp - -proc cfg_opt_func_mtrr - call dec2bin - mov [cfg_opt_used_mtrr], 1 - mov [cfg_opt_value_mtrr], al - ret -endp - -proc cfg_opt_func_ask_params - call dec2bin - mov [cfg_opt_used_ask_params], 1 - mov [cfg_opt_value_ask_params], al - ret -endp - -proc cfg_opt_func_imgfrom - call dec2bin - mov [cfg_opt_used_imgfrom], 1 - mov [cfg_opt_value_imgfrom], al - ret -endp - -proc cfg_opt_func_syspath - mov edi, cfg_opt_value_syspath -.next_char: - movzx eax, byte[esi] - cmp al, 0xd ; \r - jz .done - cmp al, 0xa ; \n - jz .done - inc esi - stosb - jmp .next_char -.done: - mov byte[edi], 0 - ret -endp - -proc parse_config stdcall uses ebx esi edi, _buffer -; mov esi, [_buffer] - mov esi, KERNEL_BASE -.next_line: - call parse_line - cmp byte[esi], 0 - jnz .next_line - ret -endp - -proc read_options_from_config stdcall uses ebx esi edi - mov ebx, [efi_table] - mov ebx, [ebx+EFI_SYSTEM_TABLE.BootServices] - ccall [ebx+EFI_BOOT_SERVICES.HandleProtocol], [efi_handle], \ - lipuuid, lip_interface - test eax, eax - jnz .error - mov eax, [lip_interface] - - mov ebx, [efi_table] - mov ebx, [ebx+EFI_SYSTEM_TABLE.BootServices] - ccall [ebx+EFI_BOOT_SERVICES.HandleProtocol], \ - [eax+EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle], sfspguid, \ - sfsp_interface - test eax, eax - jnz .error - - mov eax, [sfsp_interface] - ccall [eax+EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume], eax, esp_root - test eax, eax - jnz .error - - stdcall load_file, [esp_root], file_name, KERNEL_BASE, \ - FILE_BUFFER_SIZE, 0 - test eax, eax - jz @f - stdcall parse_config, KERNEL_BASE -@@: -.error: - ret -endp - -proc print_vmode uses eax ebx ecx esi edi, _gop_if - mov ebx, [_gop_if] - call clearbuf - mov eax, [ebx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution] - mov edi, msg - call num2dec - mov eax, [ebx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution] - mov edi, msg+8*2 - call num2dec - - mov eax, [ebx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat] - mov edi, msg+16*2 - call num2dec - - mov eax, [ebx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine] - mov edi, msg+24*2 - call num2dec - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg - ret -endp - -proc find_vmode_index_by_resolution uses ebx esi edi - mov [cfg_opt_value_vmode], 0 -.next_mode: -; mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] -; ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ -; msg_query_vmode - - movzx ecx, [cfg_opt_value_vmode] - mov eax, [gop_interface] - ccall [eax+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], eax, ecx, \ - gop_info_size, gop_info - test eax, eax - jz @f - call clearbuf - mov edi, msg - call num2hex - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg - jmp .skip_mode -@@: - mov ecx, [gop_info] - stdcall print_vmode, ecx - ; PixelBlueGreenRedReserved8BitPerColor - cmp [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat], 1 - jnz .skip_mode - xor edx, edx - mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution] - cmp ax, [edx+BOOT_LO.x_res] - jnz .skip_mode - mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution] - cmp ax, [edx+BOOT_LO.y_res] - jnz .skip_mode - jmp .done -.skip_mode: - inc [cfg_opt_value_vmode] - movzx eax, [cfg_opt_value_vmode] - mov ecx, [gop_interface] - mov edx, [ecx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode] - cmp eax, [edx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode] - jnz .next_mode - mov [cfg_opt_used_resolution], 0 - mov [cfg_opt_value_ask_params], 1 - - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_error_no_such_vmode - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg_error - jmp $ -.error: -.done: - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_vmode_found - ret -endp - -proc ask_for_params - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_ask_for_params - jmp $ -.error: -.done: - ret -endp - -main: - mov esi, [esp+4] - mov [efi_handle], esi - mov esi, [esp+8] - mov [efi_table], esi - - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset], eax, 1 - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_u4k_loaded - - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_read_options - call read_options_from_config - - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_load_kernel - stdcall load_file, [esp_root], kernel_name, KERNEL_BASE, MAX_FILE_SIZE, 1 - - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_load_ramdisk - stdcall load_file, [esp_root], ramdisk_name, RAMDISK_BASE, MAX_FILE_SIZE, 1 - - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_alloc_devicesdat - - mov eax, [esi+EFI_SYSTEM_TABLE.BootServices] - ccall [eax+EFI_BOOT_SERVICES.AllocatePages], \ - EFI_ALLOCATE_MAX_ADDRESS, EFI_RESERVED_MEMORY_TYPE, 1, \ - devicesdat_data - call halt_on_error - - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_load_devicesdat - - ccall load_file, [esp_root], devicesdat_name, [devicesdat_data], \ - [devicesdat_size], 0 - mov [devicesdat_size], eax - - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_locate_gop_handlers - - mov eax, [esi+EFI_SYSTEM_TABLE.BootServices] - ccall [eax+EFI_BOOT_SERVICES.LocateHandle], \ - EFI_LOCATE_SEARCH_TYPE.ByProtocol, gopuuid, 0, \ - gop_buffer_size, gop_buffer - mov [status], eax - - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_gop_buffer_size - call clearbuf - mov eax, [gop_buffer_size] - mov edi, msg - call num2hex - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg - - mov eax, [status] - call halt_on_error - - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_look_for_gop_handler - - mov ebx, gop_buffer -.next_gop_handle: - mov eax, ebx - sub eax, gop_buffer - cmp eax, [gop_buffer_size] - jb @f - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_error_out_of_handlers - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg_error - jmp $ -@@: - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_query_handler - - mov eax, [esi+EFI_SYSTEM_TABLE.BootServices] - ccall [eax+EFI_BOOT_SERVICES.HandleProtocol], \ - [ebx], gopuuid, gop_interface -;mov eax, 0x80000003 - test eax, eax - jz @f - call clearbuf - mov edi, msg - call num2hex - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg - - add ebx, 4 - jmp .next_gop_handle -@@: - - call find_rsdp - - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_acpi_tables_done - - cmp [cfg_opt_used_resolution], 0 - jz .not_used_resolution - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_opt_resolution - call clearbuf - xor edx, edx - movzx eax, [edx+BOOT_LO.x_res] - mov edi, msg - call num2dec - xor edx, edx - movzx eax, [edx+BOOT_LO.y_res] - mov edi, msg+8*2 - call num2dec - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg - - call find_vmode_index_by_resolution -.not_used_resolution: - cmp [cfg_opt_used_debug_print], 0 - jz .not_used_debug_print - movzx eax, [cfg_opt_value_debug_print] - xor edx, edx - mov [edx+BOOT_LO.debug_print], al -.not_used_debug_print: - - cmp [cfg_opt_value_ask_params], 0 - jz @f - call ask_for_params -@@: - - movzx ecx, [cfg_opt_value_vmode] - mov eax, [gop_interface] - ccall [eax+EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode], eax, ecx - call halt_on_error - - mov ecx, [gop_interface] - mov edx, [ecx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode] - mov edi, [edx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.FrameBufferBase.lo] - mov [fb_base], edi - - - mov ebx, [edx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.Mode] - mov eax, [gop_interface] - ccall [eax+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], eax, ebx, \ - gop_info_size, gop_info - test eax, eax - jnz .error - mov ecx, [gop_info] - mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution] - xor edx, edx - mov [edx+BOOT_LO.x_res], ax - mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution] - mov [edx+BOOT_LO.y_res], ax - mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine] - shl eax, 2 - mov [edx+BOOT_LO.pitch], ax - - mov byte[edx+BOOT_LO.pci_data+0], 1 ; PCI access mechanism - mov byte[edx+BOOT_LO.pci_data+1], 8 ; last bus, don't know how to count them - mov byte[edx+BOOT_LO.pci_data+2], 0x10 ; PCI version - mov byte[edx+BOOT_LO.pci_data+3], 0x02 - mov dword[edx+BOOT_LO.pci_data+4], 0xe3 - - ; kernel -; eficall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \ -; 450000/0x1000, EFI_ALLOCATE_ADDRESS - - ; ramdisk -; eficall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \ -; 2880*512/0x1000, EFI_ALLOCATE_ADDRESS - - call calc_memmap -; call dump_memmap - - mov eax, [efi_table] - mov eax, [eax+EFI_SYSTEM_TABLE.BootServices] - ccall [eax+EFI_BOOT_SERVICES.ExitBootServices], [efi_handle], \ - [memory_map_key] - call halt_on_error - - cli - - xor edx, edx - xor esi, esi - mov [esi+BOOT_LO.bpp], 32 - mov [esi+BOOT_LO.vesa_mode], dx - mov [esi+BOOT_LO.bank_switch], edx - mov edi, [fb_base] - mov [esi+BOOT_LO.lfb], edi - - movzx eax, [cfg_opt_value_mtrr] - mov [esi+BOOT_LO.mtrr], al - - movzx eax, [cfg_opt_value_launcher_start] - mov [esi+BOOT_LO.launcher_start], al - - movzx eax, [cfg_opt_value_debug_print] - mov [esi+BOOT_LO.debug_print], al - - mov [esi+BOOT_LO.dma], dl -; mov qword[esi+BOOT_LO.pci_data], 0 - mov [esi+BOOT_LO.apm_entry], edx - mov [esi+BOOT_LO.apm_version], dx - mov [esi+BOOT_LO.apm_flags], dx - mov [esi+BOOT_LO.apm_code_32], dx - mov [esi+BOOT_LO.apm_code_16], dx - mov [esi+BOOT_LO.apm_data_16], dx - mov [esi+BOOT_LO.bios_hd_cnt], dl - - movzx eax, [cfg_opt_value_imgfrom] - mov [esi+BOOT_LO.rd_load_from], al - - mov eax, dword[devicesdat_size] - mov [edx+BOOT_LO.devicesdat_size], eax - mov eax, dword[devicesdat_data] - mov [edx+BOOT_LO.devicesdat_data], eax - - mov esi, cfg_opt_value_syspath - mov edi, BOOT_LO.syspath - mov ecx, 0x17 - rep movsb - - lgdt [cs:GDTR] - - mov ax, DATA_32_SELECTOR - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - push CODE_32_SELECTOR - lea eax, [.next] - push eax - retf - -.next: - mov eax, cr0 - and eax, not CR0_PG - mov cr0, eax - - mov eax, cr4 - and eax, not CR4_PAE - mov cr4, eax - - push KERNEL_BASE - retn - -.error: - mov esi, [efi_table] - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_error - jmp $ - -halt_on_error: - test eax, eax - jz @f - call clearbuf - mov edi, msg - call num2hex - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_error - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg - jmp $ -@@: - ret - -proc find_rsdp - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_look_for_rsdp - - mov edi, [esi+EFI_SYSTEM_TABLE.ConfigurationTable] - mov ecx, [esi+EFI_SYSTEM_TABLE.NumberOfTableEntries] -.next_table: - dec ecx - js .all_tables_done - ; EFI_ACPI_TABLE_GUID - cmp dword[edi+EFI_CONFIGURATION_TABLE.VendorGUID+0x0], 0x8868e871 - jnz .not_acpi20 - cmp dword[edi+EFI_CONFIGURATION_TABLE.VendorGUID+0x4], 0x11d3e4f1 - jnz .not_acpi20 - cmp dword[edi+EFI_CONFIGURATION_TABLE.VendorGUID+0x8], 0x800022bc - jnz .not_acpi20 - cmp dword[edi+EFI_CONFIGURATION_TABLE.VendorGUID+0xc], 0x81883cc7 - jnz .not_acpi20 - mov eax, [edi+EFI_CONFIGURATION_TABLE.VendorTable] - mov edx, BOOT_LO.acpi_rsdp - mov [edx], eax - mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] - ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ - msg_rsdp_found - jmp .all_tables_done -.not_acpi20: - add edi, sizeof.EFI_CONFIGURATION_TABLE - jmp .next_table -.all_tables_done: - ret -endp - -proc calc_memmap - mov eax, [esi+EFI_SYSTEM_TABLE.BootServices] - ccall [eax+EFI_BOOT_SERVICES.AllocatePages], EFI_ALLOCATE_ANY_PAGES, \ - EFI_RESERVED_MEMORY_TYPE, MEMORY_MAP_SIZE/0x1000, memory_map - call halt_on_error - - mov eax, [esi+EFI_SYSTEM_TABLE.BootServices] - ccall [eax+EFI_BOOT_SERVICES.GetMemoryMap], memory_map_size, \ - [memory_map], memory_map_key, descriptor_size, descriptor_ver - call halt_on_error - - push esi - mov edi, BOOT_LO.memmap_blocks - mov dword[edi-4], 0 ; memmap_block_cnt - mov esi, [memory_map] - mov ebx, esi - add ebx, [memory_map_size] -.next_descr: - call add_uefi_memmap - add esi, [descriptor_size] - cmp esi, ebx - jb .next_descr - pop esi - ret -endp - -; linux/arch/x86/platform/efi/efi.c -; do_add_efi_memmap -proc add_uefi_memmap - cmp [BOOT_LO.memmap_block_cnt], MAX_MEMMAP_BLOCKS - jz .done - - mov eax, [esi+EFI_MEMORY_DESCRIPTOR.PhysicalStart.lo] - mov edx, [esi+EFI_MEMORY_DESCRIPTOR.PhysicalStart.hi] - mov [edi+e820entry.addr.lo], eax - mov [edi+e820entry.addr.hi], edx - - mov eax, [esi+EFI_MEMORY_DESCRIPTOR.NumberOfPages.lo] - mov edx, [esi+EFI_MEMORY_DESCRIPTOR.NumberOfPages.hi] - shld edx, eax, 12 - shl eax, 12 - mov [edi+e820entry.size.lo], eax - mov [edi+e820entry.size.hi], edx - - mov ecx, [esi+EFI_MEMORY_DESCRIPTOR.Type] - cmp ecx, EFI_LOADER_CODE - jz .mem_ram_if_wb - cmp ecx, EFI_LOADER_DATA - jz .mem_ram_if_wb - cmp ecx, EFI_BOOT_SERVICES_CODE - jz .mem_ram_if_wb - cmp ecx, EFI_BOOT_SERVICES_DATA - jz .mem_ram_if_wb - cmp ecx, EFI_CONVENTIONAL_MEMORY - jz .mem_ram_if_wb - cmp ecx, EFI_ACPI_RECLAIM_MEMORY - mov eax, E820_ACPI - jz .type_done - cmp ecx, EFI_ACPI_MEMORY_NVS - mov eax, E820_NVS - jz .type_done - cmp ecx, EFI_UNUSABLE_MEMORY - mov eax, E820_UNUSABLE - jz .type_done - cmp ecx, EFI_PERSISTENT_MEMORY - mov eax, E820_PMEM - jz .type_done - jmp .reserved -.mem_ram_if_wb: - test [esi+EFI_MEMORY_DESCRIPTOR.Attribute.lo], EFI_MEMORY_WB - mov eax, E820_RAM - jnz .type_done -.reserved: - mov eax, E820_RESERVED -.type_done: - mov [edi+e820entry.type], eax - cmp eax, E820_RAM - jnz @f - inc [BOOT_LO.memmap_block_cnt] - add edi, sizeof.e820entry -@@: -.done: - ret -endp - - -proc num2dec - pushad - - xor ecx, ecx - mov ebx, 10 -.next_digit: - xor edx, edx - div ebx - push edx - inc ecx - test eax, eax - jnz .next_digit - -.next_char: - pop eax - add eax, '0' - stosw - loop .next_char - - popad - ret -endp - - -proc num2hex - pushad - - xchg edx, eax - mov ecx, 8 -.next_tetra: - rol edx, 4 - movzx eax, dl - and eax, 0x0f - movzx eax, byte[hex+eax] - stosw - loop .next_tetra - - popad - ret -endp - - -hex db '0123456789ABCDEF' - -proc clearbuf - pushad - mov eax, 0x0020 - mov ecx, 79 - mov edi, msg - rep stosw - popad - ret -endp - -section '.rodata' data readable -align 16 -GDTR: - dw 3*8-1 - dq GDT -align 16 -GDT: - dw 0, 0, 0, 0 - dw 0FFFFh,0,9A00h,0CFh ; 32-bit code - dw 0FFFFh,0,9200h,0CFh ; flat data - -gopuuid db EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID -lipuuid db EFI_LOADED_IMAGE_PROTOCOL_GUID -sfspguid db EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID - -file_name du "\EFI\KOLIBRIOS\KOLIBRI.INI",0 -kernel_name du "\EFI\KOLIBRIOS\KOLIBRI.KRN",0 -ramdisk_name du "\EFI\KOLIBRIOS\KOLIBRI.IMG",0 -devicesdat_name du "\EFI\KOLIBRIOS\DEVICES.DAT",0 - -config_options dd cfg_opt_name_resolution, cfg_opt_func_resolution, \ - cfg_opt_cmnt_resolution, \ - cfg_opt_name_acpi, cfg_opt_func_acpi, cfg_opt_cmnt_acpi, \ - cfg_opt_name_debug_print, cfg_opt_func_debug_print, \ - cfg_opt_cmnt_debug_print, \ - cfg_opt_name_launcher_start, cfg_opt_func_launcher_start, \ - cfg_opt_cmnt_launcher_start, \ - cfg_opt_name_mtrr, cfg_opt_func_mtrr, cfg_opt_cmnt_mtrr, \ - cfg_opt_name_ask_params, cfg_opt_func_ask_params, \ - cfg_opt_cmnt_ask_params, \ - cfg_opt_name_imgfrom, cfg_opt_func_imgfrom, \ - cfg_opt_cmnt_imgfrom, \ - cfg_opt_name_syspath, cfg_opt_func_syspath, \ - cfg_opt_cmnt_syspath, \ - 0 - -cfg_opt_name_resolution db "resolution",0 -cfg_opt_name_acpi db "acpi",0 -cfg_opt_name_debug_print db "debug_print",0 -cfg_opt_name_launcher_start db "launcher_start",0 -cfg_opt_name_mtrr db "mtrr",0 -cfg_opt_name_ask_params db "ask_params",0 -cfg_opt_name_imgfrom db "imgfrom",0 -cfg_opt_name_syspath db "syspath",0 - -cfg_opt_cmnt_resolution db "# Graphic mode",0 -cfg_opt_cmnt_acpi db "# ACPI settings",0xa, \ - "# 0: don't use",0xa, \ - "# 1: parse ACPI tables",0xa, \ - "# 2: + call _PIC method",0xa, \ - "# 3: + get APIC interrupts",0xa,0 -cfg_opt_cmnt_debug_print db "# Duplicate debug output to the screen",0 -cfg_opt_cmnt_launcher_start db "# Start LAUNCHER app after kernel is loaded",0 -cfg_opt_cmnt_mtrr db "# Configure MTRR's",0 -cfg_opt_cmnt_ask_params db "# Interrupt booting to ask the user for boot", \ - " params",0 -cfg_opt_cmnt_imgfrom db "# Where to load ramdisk image from",0 -cfg_opt_cmnt_syspath db "# Path to /sys directory",0 - -msg_u4k_loaded du "uefi32kos loaded",13,10,0 -msg_read_options du "Read options from config file",13,10,0 -msg_load_kernel du "Load kernel",13,10,0 -msg_load_ramdisk du "Load ramdisk",13,10,0 -msg_load_devicesdat du "Load DEVICES.DAT",13,10,0 -msg_alloc_devicesdat du "Allocate memory for DEVICES.DAT",13,10,0 -msg_locate_gop_handlers du "Locate GOP handlers",13,10,0 -msg_look_for_gop_handler du "Look for GOP handler",13,10,0 -msg_query_handler du "Query handler",13,10,0 -msg_query_vmode du "Query vmode",13,10,0 -msg_vmode_found du "Video mode found",13,10,0 -msg_look_for_rsdp du "Look for RSDP",13,10,0 -msg_rsdp_found du "RSDP found",13,10,0 -msg_acpi_tables_done du "ACPI tables done",13,10,0 -msg_ask_for_params du "Ask for params",13,10,0 -msg_set_graphic_mode du "Set graphic mode",13,10,0 -msg_success du "Success!",13,10,0 -msg_gop_buffer_size du "GOP buffer size",13,10,0 -msg_opt_resolution du "option resolution: ",0 -msg_error du "Error!",13,10,0 -msg_error_no_such_vmode du "No such vmode",13,10,0 -msg_error_out_of_handlers du "Out of handlers",13,10,0 -msg_error_open_file du "Error: can't open file ",0 -msg du 79 dup " ",13,10,0 - - -section '.data' data readable writeable -efi_handle dd 0 -efi_table dd 0 - -fb_base dd 0 - -gop_buffer_size dd GOP_BUFFER_SIZE -gop_handle dd 0 -gop_interface dd 0 -gop_info_size dd 0 -gop_info dd 0 - -lip_buffer_size dd LIP_BUFFER_SIZE -lip_handle dd 0 -lip_interface dd 0 - -sfsp_interface dd 0 - -esp_root dd ? -file_handle dd ? -file_buffer_size dd FILE_BUFFER_SIZE-1 ; leave the last byte for \0 - -cfg_opt_used_resolution db 0 -cfg_opt_used_acpi db 0 -cfg_opt_used_debug_print db 0 -cfg_opt_used_launcher_start db 0 -cfg_opt_used_mtrr db 0 -cfg_opt_used_ask_params db 0 -cfg_opt_used_imgfrom db 0 -cfg_opt_used_syspath db 0 - -cfg_opt_value_vmode db 0 -cfg_opt_value_acpi db 0 -cfg_opt_value_debug_print db 0 -cfg_opt_value_launcher_start db 1 -cfg_opt_value_mtrr db 0 -cfg_opt_value_ask_params db 0 -cfg_opt_value_imgfrom db RD_LOAD_FROM_MEMORY -cfg_opt_value_syspath db "/RD/1",0 - rb 20 - -memory_map_key dd 0 -descriptor_size dd 0 -descriptor_ver dd 0 -memory_map_size dd MEMORY_MAP_SIZE - -efi_fs_info_id db EFI_FILE_SYSTEM_INFO_ID -efi_fs_info_size dq sizeof.EFI_FILE_SYSTEM_INFO -efi_fs_info EFI_FILE_SYSTEM_INFO - -memory_map dd ? -gop_buffer rd GOP_BUFFER_SIZE/4 -devicesdat_data dd 0xffffffff -devicesdat_size dd 0x1000 -status dd ? - -section '.reloc' fixups data discardable diff --git a/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi64.inc b/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi64.inc deleted file mode 100644 index b565bae0c..000000000 --- a/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi64.inc +++ /dev/null @@ -1,196 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2020. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; Version 2, or (at your option) any later version. ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Based on UEFI library for fasm by bzt, Public Domain. ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -DN fix dq ; native - -include "uefi.inc" - -EFIERR = 0x8000000000000000 - -struct EFI_SYSTEM_TABLE - Hdr EFI_TABLE_HEADER - FirmwareVendor dq ? - FirmwareRevision dd ? - dd ? - ConsoleInHandle dq ? - ConIn dq ? - ConsoleOutHandle dq ? - ConOut dq ? - StandardErrorHandle dq ? - StdErr dq ? - RuntimeServices dq ? - BootServices dq ? - NumberOfTableEntries dq ? - ConfigurationTable dq ? -ends - -struct EFI_LOADED_IMAGE_PROTOCOL - Revision dd ? - dd ? - ParentHandle dq ? - SystemTable dq ? - DeviceHandle dq ? - FilePath dq ? - Reserved dq ? - LoadOptionsSize dd ? - dd ? - ImageBase dq ? - ImageSize dq ? - ImageCodeType dd ? - ImageDataType dd ? - UnLoad dq ? -ends - -macro eficall interface,function,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11 -{ -numarg = 0 - -if ~ arg11 eq - numarg = numarg + 1 - if ~ arg11 eq rdi - mov rdi, arg11 - end if -end if - -if ~ arg10 eq - numarg = numarg + 1 - if ~ arg10 eq rsi - mov rsi, arg10 - end if -end if - -if ~ arg9 eq - numarg = numarg + 1 - if ~ arg9 eq r14 - mov r14, arg9 - end if -end if - -if ~ arg8 eq - numarg = numarg + 1 - if ~ arg8 eq r13 - mov r13, arg8 - end if -end if - -if ~ arg7 eq - numarg = numarg + 1 - if ~ arg7 eq r12 - mov r12, arg7 - end if -end if - -if ~ arg6 eq - numarg = numarg + 1 - if ~ arg6 eq r11 - mov r11, arg6 - end if -end if - -if ~ arg5 eq - numarg = numarg + 1 - if ~ arg5 eq r10 - mov r10, arg5 - end if -end if - -if ~ arg4 eq - numarg = numarg + 1 - if ~ arg4 eq r9 - mov r9, arg4 - end if -end if - -if ~ arg3 eq - numarg = numarg + 1 - if ~ arg3 eq r8 - mov r8, arg3 - end if -end if - -if ~ arg2 eq - numarg = numarg + 1 - if ~ arg2 eq rdx - mov rdx, arg2 - end if -end if - -if ~ arg1 eq - numarg = numarg + 1 - if ~ arg1 eq rcx - mov rcx, arg1 - end if -end if - - xor eax, eax - mov al, numarg - -if ~ interface eq rbx - mov rbx, interface -end if - - mov rbx, [rbx + function] - call uefifunc -} - -section '.text' code executable readable - -uefifunc: - ;save stack pointer - mov [uefi_rsptmp], rsp - ;set up new aligned stack - and esp, 0xFFFFFFF0 - ;alignment check on arguments - bt eax, 0 - jnc @f - push rax - ;arguments -@@: - cmp al, 11 - jb @f - push rdi -@@: - cmp al, 10 - jb @f - push rsi -@@: - cmp al, 9 - jb @f - push r14 -@@: - cmp al, 8 - jb @f - push r13 -@@: - cmp al, 7 - jb @f - push r12 -@@: - cmp al, 6 - jb @f - push r11 -@@: - cmp al, 5 - jb @f - push r10 -@@: - ;space for - ;r9 - ;r8 - ;rdx - ;rcx - sub rsp, 4*8 - ;call function - call rbx - ;restore old stack - mov rsp, [uefi_rsptmp] - ret diff --git a/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi64kos.asm b/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi64kos.asm deleted file mode 100644 index 927b0d6e0..000000000 --- a/kernel/branches/Kolibri-F/bootloader/uefi4kos/uefi64kos.asm +++ /dev/null @@ -1,1249 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2020. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; Version 2, or (at your option) any later version. ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -format pe64 efi -entry main - -section '.text' code executable readable - -include '../../struct.inc' -include '../../macros.inc' -include '../../const.inc' - -purge DQ -include 'uefi64.inc' - -MEMORY_MAP_SIZE = 0x10000 -GOP_BUFFER_SIZE = 0x100 -LIP_BUFFER_SIZE = 0x100 -FILE_BUFFER_SIZE = 0x1000 - -KERNEL_TRAMPOLINE = 0x8f80 ; just before BOOT_LO -KERNEL_BASE = 0x10000 -RAMDISK_BASE = 0x100000 -MAX_FILE_SIZE = 0x10000000 - -CODE_32_SELECTOR = 8 -DATA_32_SELECTOR = 16 -CODE_64_SELECTOR = 24 - -; linux/arch/x86/include/uapi/asm/e820.h -E820_RAM = 1 -E820_RESERVED = 2 -E820_ACPI = 3 -E820_NVS = 4 -E820_UNUSABLE = 5 -E820_PMEM = 7 - -load_file: -virtual at rsp+8 - .root dq ? - .name dq ? - .buffer dq ? - .size dq ? - .fatal dq ? -end virtual - eficall [.root], EFI_FILE_PROTOCOL.Open, [.root], file_handle, \ - [.name], EFI_FILE_MODE_READ, 0 - test eax, eax - jz @f - xor eax, eax - cmp [.fatal], 1 - jnz .done - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_error_open_file - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - [.name] - jmp $ -@@: - - lea rax, [.size] - eficall [file_handle], EFI_FILE_PROTOCOL.Read, [file_handle], rax, \ - [.buffer] - eficall [file_handle], EFI_FILE_PROTOCOL.Close, [file_handle] - mov rax, [.size] -.done: - push rax - call clearbuf - mov rdi, msg - call num2dec - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_file_size - pop rbx - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg - pop rbx - pop rax - ret 8*5 - -skip_whitespace: -.next_char: - cmp byte[rsi], 0 - jz .done - cmp byte[rsi], 0x20 ; ' ' - jz .whitespace - cmp byte[rsi], 9 ; '\t' - jz .whitespace - jmp .done -.whitespace: - inc rsi - jmp .next_char -.done: - ret - -skip_until_newline: -.next_char: - cmp byte[rsi], 0 - jz .done - cmp byte[rsi], 0xd ; '\r' - jz .done - cmp byte[rsi], 0xa ; '\n' - jz .done - inc rsi - jmp .next_char -.done: - ret - -skip_newline: -.next_char: - cmp byte[rsi], 0xd ; '\r' - jz .newline - cmp byte[rsi], 0xa ; '\n' - jz .newline - jmp .done -.newline: - inc rsi - jmp .next_char -.done: - ret - -skip_line: - call skip_until_newline - call skip_newline - ret - -dec2bin: - mov edx, 0 -.next_char: - movzx eax, byte[rsi] - test eax, eax - jz .done - sub eax, '0' - jb .done - cmp eax, 9 - ja .done - inc rsi - imul edx, 10 - add edx, eax - jmp .next_char -.done: - mov eax, edx - ret - -parse_option: - mov rbx, config_options-3*8 -.try_next_option: - add rbx, 3*8 - mov rdi, rsi - mov rdx, [rbx] ; option name - test rdx, rdx - jz .done -.next_char: - cmp byte[rdx], 0 - jnz @f - cmp byte[rdi], '=' - jz .opt_name_ok -@@: - cmp byte[rdi], 0 - jz .done - movzx eax, byte[rdi] - cmp [rdx], al - jnz .try_next_option - inc rdi - inc rdx - jmp .next_char -.opt_name_ok: - inc rdi - mov rsi, rdi - call qword[rbx+8] -.done: - ret - -parse_line: -.next_line: - cmp byte[rsi], 0 - jz .done - cmp byte[rsi], 0xd ; '\r' - jz .skip - cmp byte[rsi], 0xa ; '\n' - jz .skip - cmp byte[rsi], '#' - jz .skip - call parse_option - call skip_line - jmp .next_line -.skip: - call skip_line - jmp .next_line -.done: - ret - -cfg_opt_func_resolution: - call dec2bin - xor edx, edx - mov [rdx+BOOT_LO.x_res], ax - cmp byte[rsi], 'x' - jz @f - cmp byte[rsi], '*' - jz @f - jmp .done -@@: - inc rsi - call dec2bin - xor edx, edx - mov [rdx+BOOT_LO.y_res], ax - mov [cfg_opt_used_resolution], 1 -.done: - ret - -cfg_opt_func_acpi: - call dec2bin - mov [cfg_opt_used_acpi], 1 - mov [cfg_opt_value_acpi], al - ret - -cfg_opt_func_debug_print: - call dec2bin - mov [cfg_opt_used_debug_print], 1 - mov [cfg_opt_value_debug_print], al - ret - -cfg_opt_func_launcher_start: - call dec2bin - mov [cfg_opt_used_launcher_start], 1 - mov [cfg_opt_value_launcher_start], al - ret - -cfg_opt_func_mtrr: - call dec2bin - mov [cfg_opt_used_mtrr], 1 - mov [cfg_opt_value_mtrr], al - ret - -cfg_opt_func_ask_params: - call dec2bin - mov [cfg_opt_used_ask_params], 1 - mov [cfg_opt_value_ask_params], al - ret - -cfg_opt_func_imgfrom: - call dec2bin - mov [cfg_opt_used_imgfrom], 1 - mov [cfg_opt_value_imgfrom], al - ret - -cfg_opt_func_syspath: - mov rdi, cfg_opt_value_syspath -.next_char: - movzx eax, byte[rsi] - cmp al, 0xd ; \r - jz .done - cmp al, 0xa ; \n - jz .done - inc rsi - stosb - jmp .next_char -.done: - mov byte[rdi], 0 - ret - -parse_config: -virtual at rsp+8 - .buffer dq ? -end virtual -; mov rsi, [.buffer] - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_parsing_config - pop rbx - mov rsi, KERNEL_BASE -.next_line: - call parse_line - cmp byte[rsi], 0 - jnz .next_line - ret 1*8 - -read_options_from_config: - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices] - eficall rbx, EFI_BOOT_SERVICES.HandleProtocol, [efi_handle], lipuuid, \ - lip_interface - test eax, eax - jz @f - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_error_efi_lip_handle - pop rbx - jmp $ -@@: - mov rax, [lip_interface] - - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices] - eficall rbx, EFI_BOOT_SERVICES.HandleProtocol, \ - [rax+EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle], sfspguid, \ - sfsp_interface - test eax, eax - jz @f - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_error_lip_dev_sfsp - pop rbx - jmp $ -@@: - eficall [sfsp_interface], EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume, \ - [sfsp_interface], esp_root - test eax, eax - jz @f - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_error_sfsp_openvolume - pop rbx - jmp $ -@@: - push 0 ; not fatal, i.e. it's ok to not find this file - push FILE_BUFFER_SIZE - push KERNEL_BASE -; push file_name - mov rax, file_name - push rax - push [esp_root] - call load_file - - test eax, eax - jz @f - push KERNEL_BASE - call parse_config -@@: - -.error: - ret - -print_vmode: - push rax rbx rcx rdx rsi rdi - mov rbx, rcx - call clearbuf - mov eax, [rbx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution] - mov rdi, msg - call num2dec - mov eax, [rbx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution] - mov rdi, msg+8*2 - call num2dec - - mov eax, [rbx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat] - mov rdi, msg+16*2 - call num2dec - - mov eax, [rbx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine] - mov rdi, msg+24*2 - call num2dec - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg - pop rdi rsi rdx rcx rbx rax - ret - -find_vmode_index_by_resolution: - mov [cfg_opt_used_resolution], 1 - mov [cfg_opt_value_vmode], 0 -.next_mode: - movzx eax, [cfg_opt_value_vmode] - eficall [gop_interface], EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode, \ - [gop_interface], rax, gop_info_size, gop_info - cmp rax, EFI_SUCCESS - jnz .error - mov rcx, [gop_info] - call print_vmode - ; PixelBlueGreenRedReserved8BitPerColor - cmp [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat], 1 - jnz .skip_mode - xor edx, edx - mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution] - cmp ax, [rdx+BOOT_LO.x_res] - jnz .skip_mode - mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution] - cmp ax, [rdx+BOOT_LO.y_res] - jnz .skip_mode - jmp .done -.skip_mode: - inc [cfg_opt_value_vmode] - movzx eax, [cfg_opt_value_vmode] - mov rcx, [gop_interface] - mov rdx, [rcx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode] - cmp eax, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode] - jnz .next_mode - mov [cfg_opt_used_resolution], 0 - mov [cfg_opt_value_ask_params], 1 - - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_error_no_such_vmode - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_error - jmp $ -.error: -.done: - ret - -ask_for_params: - ret - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices] - eficall rbx, EFI_BOOT_SERVICES.HandleProtocol, [rax], gopuuid, \ - msg_ask_for_params - jmp $ - - xor ebx, ebx -.next_mode: - call clearbuf - mov eax, ebx - lea rdi, [msg] - call num2dec - - push rbx - eficall [gop_interface], EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode, \ - [gop_interface], rbx, gop_info_size, gop_info - cmp rax, EFI_SUCCESS - jnz .error - mov rcx, [gop_info] - ; PixelBlueGreenRedReserved8BitPerColor - cmp [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat], 1 - jnz .skip - mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution] - lea rdi, [msg+4*2] - call num2dec - mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution] - lea rdi, [msg+9*2] - call num2dec -; mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine] -; lea rdi, [msg+14*2] -; call num2dec -.skip: - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg - cmp rax, EFI_SUCCESS - jnz .error - - pop rbx - inc rbx - mov rcx, [gop_interface] - mov rdx, [rcx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode] - cmp ebx, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode] - jnz .next_mode - - - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConIn] - eficall rbx, SIMPLE_INPUT_INTERFACE.Reset, rbx, 1 - cmp rax, EFI_SUCCESS - jnz .error - xor ecx, ecx - @@: - push rcx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConIn] - eficall rbx, SIMPLE_INPUT_INTERFACE.ReadKeyStroke, rbx, msg - pop rcx - mov rdx, EFI_DEVICE_ERROR - cmp rax, rdx - jz .error - mov rdx, EFI_NOT_READY - cmp rax, rdx - jz @b -; cmp rax, EFI_SUCCESS - movzx eax, word[msg+2] -;jmp .key_done - cmp al, 0x0D - jz .key_done - imul ecx, 10 - sub eax, '0' - add ecx, eax - jmp @b -.key_done: - mov [cfg_opt_value_vmode], cl -.error: -.done: - ret - -main: - mov [efi_handle], rcx - mov [efi_table], rdx - - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset, rbx, 1 - test eax, eax - jz @f - jmp $ ; what can I do here? -@@: - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_u4k_loaded - - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_read_options - call read_options_from_config - - ; read kernel file - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_load_kernel - push 1 ; fatal - push MAX_FILE_SIZE - push KERNEL_BASE -; push kernel_name - mov rax, kernel_name - push rax - push [esp_root] - call load_file - - ; read ramdisk image - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_load_ramdisk - push 1 ; fatal - push MAX_FILE_SIZE - push RAMDISK_BASE -; push ramdisk_name - mov rax, ramdisk_name - push rax - push [esp_root] - call load_file - - ; alloc buffer for devices.dat - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_alloc_devicesdat - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices] - eficall rbx, EFI_BOOT_SERVICES.AllocatePages, \ - EFI_ALLOCATE_MAX_ADDRESS, EFI_RESERVED_MEMORY_TYPE, 1, \ - devicesdat_data - cmp eax, EFI_SUCCESS - jnz .error - - ; read devices.dat - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_load_devicesdat - - push 0 ; not fatal - push [devicesdat_size] - push [devicesdat_data] -; push devicesdat_name - mov rax, devicesdat_name - push rax - push [esp_root] - call load_file - mov [devicesdat_size], rax - - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_locate_gop_handlers - - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices] - eficall rbx, EFI_BOOT_SERVICES.LocateHandle, \ - EFI_LOCATE_SEARCH_TYPE.ByProtocol, gopuuid, 0, \ - gop_buffer_size, gop_buffer - mov [status], rax - - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_gop_buffer_size - call clearbuf - mov rax, [gop_buffer_size] - mov rdi, msg - call num2hex - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg - - mov rax, [status] - test eax, eax - jz @f - call clearbuf - mov rdi, msg - call num2hex - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_error - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg - jmp $ -@@: - - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_look_for_gop_handler - - mov rbx, gop_buffer -.next_gop_handle: - mov rax, rbx - mov rcx, gop_buffer - sub rax, rcx - cmp rax, [gop_buffer_size] - jb @f - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_error_out_of_handlers - pop rbx - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg_error - pop rbx - jmp $ -@@: - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_query_handler - pop rbx - - mov rax, rbx - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices] - eficall rbx, EFI_BOOT_SERVICES.HandleProtocol, [rax], gopuuid, \ - gop_interface - pop rbx -;mov rax, 0x8000_0000_0000_0003 - test eax, eax - jz @f - call clearbuf - mov rdi, msg - call num2hex - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg - pop rbx - - add rbx, 8 - jmp .next_gop_handle -@@: - - call find_rsdp - - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_acpi_tables_done - - cmp [cfg_opt_used_resolution], 0 - jz .not_used_resolution - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_opt_resolution - call clearbuf - xor edx, edx - movzx eax, [rdx+BOOT_LO.x_res] - mov rdi, msg - call num2dec - xor edx, edx - movzx eax, [rdx+BOOT_LO.y_res] - mov rdi, msg+8*2 - call num2dec - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg - call find_vmode_index_by_resolution -.not_used_resolution: - cmp [cfg_opt_used_debug_print], 0 - jz .not_used_debug_print - movzx eax, [cfg_opt_value_debug_print] - xor edx, edx - mov [rdx+BOOT_LO.debug_print], al -.not_used_debug_print: - - cmp [cfg_opt_value_ask_params], 0 - jz @f - call ask_for_params -@@: - - movzx ecx, [cfg_opt_value_vmode] - eficall [gop_interface], EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode, \ - [gop_interface], rcx - test eax, eax - jz @f - call clearbuf - mov rdi, msg - call num2hex - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_error - jmp $ -@@: - - mov rcx, [gop_interface] - mov rdx, [rcx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode] - mov rdi, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.FrameBufferBase] - mov [fb_base], rdi - - mov ebx, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.Mode] - eficall [gop_interface], EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode, \ - [gop_interface], rbx, gop_info_size, gop_info - test eax, eax - jz @f - jmp .error -@@: - mov rcx, [gop_info] - mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution] - xor rdx, rdx - mov [rdx+BOOT_LO.x_res], ax - mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution] - mov [rdx+BOOT_LO.y_res], ax - mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine] - shl eax, 2 - mov [rdx+BOOT_LO.pitch], ax - - mov byte[rdx+BOOT_LO.pci_data+0], 1 ; PCI access mechanism - mov byte[rdx+BOOT_LO.pci_data+1], 8 ; last bus, don't know how to count them - mov byte[rdx+BOOT_LO.pci_data+2], 0x10 ; PCI version - mov byte[rdx+BOOT_LO.pci_data+3], 0x02 - mov dword[rdx+BOOT_LO.pci_data+4], 0xe3 - - ; kernel -; eficall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \ -; 450000/0x1000, EFI_ALLOCATE_ADDRESS - - ; ramdisk -; eficall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \ -; 2880*512/0x1000, EFI_ALLOCATE_ADDRESS - - call calc_memmap -; call dump_memmap - - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices] - eficall rbx, EFI_BOOT_SERVICES.ExitBootServices, [efi_handle], \ - [memory_map_key] - call halt_on_error - - cli - - xor edx, edx - xor esi, esi - mov [esi+BOOT_LO.bpp], 32 - mov [esi+BOOT_LO.vesa_mode], dx - mov [esi+BOOT_LO.bank_switch], edx - mov rdi, [fb_base] - mov [esi+BOOT_LO.lfb], edi - - movzx eax, [cfg_opt_value_mtrr] - mov [esi+BOOT_LO.mtrr], al - - movzx eax, [cfg_opt_value_launcher_start] - mov [esi+BOOT_LO.launcher_start], al - - movzx eax, [cfg_opt_value_debug_print] - mov [esi+BOOT_LO.debug_print], al - - mov [esi+BOOT_LO.dma], dl -; mov qword[esi+BOOT_LO.pci_data], 0 - mov [esi+BOOT_LO.apm_entry], edx - mov [esi+BOOT_LO.apm_version], dx - mov [esi+BOOT_LO.apm_flags], dx - mov [esi+BOOT_LO.apm_code_32], dx - mov [esi+BOOT_LO.apm_code_16], dx - mov [esi+BOOT_LO.apm_data_16], dx - mov [esi+BOOT_LO.bios_hd_cnt], dl - - movzx eax, [cfg_opt_value_imgfrom] - mov [esi+BOOT_LO.rd_load_from], al - - mov eax, dword[devicesdat_size] - mov [rdx+BOOT_LO.devicesdat_size], eax - mov eax, dword[devicesdat_data] - mov [rdx+BOOT_LO.devicesdat_data], eax - - mov rsi, cfg_opt_value_syspath - mov rdi, BOOT_LO.syspath - mov ecx, 0x17 - rep movsb - - ; kernel trampoline - mov rsi, kernel_trampoline - mov rdi, KERNEL_TRAMPOLINE - mov ecx, kernel_trampoline.size - rep movsb - - mov rax, GDTR - lgdt [cs:rax] - - mov ax, DATA_32_SELECTOR - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - push CODE_32_SELECTOR - mov rax, KERNEL_TRAMPOLINE - push rax - retf - -.error: - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_error - jmp $ - - -halt_on_error: - test eax, eax - jz @f - call clearbuf - mov rdi, msg - call num2hex - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_error - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg - jmp $ -@@: - ret - -find_rsdp: - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_look_for_rsdp - pop rbx - - mov rbx, [efi_table] - mov rdi, [rbx+EFI_SYSTEM_TABLE.ConfigurationTable] - mov rcx, [rbx+EFI_SYSTEM_TABLE.NumberOfTableEntries] - mov rax, 0x11d3e4f18868e871 - mov rdx, 0x81883cc7800022bc -.next_table: - dec ecx - js .all_tables_done - cmp [rdi+0], rax - jnz .not_acpi20 - cmp [rdi+8], rdx - jnz .not_acpi20 - mov rax, [rdi+16] - mov rdx, BOOT_LO.acpi_rsdp - mov [rdx], eax - jmp .all_tables_done -.not_acpi20: - add rdi, 24 - jmp .next_table -.all_tables_done: - ret - -calc_memmap: - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices] - eficall rbx, EFI_BOOT_SERVICES.AllocatePages, EFI_ALLOCATE_ANY_PAGES, \ - EFI_RESERVED_MEMORY_TYPE, MEMORY_MAP_SIZE/0x1000, memory_map - call halt_on_error - - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices] - eficall rbx, EFI_BOOT_SERVICES.GetMemoryMap, memory_map_size, \ - [memory_map], memory_map_key, descriptor_size, descriptor_ver - call halt_on_error - - mov rdi, BOOT_LO.memmap_blocks - mov dword[rdi-4], 0 ; memmap_block_cnt - mov rsi, [memory_map] - mov rbx, rsi - add rbx, [memory_map_size] -.next_descr: - call add_uefi_memmap - add rsi, [descriptor_size] - cmp rsi, rbx - jb .next_descr - ret - -dump_memmap: - xor eax, eax - mov rsi, BOOT_LO.memmap_blocks - mov ebx, [rax+BOOT_LO.memmap_block_cnt] - - call clearbuf - mov eax, ebx - mov rdi, msg - call num2dec - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \ - msg_memmap - pop rbx - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg - pop rbx - call clearbuf -.next_mapping: - dec ebx - js .done - mov rax, rsi - mov rcx, BOOT_LO.memmap_blocks - sub rax, rcx - mov ecx, sizeof.e820entry - xor edx, edx - div ecx - mov rdi, msg - call num2dec - mov rax, [rsi+e820entry.addr] - mov rdi, msg+4*2 - call num2hex - mov rax, [rsi+e820entry.size] - mov rdi, msg+24*2 - call num2hex - push rbx - mov rbx, [efi_table] - mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut] - eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg - pop rbx - add rsi, sizeof.e820entry - jmp .next_mapping -.done: - ret - - -; linux/arch/x86/platform/efi/efi.c -; do_add_efi_memmap -add_uefi_memmap: - xor eax, eax - cmp [rax+BOOT_LO.memmap_block_cnt], MAX_MEMMAP_BLOCKS - jz .done - - mov rax, [rsi+EFI_MEMORY_DESCRIPTOR.PhysicalStart] - mov [rdi+e820entry.addr], rax - - mov rax, [rsi+EFI_MEMORY_DESCRIPTOR.NumberOfPages] - shl rax, 12 - mov [rdi+e820entry.size], rax - - mov ecx, [rsi+EFI_MEMORY_DESCRIPTOR.Type] - cmp ecx, EFI_LOADER_CODE - jz .mem_ram_if_wb - cmp ecx, EFI_LOADER_DATA - jz .mem_ram_if_wb - cmp ecx, EFI_BOOT_SERVICES_CODE - jz .mem_ram_if_wb - cmp ecx, EFI_BOOT_SERVICES_DATA - jz .mem_ram_if_wb - cmp ecx, EFI_CONVENTIONAL_MEMORY - jz .mem_ram_if_wb - cmp ecx, EFI_ACPI_RECLAIM_MEMORY - mov eax, E820_ACPI - jz .type_done - cmp ecx, EFI_ACPI_MEMORY_NVS - mov eax, E820_NVS - jz .type_done - cmp ecx, EFI_UNUSABLE_MEMORY - mov eax, E820_UNUSABLE - jz .type_done - cmp ecx, EFI_PERSISTENT_MEMORY - mov eax, E820_PMEM - jz .type_done - jmp .reserved -.mem_ram_if_wb: - test [rsi+EFI_MEMORY_DESCRIPTOR.Attribute], dword EFI_MEMORY_WB - mov eax, E820_RAM - jnz .type_done -.reserved: - mov eax, E820_RESERVED -.type_done: - mov [rdi+e820entry.type], eax - cmp eax, E820_RAM - jnz @f - xor eax, eax - inc [rax+BOOT_LO.memmap_block_cnt] - add rdi, sizeof.e820entry -@@: -.done: - ret - - -num2dec: - push rax rbx rcx rdx rsi rdi - - xor ecx, ecx - mov ebx, 10 -.next_digit: - xor edx, edx - div ebx - push rdx - inc ecx - test eax, eax - jnz .next_digit - -.next_char: - pop rax - add eax, '0' - stosw - loop .next_char - - pop rdi rsi rdx rcx rbx rax - ret - - -num2hex: - push rax rbx rcx rdx rsi rdi - - xchg rdx, rax - mov ecx, 16 -.next_tetra: - rol rdx, 4 - movzx eax, dl - and eax, 0x0f - movzx eax, byte[hex+eax] - stosw - loop .next_tetra - - pop rdi rsi rdx rcx rbx rax - ret - -hex db '0123456789ABCDEF' - -clearbuf: - push rax rbx rcx rdx rsi rdi - mov eax, 0x0020 - mov ecx, 79 - mov rdi, msg - rep stosw - pop rdi rsi rdx rcx rbx rax - ret - -use32 -kernel_trampoline: -org KERNEL_TRAMPOLINE - mov eax, cr0 - and eax, not CR0_PG - mov cr0, eax - - mov ecx, MSR_AMD_EFER - rdmsr - btr eax, 8 ; LME - wrmsr - - mov eax, cr4 - and eax, not CR4_PAE - mov cr4, eax - - push KERNEL_BASE - retn - -align 16 -GDTR: - dw 4*8-1 - dq GDT -align 16 -GDT: - dw 0, 0, 0, 0 - dw 0FFFFh,0,9A00h,0CFh ; 32-bit code - dw 0FFFFh,0,9200h,0CFh ; flat data - dw 0FFFFh,0,9A00h,0AFh ; 64-bit code -assert $ < BOOT_LO -kernel_trampoline.size = $ - KERNEL_TRAMPOLINE - -section '.rodata' data readable -gopuuid db EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID -lipuuid db EFI_LOADED_IMAGE_PROTOCOL_GUID -sfspguid db EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID - -file_name du '\EFI\KOLIBRIOS\KOLIBRI.INI',0 -kernel_name du '\EFI\KOLIBRIOS\KOLIBRI.KRN',0 -ramdisk_name du '\EFI\KOLIBRIOS\KOLIBRI.IMG',0 -devicesdat_name du '\EFI\KOLIBRIOS\DEVICES.DAT',0 - -config_options dq cfg_opt_name_resolution, cfg_opt_func_resolution, \ - cfg_opt_cmnt_resolution, \ - cfg_opt_name_acpi, cfg_opt_func_acpi, cfg_opt_cmnt_acpi, \ - cfg_opt_name_debug_print, cfg_opt_func_debug_print, \ - cfg_opt_cmnt_debug_print, \ - cfg_opt_name_launcher_start, cfg_opt_func_launcher_start, \ - cfg_opt_cmnt_launcher_start, \ - cfg_opt_name_mtrr, cfg_opt_func_mtrr, cfg_opt_cmnt_mtrr, \ - cfg_opt_name_ask_params, cfg_opt_func_ask_params, \ - cfg_opt_cmnt_ask_params, \ - cfg_opt_name_imgfrom, cfg_opt_func_imgfrom, \ - cfg_opt_cmnt_imgfrom, \ - cfg_opt_name_syspath, cfg_opt_func_syspath, \ - cfg_opt_cmnt_syspath, \ - 0 - -cfg_opt_name_resolution db "resolution",0 -cfg_opt_name_acpi db "acpi",0 -cfg_opt_name_debug_print db "debug_print",0 -cfg_opt_name_launcher_start db "launcher_start",0 -cfg_opt_name_mtrr db "mtrr",0 -cfg_opt_name_ask_params db "ask_params",0 -cfg_opt_name_imgfrom db "imgfrom",0 -cfg_opt_name_syspath db "syspath",0 - -cfg_opt_cmnt_resolution db "# Graphic mode",0 -cfg_opt_cmnt_acpi db "# ACPI settings",0xa, \ - "# 0: don't use",0xa, \ - "# 1: parse ACPI tables",0xa, \ - "# 2: + call _PIC method",0xa, \ - "# 3: + get APIC interrupts",0xa,0 -cfg_opt_cmnt_debug_print db "# Duplicate debug output to the screen",0 -cfg_opt_cmnt_launcher_start db "# Start LAUNCHER app after kernel is loaded",0 -cfg_opt_cmnt_mtrr db "# Configure MTRR's",0 -cfg_opt_cmnt_ask_params db "# Interrupt booting to ask the user for boot", \ - " params",0 -cfg_opt_cmnt_imgfrom db "# Where to load ramdisk image from",0 -cfg_opt_cmnt_syspath db "# Path to /sys directory",0 - -msg_u4k_loaded du "uefi64kos loaded",13,10,0 -msg_read_options du "Read options from config file",13,10,0 -msg_file_size du "File size:",13,10,0 -msg_parsing_config du "Parsing config file",13,10,0 -msg_load_kernel du "Load kernel",13,10,0 -msg_load_ramdisk du "Load ramdisk",13,10,0 -msg_load_devicesdat du "Load DEVICES.DAT",13,10,0 -msg_alloc_devicesdat du "Allocate memory for DEVICES.DAT",13,10,0 -msg_locate_gop_handlers du "Locate GOP handlers",13,10,0 -msg_look_for_gop_handler du "Look for GOP handler",13,10,0 -msg_query_handler du "Query handler",13,10,0 -msg_query_vmode du "Query vmode",13,10,0 -msg_vmode_found du "Video mode found",13,10,0 -msg_look_for_rsdp du "Look for RSDP",13,10,0 -msg_rsdp_found du "RSDP found",13,10,0 -msg_acpi_tables_done du "ACPI tables done",13,10,0 -msg_ask_for_params du "Ask for params",13,10,0 -msg_set_graphic_mode du "Set graphic mode",13,10,0 -msg_success du "Success!",13,10,0 -msg_gop_buffer_size du "GOP buffer size",13,10,0 -msg_opt_resolution du "Option resolution: ",0 -msg_memmap du "Memmap",13,10,0 -msg_error du "Error!",13,10,0 -msg_error_efi_lip_handle du "efi_handle can't handle LIP",13,10,0 -msg_error_lip_dev_sfsp du "LIP device handle can't handle SFSP",13,10,0 -msg_error_sfsp_openvolume du "SFSP OpenVolume failed",13,10,0 -msg_error_no_such_vmode du "No such vmode",13,10,0 -msg_error_out_of_handlers du "Out of handlers",13,10,0 -msg_error_open_file du "Error: can't open file ",0 -msg_error_exit_boot_services du "Error: Exit boot services",13,10,0 -msg du 79 dup " ",13,10,0 - - -section '.data' data readable writeable -efi_handle dq 0 -efi_table dq 0 -uefi_rsptmp dq 0 - -fb_base dq 0 - -gop_buffer_size dq GOP_BUFFER_SIZE -gop_handle dq 0 -gop_interface dq 0 -gop_info_size dq 0 -gop_info dq 0 - -lip_buffer_size dq LIP_BUFFER_SIZE -lip_handle dq 0 -lip_interface dq 0 - -sfsp_interface dq 0 - -esp_root dq ? -file_handle dq ? -file_buffer_size dq FILE_BUFFER_SIZE-1 ; leave the last byte for \0 - -cfg_opt_used_resolution db 0 -cfg_opt_used_acpi db 0 -cfg_opt_used_debug_print db 0 -cfg_opt_used_launcher_start db 0 -cfg_opt_used_mtrr db 0 -cfg_opt_used_ask_params db 0 -cfg_opt_used_imgfrom db 0 -cfg_opt_used_syspath db 0 - -cfg_opt_value_vmode db 0 -cfg_opt_value_acpi db 0 -cfg_opt_value_debug_print db 0 -cfg_opt_value_launcher_start db 1 -cfg_opt_value_mtrr db 0 -cfg_opt_value_ask_params db 0 -cfg_opt_value_imgfrom db RD_LOAD_FROM_MEMORY -cfg_opt_value_syspath db "/RD/1",0 - rb 20 - -memory_map_key dq 0 -descriptor_size dq 0 -descriptor_ver dq 0 -memory_map_size dq MEMORY_MAP_SIZE - -efi_fs_info_id db EFI_FILE_SYSTEM_INFO_ID -efi_fs_info_size dq sizeof.EFI_FILE_SYSTEM_INFO -efi_fs_info EFI_FILE_SYSTEM_INFO - -memory_map dq ? -gop_buffer rq GOP_BUFFER_SIZE/8 -devicesdat_data dq 0xffffffff -devicesdat_size dq 0x1000 -status dq ? - -section '.reloc' fixups data discardable diff --git a/kernel/branches/Kolibri-F/build.bat b/kernel/branches/Kolibri-F/build.bat deleted file mode 100644 index 1e8981838..000000000 --- a/kernel/branches/Kolibri-F/build.bat +++ /dev/null @@ -1,39 +0,0 @@ -@echo off -cls - -call :Target_kernel - -if ERRORLEVEL 0 goto Exit_OK - -echo There was an error executing script. -echo For any help, please send a report. -pause -goto :eof - -:Target_kernel - rem valid languages: en ru ge et sp - set lang=en - - echo *** building kernel with language '%lang%' ... - - echo lang fix %lang% > lang.inc - fasm -m 65536 bootbios.asm bootbios.bin - fasm -m 65536 kernel.asm kernel.mnt - fasm -m 65536 kernel.asm kernel.bin -dUEFI=1 - if not %errorlevel%==0 goto :Error_FasmFailed - erase lang.inc -goto :eof - - -:Error_FasmFailed -echo error: fasm execution failed -erase lang.inc >nul 2>&1 -echo. -pause -exit 1 - -:Exit_OK -echo. -echo all operations have been done -pause -exit 0 diff --git a/kernel/branches/Kolibri-F/build.sh b/kernel/branches/Kolibri-F/build.sh deleted file mode 100755 index 2cf03e663..000000000 --- a/kernel/branches/Kolibri-F/build.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -# Compile the KolibriOS kernel on Linux -# 2017, The KolibriOS team - -KERPACK=./tools/kerpack -KOLIBRI_IMG=kolibri.img - -echo 'lang fix en' > lang.inc -fasm -m 65536 bootbios.asm bootbios.bin -fasm -m 65536 -s kernel.fas kernel.asm kernel.mnt -$KERPACK kernel.mnt kernel.mnt -mcopy -D o -i $KOLIBRI_IMG kernel.mnt ::kernel.mnt \ No newline at end of file diff --git a/kernel/branches/Kolibri-F/bus/pci/PCIe.inc b/kernel/branches/Kolibri-F/bus/pci/PCIe.inc deleted file mode 100644 index fe984eb60..000000000 --- a/kernel/branches/Kolibri-F/bus/pci/PCIe.inc +++ /dev/null @@ -1,119 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;; ;; -;; PCIe.INC ;; -;; ;; -;; Extended PCI express services ;; -;; ;; -;; art_zh ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -;*************************************************************************** -; Function -; pci_ext_config: -; -; Description -; PCIe extended (memory-mapped) config space detection -; -; WARNINGs: -; 1) Very Experimental! -; 2) direct HT-detection (no ACPI or BIOS service used) -; 3) Only AMD/HT processors currently supported -; -;*************************************************************************** - -PCIe_CONFIG_SPACE = 0xF0000000 ; to be moved to const.inc -mmio_pcie_cfg_addr dd 0x0 ; intel pcie space may be defined here -mmio_pcie_cfg_lim dd 0x0 ; upper pcie space address - - -align 4 - -pci_ext_config: - - mov ebx, [mmio_pcie_cfg_addr] - or ebx, ebx - jz @f - or ebx, 0x7FFFFFFF ; required by PCI-SIG standards - jnz .pcie_failed - add ebx, 0x0FFFFC - cmp ebx, [mmio_pcie_cfg_lim]; is the space limit correct? - ja .pcie_failed - jmp .pcie_cfg_mapped -@@: - mov ebx, [cpu_vendor] - cmp ebx, dword [AMD_str] - jne .pcie_failed - mov bx, 0xC184 ; dev = 24, fn = 01, reg = 84h - -.check_HT_mmio: - mov cx, bx - mov ax, 0x0002 ; bus = 0, 1dword to read - call pci_read_reg - mov bx, cx - sub bl, 4 - and al, 0x80 ; check the NP bit - jz .no_pcie_cfg - shl eax, 8 ; bus:[27..20], dev:[19:15] - or eax, 0x00007FFC ; fun:[14..12], reg:[11:2] - mov [mmio_pcie_cfg_lim], eax - mov cl, bl - mov ax, 0x0002 ; bus = 0, 1dword to read - call pci_read_reg - mov bx, cx - test al, 0x03 ; MMIO Base RW enabled? - jz .no_pcie_cfg - test al, 0x0C ; MMIO Base locked? - jnz .no_pcie_cfg - xor al, al - shl eax, 8 - test eax, 0x000F0000 ; MMIO Base must be bus0-aligned - jnz .no_pcie_cfg - mov [mmio_pcie_cfg_addr], eax - add eax, 0x000FFFFC - sub eax, [mmio_pcie_cfg_lim]; MMIO must cover at least one bus - ja .no_pcie_cfg - -; -- it looks like a true PCIe config space; - mov eax, [mmio_pcie_cfg_addr] ; physical address - or eax, (PG_SHARED + PG_LARGE + PG_USER) - mov ebx, PCIe_CONFIG_SPACE ; linear address - mov ecx, ebx - shr ebx, 20 - add ebx, sys_pgdir ; PgDir entry @ -@@: - mov dword[ebx], eax ; map 4 buses - invlpg [ecx] - cmp bl, 4 - jz .pcie_cfg_mapped ; fix it later - add bl, 4 ; next PgDir entry - add eax, 0x400000 ; eax += 4M - add ecx, 0x400000 - jmp @b - -.pcie_cfg_mapped: - -; -- glad to have the extended PCIe config field found -; mov esi, boot_pcie_ok -; call boot_log - ret ; <<<<<<<<<<< OK >>>>>>>>>>> - -.no_pcie_cfg: - - xor eax, eax - mov [mmio_pcie_cfg_addr], eax - mov [mmio_pcie_cfg_lim], eax - add bl, 12 - cmp bl, 0xC0 ; MMIO regs lay below this offset - jb .check_HT_mmio -.pcie_failed: -; mov esi, boot_pcie_fail -; call boot_log - ret ; <<<<<<<<< FAILURE >>>>>>>>> - diff --git a/kernel/branches/Kolibri-F/bus/pci/pci16.inc b/kernel/branches/Kolibri-F/bus/pci/pci16.inc deleted file mode 100644 index 9040d5f88..000000000 --- a/kernel/branches/Kolibri-F/bus/pci/pci16.inc +++ /dev/null @@ -1,51 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;; PCI16.INC ;; -;; ;; -;; 16 bit PCI driver code ;; -;; ;; -;; Version 0.2 December 21st, 2002 ;; -;; ;; -;; Author: Victor Prodan, victorprodan@yahoo.com ;; -;; ;; -;; See file COPYING for details ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -init_pci_16: - - pushad - - xor ax, ax - mov es, ax - mov byte [es:BOOT_LO.pci_data], 1;default mechanism:1 - mov ax, 0xb101 - int 0x1a - or ah, ah - jnz pci16skip - - mov [es:BOOT_LO.pci_data+1], cl;last PCI bus in system - mov word[es:BOOT_LO.pci_data+2], bx - mov dword[es:BOOT_LO.pci_data+4], edi - -; we have a PCI BIOS, so check which configuration mechanism(s) -; it supports -; AL = PCI hardware characteristics (bit0 => mechanism1, bit1 => mechanism2) - test al, 1 - jnz pci16skip - test al, 2 - jz pci16skip - mov byte [es:BOOT_LO.pci_data], 2; if (al&3)==2 => mechanism 2 - -pci16skip: - - mov ax, 0x1000 - mov es, ax - - popad diff --git a/kernel/branches/Kolibri-F/bus/pci/pci32.inc b/kernel/branches/Kolibri-F/bus/pci/pci32.inc deleted file mode 100644 index a20929ebb..000000000 --- a/kernel/branches/Kolibri-F/bus/pci/pci32.inc +++ /dev/null @@ -1,679 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;; ;; -;; PCI32.INC ;; -;; ;; -;; 32 bit PCI driver code ;; -;; ;; -;; Version 0.3 April 9, 2007 ;; -;; Version 0.2 December 21st, 2002 ;; -;; ;; -;; Author: Victor Prodan, victorprodan@yahoo.com ;; -;; Mihailov Ilia, ghost.nsk@gmail.com ;; -;; Credits: ;; -;; Ralf Brown ;; -;; Mike Hibbett, mikeh@oceanfree.net ;; -;; ;; -;; See file COPYING for details ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -;*************************************************************************** -; Function -; pci_api: -; -; Description -; entry point for system PCI calls -;*************************************************************************** -;mmio_pci_addr = 0x400 ; set actual PCI address here to activate user-MMIO - -iglobal -align 4 -f62call: - dd pci_fn_0 - dd pci_fn_1 - dd pci_fn_2 - dd pci_service_not_supported ;3 - dd pci_read_reg ;4 byte - dd pci_read_reg ;5 word - dd pci_read_reg ;6 dword - dd pci_service_not_supported ;7 - dd pci_write_reg ;8 byte - dd pci_write_reg ;9 word - dd pci_write_reg ;10 dword -if defined mmio_pci_addr - dd pci_mmio_init ;11 - dd pci_mmio_map ;12 - dd pci_mmio_unmap ;13 -end if - -endg - -align 4 - -syscall_pci_api: - -;cross - mov eax, ebx - mov ebx, ecx - mov ecx, edx - - cmp [pci_access_enabled], 1 - jne pci_service_not_supported - - movzx edx, al - -if defined mmio_pci_addr - cmp al, 13 - ja pci_service_not_supported -else - cmp al, 10 - ja pci_service_not_supported -end if - - call dword [f62call+edx*4] - mov dword [esp+32], eax - ret - - -align 4 -pci_api_drv: - - cmp [pci_access_enabled], 1 - jne .fail - - cmp eax, 2 - ja .fail - - jmp dword [f62call+eax*4] - -.fail: - or eax, -1 - ret - - -;; ============================================ - -pci_fn_0: -; PCI function 0: get pci version (AH.AL) - movzx eax, word [BOOT.pci_data+2] - ret - -pci_fn_1: -; PCI function 1: get last bus in AL - mov al, [BOOT.pci_data+1] - ret - -pci_fn_2: -; PCI function 2: get pci access mechanism - mov al, [BOOT.pci_data] - ret - -pci_service_not_supported: - or eax, -1 - mov dword [esp+32], eax - ret - -;*************************************************************************** -; Function -; pci_make_config_cmd -; -; Description -; creates a command dword for use with the PCI bus -; bus # in ah -; device+func in bh (dddddfff) -; register in bl -; -; command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 ) -;*************************************************************************** - -align 4 - -pci_make_config_cmd: - shl eax, 8 ; move bus to bits 16-23 - mov ax, bx ; combine all - and eax, 0xffffff - or eax, 0x80000000 - ret - -;*************************************************************************** -; Function -; pci_read_reg: -; -; Description -; read a register from the PCI config space into EAX/AX/AL -; IN: ah=bus,device+func=bh,register address=bl -; number of bytes to read (1,2,4) coded into AL, bits 0-1 -; (0 - byte, 1 - word, 2 - dword) -;*************************************************************************** - -align 4 - -pci_read_reg: - push ebx esi - cmp byte [BOOT.pci_data], 2;what mechanism will we use? - je pci_read_reg_2 - - ; mechanism 1 - mov esi, eax ; save register size into ESI - and esi, 3 - - call pci_make_config_cmd - mov ebx, eax - mov dx, 0xcf8 - ; set up addressing to config data - mov eax, ebx - and al, 0xfc; make address dword-aligned - out dx, eax - ; get requested DWORD of config data - mov dl, 0xfc - and bl, 3 - or dl, bl ; add to port address first 2 bits of register address - - or esi, esi - jz pci_read_byte1 - cmp esi, 1 - jz pci_read_word1 - cmp esi, 2 - jz pci_read_dword1 - jmp pci_fin_read1 - -pci_read_byte1: - in al, dx - jmp pci_fin_read1 -pci_read_word1: - in ax, dx - jmp pci_fin_read1 -pci_read_dword1: - in eax, dx -pci_fin_read1: - pop esi ebx - ret -pci_read_reg_2: - - test bh, 128 ;mech#2 only supports 16 devices per bus - jnz pci_read_reg_err - - mov esi, eax ; save register size into ESI - and esi, 3 - - mov dx, 0xcfa - - ; out 0xcfa,bus - mov al, ah - out dx, al - ; out 0xcf8,0x80 - mov dl, 0xf8 - mov al, 0x80 - out dx, al - ; compute addr - shr bh, 3; func is ignored in mechanism 2 - or bh, 0xc0 - mov dx, bx - - or esi, esi - jz pci_read_byte2 - cmp esi, 1 - jz pci_read_word2 - cmp esi, 2 - jz pci_read_dword2 - jmp pci_fin_read2 - -pci_read_byte2: - in al, dx - jmp pci_fin_read2 -pci_read_word2: - in ax, dx - jmp pci_fin_read2 -pci_read_dword2: - in eax, dx -pci_fin_read2: - - pop esi ebx - ret - -pci_read_reg_err: - xor eax, eax - dec eax - pop esi ebx - ret - - -;*************************************************************************** -; Function -; pci_write_reg: -; -; Description -; write a register from ECX/CX/CL into the PCI config space -; IN: ah=bus,device+func=bh,register address (dword aligned)=bl, -; value to write in ecx -; number of bytes to write (1,2,4) coded into AL, bits 0-1 -; (0 - byte, 1 - word, 2 - dword) -;*************************************************************************** - -align 4 - -pci_write_reg: - push esi ebx - cmp byte [BOOT.pci_data], 2;what mechanism will we use? - je pci_write_reg_2 - - ; mechanism 1 - mov esi, eax ; save register size into ESI - and esi, 3 - - call pci_make_config_cmd - mov ebx, eax - mov dx, 0xcf8 - ; set up addressing to config data - mov eax, ebx - and al, 0xfc; make address dword-aligned - out dx, eax - ; write DWORD of config data - mov dl, 0xfc - and bl, 3 - or dl, bl - mov eax, ecx - - or esi, esi - jz pci_write_byte1 - cmp esi, 1 - jz pci_write_word1 - cmp esi, 2 - jz pci_write_dword1 - jmp pci_fin_write1 - -pci_write_byte1: - out dx, al - jmp pci_fin_write1 -pci_write_word1: - out dx, ax - jmp pci_fin_write1 -pci_write_dword1: - out dx, eax -pci_fin_write1: - - xor eax, eax - pop ebx esi - - ret -pci_write_reg_2: - - test bh, 128 ;mech#2 only supports 16 devices per bus - jnz pci_write_reg_err - - - mov esi, eax ; save register size into ESI - and esi, 3 - - mov dx, 0xcfa - ; out 0xcfa,bus - mov al, ah - out dx, al - ; out 0xcf8,0x80 - mov dl, 0xf8 - mov al, 0x80 - out dx, al - ; compute addr - shr bh, 3; func is ignored in mechanism 2 - or bh, 0xc0 - mov dx, bx - ; write register - mov eax, ecx - - or esi, esi - jz pci_write_byte2 - cmp esi, 1 - jz pci_write_word2 - cmp esi, 2 - jz pci_write_dword2 - jmp pci_fin_write2 - -pci_write_byte2: - out dx, al - jmp pci_fin_write2 -pci_write_word2: - out dx, ax - jmp pci_fin_write2 -pci_write_dword2: - out dx, eax -pci_fin_write2: - - xor eax, eax - pop ebx esi - ret - -pci_write_reg_err: - xor eax, eax - dec eax - pop ebx esi - ret - -if defined mmio_pci_addr ; must be set above -;*************************************************************************** -; Function -; pci_mmio_init -; -; Description -; IN: bx = device's PCI bus address (bbbbbbbbdddddfff) -; Returns eax = user heap space available (bytes) -; Error codes -; eax = -1 : PCI user access blocked, -; eax = -2 : device not registered for uMMIO service -; eax = -3 : user heap initialization failure -;*************************************************************************** -pci_mmio_init: - cmp bx, mmio_pci_addr - jz @f - mov eax, -2 - ret -@@: - call init_heap ; (if not initialized yet) - or eax, eax - jz @f - ret -@@: - mov eax, -3 - ret - - -;*************************************************************************** -; Function -; pci_mmio_map -; -; Description -; maps a block of PCI memory to user-accessible linear address -; -; WARNING! This VERY EXPERIMENTAL service is for one chosen PCI device only! -; The target device address should be set in kernel var mmio_pci_addr -; -; IN: ah = BAR#; -; IN: ebx = block size (bytes); -; IN: ecx = offset in MMIO block (in 4K-pages, to avoid misaligned pages); -; -; Returns eax = MMIO block's linear address in the userspace (if no error) -; -; -; Error codes -; eax = -1 : user access to PCI blocked, -; eax = -2 : an invalid BAR register referred -; eax = -3 : no i/o space on that BAR -; eax = -4 : a port i/o BAR register referred -; eax = -5 : dynamic userspace allocation problem -;*************************************************************************** - -pci_mmio_map: - and edx, 0x0ffff - cmp ah, 6 - jc .bar_0_5 - jz .bar_rom - mov eax, -2 - ret -.bar_rom: - mov ah, 8 ; bar6 = Expansion ROM base address -.bar_0_5: - push ecx - add ebx, 4095 - and ebx, -4096 - push ebx - mov bl, ah ; bl = BAR# (0..5), however bl=8 for BAR6 - shl bl, 1 - shl bl, 1 - add bl, 0x10; now bl = BAR offset in PCI config. space - mov ax, mmio_pci_addr - mov bh, al ; bh = dddddfff - mov al, 2 ; al : DW to read - call pci_read_reg - or eax, eax - jnz @f - mov eax, -3 ; empty I/O space - jmp mmio_ret_fail -@@: - test eax, 1 - jz @f - mov eax, -4 ; damned ports (not MMIO space) - jmp mmio_ret_fail -@@: - pop ecx ; ecx = block size, bytes (expanded to whole page) - mov ebx, ecx; user_alloc destroys eax, ecx, edx, but saves ebx - and eax, 0xFFFFFFF0 - push eax ; store MMIO physical address + keep 2DWords in the stack - stdcall user_alloc, ecx - or eax, eax - jnz mmio_map_over - mov eax, -5 ; problem with page allocation - -mmio_ret_fail: - pop ecx - pop edx - ret - -mmio_map_over: - mov ecx, ebx; ecx = size (bytes, expanded to whole page) - shr ecx, 12 ; ecx = number of pages - mov ebx, eax; ebx = linear address - pop eax ; eax = MMIO start - pop edx ; edx = MMIO shift (pages) - shl edx, 12 ; edx = MMIO shift (bytes) - add eax, edx; eax = uMMIO physical address - or eax, PG_SHARED - or eax, PG_UW - or eax, PG_NOCACHE - mov edi, ebx - call commit_pages - mov eax, edi - ret - -;*************************************************************************** -; Function -; pci_mmio_unmap_page -; -; Description -; unmaps the linear space previously tied to a PCI memory block -; -; IN: ebx = linear address of space previously allocated by pci_mmio_map -; returns eax = 1 if successfully unmapped -; -; Error codes -; eax = -1 if no user PCI access allowed, -; eax = 0 if unmapping failed -;*************************************************************************** - -pci_mmio_unmap: - stdcall user_free, ebx - ret - -end if - -;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -uglobal -align 4 -; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1) -pci_emu_dat: - times 30*10 db 0 -endg -;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -align 4 -syscall_pcibios: - cmp [pci_access_enabled], 1 - jne .unsupported_func - cmp [pci_bios_entry], 0 - jz .emulate_bios - - push ds - mov ax, pci_data_sel - mov ds, ax - mov eax, ebp - mov ah, 0B1h - call pword [cs:pci_bios_entry] - pop ds - - jmp .return - ;-=-=-=-=-=-=-=-= -.emulate_bios: - cmp ebp, 1 ; PCI_FUNCTION_ID - jnz .not_PCI_BIOS_PRESENT - mov edx, 'PCI ' - mov al, [BOOT.pci_data] - mov bx, word[BOOT.pci_data + 2] - mov cl, [BOOT.pci_data + 1] - xor ah, ah - jmp .return_abcd - -.not_PCI_BIOS_PRESENT: - cmp ebp, 2 ; FIND_PCI_DEVICE - jne .not_FIND_PCI_DEVICE - mov ebx, pci_emu_dat -..nxt: - cmp [ebx], dx - jne ..no - cmp [ebx + 2], cx - jne ..no - dec si - jns ..no - mov bx, [ebx + 4] - xor ah, ah - jmp .return_ab -..no: - cmp word[ebx], 0 - je ..dev_not_found - add ebx, 10 - jmp ..nxt -..dev_not_found: - mov ah, 0x86 ; DEVICE_NOT_FOUND - jmp .return_a - -.not_FIND_PCI_DEVICE: - cmp ebp, 3 ; FIND_PCI_CLASS_CODE - jne .not_FIND_PCI_CLASS_CODE - mov esi, pci_emu_dat - shl ecx, 8 -..nxt2: - cmp [esi], ecx - jne ..no2 - mov bx, [esi] - xor ah, ah - jmp .return_ab -..no2: - cmp dword[esi], 0 - je ..dev_not_found - add esi, 10 - jmp ..nxt2 - -.not_FIND_PCI_CLASS_CODE: - cmp ebp, 8 ; READ_CONFIG_* - jb .not_READ_CONFIG - cmp ebp, 0x0A - ja .not_READ_CONFIG - mov eax, ebp - mov ah, bh - mov edx, edi - mov bh, bl - mov bl, dl - call pci_read_reg - mov ecx, eax - xor ah, ah ; SUCCESSFUL - jmp .return_abc -.not_READ_CONFIG: - cmp ebp, 0x0B ; WRITE_CONFIG_* - jb .not_WRITE_CONFIG - cmp ebp, 0x0D - ja .not_WRITE_CONFIG - lea eax, [ebp+1] - mov ah, bh - mov edx, edi - mov bh, bl - mov bl, dl - call pci_write_reg - xor ah, ah ; SUCCESSFUL - jmp .return_abc -.not_WRITE_CONFIG: -.unsupported_func: - mov ah, 0x81 ; FUNC_NOT_SUPPORTED -.return: - mov dword[esp + 4 ], edi - mov dword[esp + 8], esi -.return_abcd: - mov dword[esp + 24], edx -.return_abc: - mov dword[esp + 28], ecx -.return_ab: - mov dword[esp + 20], ebx -.return_a: - mov dword[esp + 32], eax - ret - -proc pci_enum - push ebp - mov ebp, esp - push 0 -virtual at ebp-4 -.devfn db ? -.bus db ? -end virtual -.loop: - mov ah, [.bus] - mov al, 2 - mov bh, [.devfn] - mov bl, 0 - call pci_read_reg - cmp eax, 0xFFFFFFFF - jnz .has_device - test byte [.devfn], 7 - jnz .next_func - jmp .no_device -.has_device: - push eax - movi eax, sizeof.PCIDEV - call malloc - pop ecx - test eax, eax - jz .nomemory - mov edi, eax - mov [edi+PCIDEV.vendor_device_id], ecx - mov eax, pcidev_list - mov ecx, [eax+PCIDEV.bk] - mov [edi+PCIDEV.bk], ecx - mov [edi+PCIDEV.fd], eax - mov [ecx+PCIDEV.fd], edi - mov [eax+PCIDEV.bk], edi - mov eax, dword [.devfn] - mov dword [edi+PCIDEV.devfn], eax - mov dword [edi+PCIDEV.owner], 0 - mov bh, al - mov al, 2 - mov bl, 8 - call pci_read_reg - shr eax, 8 - mov [edi+PCIDEV.class], eax - test byte [.devfn], 7 - jnz .next_func - mov ah, [.bus] - mov al, 0 - mov bh, [.devfn] - mov bl, 0Eh - call pci_read_reg - test al, al - js .next_func -.no_device: - or byte [.devfn], 7 -.next_func: - inc dword [.devfn] - mov ah, [.bus] - cmp ah, [BOOT.pci_data+1] - jbe .loop -.nomemory: - leave - ret -endp - -; Export for drivers. Just returns the pointer to the pci-devices list. -proc get_pcidev_list - mov eax, pcidev_list - ret -endp diff --git a/kernel/branches/Kolibri-F/bus/usb/common.inc b/kernel/branches/Kolibri-F/bus/usb/common.inc deleted file mode 100644 index cf59e30cb..000000000 --- a/kernel/branches/Kolibri-F/bus/usb/common.inc +++ /dev/null @@ -1,462 +0,0 @@ -; Constants and structures that are shared between different parts of -; USB subsystem and *HCI drivers. - -; ============================================================================= -; ================================= Constants ================================= -; ============================================================================= -; Version of all structures related to host controllers. -; Must be the same in kernel and *hci-drivers. -USBHC_VERSION = 2 - -; USB device must have at least 100ms of stable power before initializing can -; proceed; one timer tick is 10ms, so enforce delay in 10 ticks -USB_CONNECT_DELAY = 10 -; USB requires at least 10 ms for reset signalling. Normally, this is one timer -; tick. However, it is possible that we start reset signalling in the end of -; interval between timer ticks and then we test time in the start of the next -; interval; in this case, the delta between [timer_ticks] is 1, but the real -; time passed is significantly less than 10 ms. To avoid this, we add an extra -; tick; this guarantees that at least 10 ms have passed. -USB_RESET_TIME = 2 -; USB requires at least 10 ms of reset recovery, a delay between reset -; signalling and any commands to device. Add an extra tick for the same reasons -; as with the previous constant. -USB_RESET_RECOVERY_TIME = 2 - -; USB pipe types -CONTROL_PIPE = 0 -ISOCHRONOUS_PIPE = 1 -BULK_PIPE = 2 -INTERRUPT_PIPE = 3 - -; Status codes for transfer callbacks. -; Taken from OHCI as most verbose controller in this sense. -USB_STATUS_OK = 0 ; no error -USB_STATUS_CRC = 1 ; CRC error -USB_STATUS_BITSTUFF = 2 ; bit stuffing violation -USB_STATUS_TOGGLE = 3 ; data toggle mismatch -USB_STATUS_STALL = 4 ; device returned STALL -USB_STATUS_NORESPONSE = 5 ; device not responding -USB_STATUS_PIDCHECK = 6 ; invalid PID check bits -USB_STATUS_WRONGPID = 7 ; unexpected PID value -USB_STATUS_OVERRUN = 8 ; too many data from endpoint -USB_STATUS_UNDERRUN = 9 ; too few data from endpoint -USB_STATUS_BUFOVERRUN = 12 ; overflow of internal controller buffer -USB_STATUS_BUFUNDERRUN = 13 ; underflow of internal controller buffer -USB_STATUS_CLOSED = 16 ; pipe closed - ; either explicitly with USBClosePipe - ; or implicitly due to device disconnect -USB_STATUS_CANCELLED = 17 ; transfer cancelled with USBAbortPipe - -; Possible speeds of USB devices -USB_SPEED_FS = 0 ; full-speed -USB_SPEED_LS = 1 ; low-speed -USB_SPEED_HS = 2 ; high-speed - -; flags for usb_pipe.Flags -USB_FLAG_CLOSED = 1 ; pipe is closed, no new transfers -; pipe is closed, return error instead of submitting any new transfer -USB_FLAG_CAN_FREE = 2 -; pipe is closed via explicit call to USBClosePipe, so it can be freed without -; any driver notification; if this flag is not set, then the pipe is closed due -; to device disconnect, so it must remain valid until return from disconnect -; callback provided by the driver -USB_FLAG_EXTRA_WAIT = 4 -; The pipe was in wait list, while another event occured; -; when the first wait will be done, reinsert the pipe to wait list -USB_FLAG_DISABLED = 8 -; The pipe is temporarily disabled so that it is not visible to hardware -; but still remains in software list. Used for usb_abort_pipe. -USB_FLAG_CLOSED_BIT = 0 ; USB_FLAG_CLOSED = 1 shl USB_FLAG_CLOSED_BIT - -; ============================================================================= -; ================================ Structures ================================= -; ============================================================================= - -; Description of controller-specific data and functions. -struct usb_hardware_func -Version dd ? ; must be USBHC_VERSION -ID dd ? ; '*HCI' -DataSize dd ? ; sizeof(*hci_controller) -BeforeInit dd ? -; Early initialization: take ownership from BIOS. -; in: [ebp-4] = (bus shl 8) + devfn -Init dd ? -; Initialize controller-specific part of controller data. -; in: eax -> *hci_controller to initialize, [ebp-4] = (bus shl 8) + devfn -; out: eax = 0 <=> failed, otherwise eax -> usb_controller -ProcessDeferred dd ? -; Called regularly from the main loop of USB thread -; (either due to timeout from a previous call, or due to explicit wakeup). -; in: esi -> usb_controller -; out: eax = maximum timeout for next call (-1 = infinity) -SetDeviceAddress dd ? -; in: esi -> usb_controller, ebx -> usb_pipe, cl = address -GetDeviceAddress dd ? -; in: esi -> usb_controller, ebx -> usb_pipe -; out: eax = address -PortDisable dd ? -; Disable the given port in the root hub. -; in: esi -> usb_controller, ecx = port (zero-based) -InitiateReset dd ? -; Start reset signalling on the given port. -; in: esi -> usb_controller, ecx = port (zero-based) -SetEndpointPacketSize dd ? -; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size -AllocPipe dd ? -; out: eax = pointer to allocated usb_pipe -FreePipe dd ? -; void stdcall with one argument = pointer to previously allocated usb_pipe -InitPipe dd ? -; in: edi -> usb_pipe for target, ecx -> usb_pipe for config pipe, -; esi -> usb_controller, eax -> usb_gtd for the first TD, -; [ebp+12] = endpoint, [ebp+16] = maxpacket, [ebp+20] = type -UnlinkPipe dd ? -; esi -> usb_controller, ebx -> usb_pipe -AllocTD dd ? -; out: eax = pointer to allocated usb_gtd -FreeTD dd ? -; void stdcall with one argument = pointer to previously allocated usb_gtd -AllocTransfer dd ? -; Allocate and initialize one stage of a transfer. -; ebx -> usb_pipe, other parameters are passed through the stack: -; buffer,size = data to transfer -; flags = same as in usb_open_pipe: -; bit 0 = allow short transfer, other bits reserved -; td = pointer to the current end-of-queue descriptor -; direction = -; 0000b for normal transfers, -; 1000b for control SETUP transfer, -; 1101b for control OUT transfer, -; 1110b for control IN transfer -; returns eax = pointer to the new end-of-queue descriptor -; (not included in the queue itself) or 0 on error -InsertTransfer dd ? -; Activate previously initialized transfer (maybe with multiple stages). -; esi -> usb_controller, ebx -> usb_pipe, -; [esp+4] -> first usb_gtd for the transfer, -; ecx -> last descriptor for the transfer -NewDevice dd ? -; Initiate configuration of a new device (create pseudo-pipe describing that -; device and call usb_new_device). -; esi -> usb_controller, eax = speed (one of USB_SPEED_* constants). -DisablePipe dd ? -; This procedure temporarily removes the given pipe from hardware queue. -; esi -> usb_controller, ebx -> usb_pipe -EnablePipe dd ? -; This procedure reinserts the given pipe to hardware queue -; after DisablePipe, with clearing transfer queue. -; esi -> usb_controller, ebx -> usb_pipe -; edx -> current descriptor, eax -> new last descriptor -ends - -; pointers to kernel API functions that are called from *HCI-drivers -struct usbhc_func -usb_process_gtd dd ? -usb_init_static_endpoint dd ? -usb_wakeup_if_needed dd ? -usb_subscribe_control dd ? -usb_subscription_done dd ? -usb_allocate_common dd ? -usb_free_common dd ? -usb_td_to_virt dd ? -usb_init_transfer dd ? -usb_undo_tds dd ? -usb_test_pending_port dd ? -usb_get_tt dd ? -usb_get_tt_think_time dd ? -usb_new_device dd ? -usb_disconnect_stage2 dd ? -usb_process_wait_lists dd ? -usb_unlink_td dd ? -usb_is_final_packet dd ? -usb_find_ehci_companion dd ? -ends - -; Controller descriptor. -; This structure represents the common (controller-independent) part -; of a controller for the USB code. The corresponding controller-dependent -; part *hci_controller is located immediately before usb_controller. -struct usb_controller -; Two following fields organize all controllers in the global linked list. -Next dd ? -Prev dd ? -HardwareFunc dd ? -; Pointer to usb_hardware_func structure with controller-specific functions. -NumPorts dd ? -; Number of ports in the root hub. -PCICoordinates dd ? -; Device:function and bus number from PCI. -; -; The hardware is allowed to cache some data from hardware structures. -; Regular operations are designed considering this, -; but sometimes it is required to wait for synchronization of hardware cache -; with modified structures in memory. -; The code keeps two queues of pipes waiting for synchronization, -; one for asynchronous (bulk/control) pipes, one for periodic pipes, hardware -; cache is invalidated under different conditions for those types. -; Both queues are organized in the same way, as single-linked lists. -; There are three special positions: the head of list (new pipes are added -; here), the first pipe to be synchronized at the current iteration, -; the tail of list (all pipes starting from here are synchronized). -WaitPipeListAsync dd ? -WaitPipeListPeriodic dd ? -; List heads. -WaitPipeRequestAsync dd ? -WaitPipeRequestPeriodic dd ? -; Pending request to hardware to refresh cache for items from WaitPipeList*. -; (Pointers to some items in WaitPipeList* or NULLs). -ReadyPipeHeadAsync dd ? -ReadyPipeHeadPeriodic dd ? -; Items of RemovingList* which were released by hardware and are ready -; for further processing. -; (Pointers to some items in WaitPipeList* or NULLs). -NewConnected dd ? -; bit mask of recently connected ports of the root hub, -; bit set = a device was recently connected to the corresponding port; -; after USB_CONNECT_DELAY ticks of stable status these ports are moved to -; PendingPorts -NewDisconnected dd ? -; bit mask of disconnected ports of the root hub, -; bit set = a device in the corresponding port was disconnected, -; disconnect processing is required. -PendingPorts dd ? -; bit mask of ports which are ready to be initialized -ControlLock MUTEX ? -; mutex which guards all operations with control queue -BulkLock MUTEX ? -; mutex which guards all operations with bulk queue -PeriodicLock MUTEX ? -; mutex which guards all operations with periodic queues -WaitSpinlock: -; spinlock guarding WaitPipeRequest/ReadyPipeHead (but not WaitPipeList) -StartWaitFrame dd ? -; USB frame number when WaitPipeRequest* was registered. -ResettingHub dd ? -; Pointer to usb_hub responsible for the currently resetting port, if any. -; NULL for the root hub. -ResettingPort db ? -; Port that is currently resetting, 0-based. -ResettingSpeed db ? -; Speed of currently resetting device. -ResettingStatus db ? -; Status of port reset. 0 = no port is resetting, -1 = reset failed, -; 1 = reset in progress, 2 = reset recovery in progress. - rb 1 ; alignment -ResetTime dd ? -; Time when reset signalling or reset recovery has been started. -SetAddressBuffer rb 8 -; Buffer for USB control command SET_ADDRESS. -ExistingAddresses rd 128/32 -; Bitmask for 128 bits; bit i is cleared <=> address i is free for allocating -; for new devices. Bit 0 is always set. -ConnectedTime rd 16 -; Time, in timer ticks, when the port i has signalled the connect event. -; Valid only if bit i in NewConnected is set. -DevicesByPort rd 16 -; Pointer to usb_pipe for zero endpoint (which serves as device handle) -; for each port. -ends - -; Pipe descriptor. -; * An USB pipe is described by two structures, for hardware and for software. -; * This is the software part. The hardware part is defined in a driver -; of the corresponding controller. -; * The hardware part is located immediately before usb_pipe, -; both are allocated at once by controller-specific code -; (it knows the total length, which depends on the hardware part). -struct usb_pipe -Controller dd ? -; Pointer to usb_controller structure corresponding to this pipe. -; Must be the first dword after hardware part, see *hci_new_device. -; -; Every endpoint is included into one of processing lists: -; * Bulk list contains all Bulk endpoints. -; * Control list contains all Control endpoints. -; * Several Periodic lists serve Interrupt endpoints with different interval. -; - There are N=2^n "leaf" periodic lists for N ms interval, one is processed -; in the frames 0,N,2N,..., another is processed in the frames -; 1,1+N,1+2N,... and so on. The hardware starts processing of periodic -; endpoints in every frame from the list identified by lower n bits of the -; frame number; the addresses of these N lists are written to the -; controller data area during the initialization. -; - We assume that n=5, N=32 to simplify the code and compact the data. -; OHCI works in this way. UHCI and EHCI actually have n=10, N=1024, -; but this is an overkill for interrupt endpoints; the large value of N is -; useful only for isochronous transfers in UHCI and EHCI. UHCI/EHCI code -; initializes "leaf" lists k,k+32,k+64,...,k+(1024-32) to the same value, -; giving essentially N=32. -; This restriction means that the actual maximum interval of polling any -; interrupt endpoint is 32ms, which seems to be a reasonable value. -; - Similarly, there are 16 lists for 16-ms interval, 8 lists for 8-ms -; interval and so on. Finally, there is one list for 1ms interval. Their -; addresses are not directly known to the controller. -; - The hardware serves endpoints following a physical link from the hardware -; part. -; - The hardware links are organized as follows. If the list item is not the -; last, it's hardware link points to the next item. The hardware link of -; the last item points to the first item of the "next" list. -; - The "next" list for k-th and (k+M)-th periodic lists for interval 2M ms -; is the k-th periodic list for interval M ms, M >= 1. In this scheme, -; if two "previous" lists are served in the frames k,k+2M,k+4M,... -; and k+M,k+3M,k+5M,... correspondingly, the "next" list is served in -; the frames k,k+M,k+2M,k+3M,k+4M,k+5M,..., which is exactly what we want. -; - The links between Periodic, Control, Bulk lists and the processing of -; Isochronous endpoints are controller-specific. -; * The head of every processing list is a static entry which does not -; correspond to any real pipe. It is described by usb_static_ep -; structure, not usb_pipe. For OHCI and UHCI, sizeof.usb_static_ep plus -; sizeof hardware part is 20h, the total number of lists is -; 32+16+8+4+2+1+1+1 = 65, so all these structures fit in one page, -; leaving space for other data. This is another reason for 32ms limit. -; * Static endpoint descriptors are kept in *hci_controller structure. -; * All items in every processing list, including the static head, are -; organized in a double-linked list using .NextVirt and .PrevVirt fields. -; * [[item.NextVirt].PrevVirt] = [[item.PrevVirt].NextVirt] for all items. -NextVirt dd ? -; Next endpoint in the processing list. -; See also PrevVirt field and the description before NextVirt field. -PrevVirt dd ? -; Previous endpoint in the processing list. -; See also NextVirt field and the description before NextVirt field. -BaseList dd ? -; Pointer to head of the processing list. -; -; Every pipe has the associated transfer queue, that is, the double-linked -; list of Transfer Descriptors aka TD. For Control, Bulk and Interrupt -; endpoints this list consists of usb_gtd structures -; (GTD = General Transfer Descriptors), for Isochronous endpoints -; this list consists of usb_itd structures, which are not developed yet. -; The pipe needs to know only the last TD; the first TD can be -; obtained as [[pipe.LastTD].NextVirt]. -LastTD dd ? -; Last TD in the transfer queue. -; -; All opened pipes corresponding to the same physical device are organized in -; the double-linked list using .NextSibling and .PrevSibling fields. -; The head of this list is kept in usb_device_data structure (OpenedPipeList). -; This list is used when the device is disconnected and all pipes for the -; device should be closed. -; Also, all pipes closed due to disconnect must remain valid at least until -; driver-provided disconnect function returns; all should-be-freed-but-not-now -; pipes for one device are organized in another double-linked list with -; the head in usb_device_data.ClosedPipeList; this list uses the same link -; fields, one pipe can never be in both lists. -NextSibling dd ? -; Next pipe for the physical device. -PrevSibling dd ? -; Previous pipe for the physical device. -; -; When hardware part of pipe is changed, some time is needed before further -; actions so that hardware reacts on this change. During that time, -; all changed pipes are organized in single-linked list with the head -; usb_controller.WaitPipeList* and link field NextWait. -; Currently there are two possible reasons to change: -; change of address/packet size in initial configuration, -; close of the pipe. They are distinguished by USB_FLAG_CLOSED. -NextWait dd ? -Lock MUTEX -; Mutex that guards operations with transfer queue for this pipe. -Type db ? -; Type of pipe, one of {CONTROL,ISOCHRONOUS,BULK,INTERRUPT}_PIPE. -Flags db ? -; Combination of flags, USB_FLAG_*. - rb 2 ; dword alignment -DeviceData dd ? -; Pointer to usb_device_data, common for all pipes for one device. -ends - -; This structure describes the static head of every list of pipes. -struct usb_static_ep -; software fields -Bandwidth dd ? -; valid only for interrupt/isochronous USB1 lists -; The offsets of the following two fields must be the same in this structure -; and in usb_pipe. -NextVirt dd ? -PrevVirt dd ? -ends - -; This structure represents one transfer descriptor -; ('g' stands for "general" as opposed to isochronous usb_itd). -; Note that one transfer can have several descriptors: -; a control transfer has three stages. -; Additionally, every controller has a limit on transfer length with -; one descriptor (packet size for UHCI, 1K for OHCI, 4K for EHCI), -; large transfers must be split into individual packets according to that limit. -struct usb_gtd -Callback dd ? -; Zero for intermediate descriptors, pointer to callback function -; for final descriptor. See the docs for description of the callback. -UserData dd ? -; Dword which is passed to Callback as is, not used by USB code itself. -; Two following fields organize all descriptors for one pipe in -; the linked list. -NextVirt dd ? -PrevVirt dd ? -Pipe dd ? -; Pointer to the parent usb_pipe. -Buffer dd ? -; Pointer to data for this descriptor. -Length dd ? -; Length of data for this descriptor. -ends - -; Interface-specific data. Several interfaces of one device can operate -; independently, each is controlled by some driver and is identified by -; some driver-specific data passed as is to the driver. -struct usb_interface_data -DriverData dd ? -; Passed as is to the driver. -DriverFunc dd ? -; Pointer to USBSRV structure for the driver. -ends - -; Device-specific data. -struct usb_device_data -PipeListLock MUTEX -; Lock guarding OpenedPipeList. Must be the first item of the structure, -; the code passes pointer to usb_device_data as is to mutex_lock/unlock. -OpenedPipeList rd 2 -; List of all opened pipes for the device. -; Used when the device is disconnected, so all pipes should be closed. -ClosedPipeList rd 2 -; List of all closed, but still valid pipes for the device. -; A pipe closed with USBClosePipe is just deallocated, -; but a pipe closed due to disconnect must remain valid until driver-provided -; disconnect handler returns; this list links all such pipes to deallocate them -; after disconnect processing. -NumPipes dd ? -; Number of not-yet-closed pipes. -Hub dd ? -; NULL if connected to the root hub, pointer to usb_hub otherwise. -TTHub dd ? -; Pointer to usb_hub for (the) hub with Transaction Translator for the device, -; NULL if the device operates in the same speed as the controller. -Port db ? -; Port on the hub, zero-based. -TTPort db ? -; Port on the TTHub, zero-based. -DeviceDescrSize db ? -; Size of device descriptor. -Speed db ? -; Device speed, one of USB_SPEED_*. -Timer dd ? -; Handle of timer that handles request timeout. -NumInterfaces dd ? -; Number of interfaces. -ConfigDataSize dd ? -; Total size of data associated with the configuration descriptor -; (including the configuration descriptor itself). -Interfaces dd ? -; Offset from the beginning of this structure to Interfaces field. -; Variable-length fields: -; DeviceDescriptor: -; device descriptor starts here -; ConfigDescriptor = DeviceDescriptor + DeviceDescrSize -; configuration descriptor with all associated data -; Interfaces = ALIGN_UP(ConfigDescriptor + ConfigDataSize, 4) -; array of NumInterfaces elements of type usb_interface_data -ends - -usb_device_data.DeviceDescriptor = sizeof.usb_device_data diff --git a/kernel/branches/Kolibri-F/bus/usb/hccommon.inc b/kernel/branches/Kolibri-F/bus/usb/hccommon.inc deleted file mode 100644 index 90eacfab5..000000000 --- a/kernel/branches/Kolibri-F/bus/usb/hccommon.inc +++ /dev/null @@ -1,348 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; USB Host Controller support code: hardware-independent part, -; common for all controller types. - -iglobal -; USB HC support: some functions interesting only for *HCI-drivers. -align 4 -usb_hc_func: - dd usb_process_gtd - dd usb_init_static_endpoint - dd usb_wakeup_if_needed - dd usb_subscribe_control - dd usb_subscription_done - dd slab_alloc - dd slab_free - dd usb_td_to_virt - dd usb_init_transfer - dd usb_undo_tds - dd usb_test_pending_port - dd usb_get_tt - dd usb_get_tt_think_time - dd usb_new_device - dd usb_disconnect_stage2 - dd usb_process_wait_lists - dd usb_unlink_td - dd usb_is_final_packet - dd usb_find_ehci_companion -endg - -; Initializes one controller, called by usb_init for every controller. -; eax -> PCIDEV structure for the device. -proc usb_init_controller - push ebp - mov ebp, esp -; 1. Store in the stack PCI coordinates and save pointer to PCIDEV: -; make [ebp-4] = (bus shl 8) + devfn, used by controller-specific Init funcs. - push dword [eax+PCIDEV.devfn] - push eax - mov edi, [eax+PCIDEV.owner] - test edi, edi - jz .nothing - mov edi, [edi+USBSRV.usb_func] -; 2. Allocate *hci_controller + usb_controller. - mov ebx, [edi+usb_hardware_func.DataSize] - add ebx, sizeof.usb_controller - stdcall kernel_alloc, ebx - test eax, eax - jz .nothing -; 3. Zero-initialize both structures. - push edi eax - mov ecx, ebx - shr ecx, 2 - xchg edi, eax - xor eax, eax - rep stosd -; 4. Initialize usb_controller structure, -; except data known only to controller-specific code (like NumPorts) -; and link fields -; (this structure will be inserted to the overall list at step 6). - dec eax - mov [edi+usb_controller.ExistingAddresses+4-sizeof.usb_controller], eax - mov [edi+usb_controller.ExistingAddresses+8-sizeof.usb_controller], eax - mov [edi+usb_controller.ExistingAddresses+12-sizeof.usb_controller], eax - mov [edi+usb_controller.ResettingPort-sizeof.usb_controller], al ; no resetting port - dec eax ; don't allocate zero address - mov [edi+usb_controller.ExistingAddresses-sizeof.usb_controller], eax - mov eax, [ebp-4] - mov [edi+usb_controller.PCICoordinates-sizeof.usb_controller], eax - lea ecx, [edi+usb_controller.PeriodicLock-sizeof.usb_controller] - call mutex_init - add ecx, usb_controller.ControlLock - usb_controller.PeriodicLock - call mutex_init - add ecx, usb_controller.BulkLock - usb_controller.ControlLock - call mutex_init - pop eax edi - mov [eax+ebx-sizeof.usb_controller+usb_controller.HardwareFunc], edi - push eax -; 5. Call controller-specific initialization. -; If failed, free memory allocated in step 2 and return. - call [edi+usb_hardware_func.Init] - test eax, eax - jz .fail - pop ecx -; 6. Insert the controller to the global list. - xchg eax, ebx - mov ecx, usb_controllers_list_mutex - call mutex_lock - mov edx, usb_controllers_list - mov eax, [edx+usb_controller.Prev] - mov [ebx+usb_controller.Next], edx - mov [ebx+usb_controller.Prev], eax - mov [edx+usb_controller.Prev], ebx - mov [eax+usb_controller.Next], ebx - call mutex_unlock -; 7. Wakeup USB thread to call ProcessDeferred. - call usb_wakeup -.nothing: -; 8. Restore pointer to PCIDEV saved in step 1 and return. - pop eax - leave - ret -.fail: - call kernel_free - jmp .nothing -endp - -; Helper function, calculates physical address including offset in page. -proc get_phys_addr - push ecx - mov ecx, eax - and ecx, 0xFFF - call get_pg_addr - add eax, ecx - pop ecx - ret -endp - -; Put the given control/bulk pipe in the wait list; -; called when the pipe structure is changed and a possible hardware cache -; needs to be synchronized. When it will be known that the cache is updated, -; usb_subscription_done procedure will be called. -proc usb_subscribe_control - cmp [ebx+usb_pipe.NextWait], -1 - jnz @f - mov eax, [esi+usb_controller.WaitPipeListAsync] - mov [ebx+usb_pipe.NextWait], eax - mov [esi+usb_controller.WaitPipeListAsync], ebx -@@: - ret -endp - -; Same as usb_subscribe_control, but for interrupt/isochronous pipe. -proc usb_subscribe_periodic - cmp [ebx+usb_pipe.NextWait], -1 - jnz @f - mov eax, [esi+usb_controller.WaitPipeListPeriodic] - mov [ebx+usb_pipe.NextWait], eax - mov [esi+usb_controller.WaitPipeListPeriodic], ebx -@@: - ret -endp - -; Called after synchronization of hardware cache with software changes. -; Continues process of device enumeration based on when it was delayed -; due to call to usb_subscribe_control. -proc usb_subscription_done - mov eax, [ebx+usb_pipe.DeviceData] - cmp [eax+usb_device_data.DeviceDescrSize], 0 - jz usb_after_set_address - jmp usb_after_set_endpoint_size -endp - -; This function is called when a new device has either passed -; or failed first stages of configuration, so the next device -; can enter configuration process. -proc usb_test_pending_port - mov [esi+usb_controller.ResettingPort], -1 - cmp [esi+usb_controller.PendingPorts], 0 - jz .nothing - bsf ecx, [esi+usb_controller.PendingPorts] - btr [esi+usb_controller.PendingPorts], ecx - mov eax, [esi+usb_controller.HardwareFunc] - jmp [eax+usb_hardware_func.InitiateReset] -.nothing: - ret -endp - -; This procedure is regularly called from controller-specific ProcessDeferred, -; it checks whether there are disconnected events and if so, process them. -proc usb_disconnect_stage2 - bsf ecx, [esi+usb_controller.NewDisconnected] - jz .nothing - lock btr [esi+usb_controller.NewDisconnected], ecx - btr [esi+usb_controller.PendingPorts], ecx - xor ebx, ebx - xchg ebx, [esi+usb_controller.DevicesByPort+ecx*4] - test ebx, ebx - jz usb_disconnect_stage2 - call usb_device_disconnected - jmp usb_disconnect_stage2 -.nothing: - ret -endp - -; Initial stage of disconnect processing: called when device is disconnected. -proc usb_device_disconnected -; Loop over all pipes, close everything, wait until hardware reacts. -; The final handling is done in usb_pipe_closed. - push ebx - mov ecx, [ebx+usb_pipe.DeviceData] - call mutex_lock - lea eax, [ecx+usb_device_data.OpenedPipeList-usb_pipe.NextSibling] - push eax - mov ebx, [eax+usb_pipe.NextSibling] -.pipe_loop: - call usb_close_pipe_nolock - mov ebx, [ebx+usb_pipe.NextSibling] - cmp ebx, [esp] - jnz .pipe_loop - pop eax - pop ebx - mov ecx, [ebx+usb_pipe.DeviceData] - call mutex_unlock - ret -endp - -; Called from controller-specific ProcessDeferred, -; processes wait-pipe-done notifications, -; returns whether there are more items in wait queues. -; in: esi -> usb_controller -; out: eax = bitmask of pipe types with non-empty wait queue -proc usb_process_wait_lists - xor edx, edx - push edx - call usb_process_one_wait_list - jnc @f - or byte [esp], 1 shl CONTROL_PIPE -@@: - movi edx, 4 - call usb_process_one_wait_list - jnc @f - or byte [esp], 1 shl INTERRUPT_PIPE -@@: - xor edx, edx - call usb_process_one_wait_list - jnc @f - or byte [esp], 1 shl CONTROL_PIPE -@@: - pop eax - ret -endp - -; Helper procedure for usb_process_wait_lists; -; does the same for one wait queue. -; in: esi -> usb_controller, -; edx=0 for *Async, edx=4 for *Periodic list -; out: CF = issue new request -proc usb_process_one_wait_list -; 1. Check whether there is a pending request. If so, do nothing. - mov ebx, [esi+usb_controller.WaitPipeRequestAsync+edx] - cmp ebx, [esi+usb_controller.ReadyPipeHeadAsync+edx] - clc - jnz .nothing -; 2. Check whether there are new data. If so, issue a new request. - cmp ebx, [esi+usb_controller.WaitPipeListAsync+edx] - stc - jnz .nothing - test ebx, ebx - jz .nothing -; 3. Clear all lists. - xor ecx, ecx - mov [esi+usb_controller.WaitPipeListAsync+edx], ecx - mov [esi+usb_controller.WaitPipeRequestAsync+edx], ecx - mov [esi+usb_controller.ReadyPipeHeadAsync+edx], ecx -; 4. Loop over all pipes from the wait list. -.pipe_loop: -; For every pipe: -; 5. Save edx and next pipe in the list. - push edx - push [ebx+usb_pipe.NextWait] -; 6. If USB_FLAG_EXTRA_WAIT is set, reinsert the pipe to the list and continue. - test [ebx+usb_pipe.Flags], USB_FLAG_EXTRA_WAIT - jz .process - mov eax, [esi+usb_controller.WaitPipeListAsync+edx] - mov [ebx+usb_pipe.NextWait], eax - mov [esi+usb_controller.WaitPipeListAsync+edx], ebx - jmp .continue -.process: -; 7. Call the handler depending on USB_FLAG_CLOSED and USB_FLAG_DISABLED. - or [ebx+usb_pipe.NextWait], -1 - test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED - jz .nodisconnect - call usb_pipe_closed - jmp .continue -.nodisconnect: - test [ebx+usb_pipe.Flags], USB_FLAG_DISABLED - jz .nodisabled - call usb_pipe_disabled - jmp .continue -.nodisabled: - call usb_subscription_done -.continue: -; 8. Restore edx and next pipe saved in step 5 and continue the loop. - pop ebx - pop edx - test ebx, ebx - jnz .pipe_loop -.check_new_work: -; 9. Set CF depending on whether WaitPipeList* is nonzero. - cmp [esi+usb_controller.WaitPipeListAsync+edx], 1 - cmc -.nothing: - ret -endp - -; Called from USB1 controller-specific initialization. -; Finds EHCI companion controller for given USB1 controller. -; in: bl = PCI device:function for USB1 controller, bh = PCI bus -; out: eax -> usb_controller for EHCI companion -proc usb_find_ehci_companion -; 1. Loop over all registered controllers. - mov eax, usb_controllers_list -.next: - mov eax, [eax+usb_controller.Next] - cmp eax, usb_controllers_list - jz .notfound -; 2. For every controller, check the type, ignore everything that is not EHCI. - mov edx, [eax+usb_controller.HardwareFunc] - cmp [edx+usb_hardware_func.ID], 'EHCI' - jnz .next -; 3. For EHCI controller, compare PCI coordinates with input data: -; bus and device must be the same, function can be different. - mov edx, [eax+usb_controller.PCICoordinates] - xor edx, ebx - cmp dx, 8 - jae .next - ret -.notfound: - xor eax, eax - ret -endp - -; Find Transaction Translator hub and port for the given device. -; in: edx = parent hub for the device, ecx = port for the device -; out: edx = TT hub for the device, ecx = TT port for the device. -proc usb_get_tt -; If the parent hub is high-speed, it is TT for the device. -; Otherwise, the parent hub itself is behind TT, and the device -; has the same TT hub+port as the parent hub. - mov eax, [edx+usb_hub.ConfigPipe] - mov eax, [eax+usb_pipe.DeviceData] - cmp [eax+usb_device_data.Speed], USB_SPEED_HS - jz @f - movzx ecx, [eax+usb_device_data.TTPort] - mov edx, [eax+usb_device_data.TTHub] -@@: - mov edx, [edx+usb_hub.ConfigPipe] - ret -endp diff --git a/kernel/branches/Kolibri-F/bus/usb/hub.inc b/kernel/branches/Kolibri-F/bus/usb/hub.inc deleted file mode 100644 index 40cfaa5b6..000000000 --- a/kernel/branches/Kolibri-F/bus/usb/hub.inc +++ /dev/null @@ -1,1285 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; Support for USB (non-root) hubs: -; powering up/resetting/disabling ports, -; watching for adding/removing devices. - -; ============================================================================= -; ================================= Constants ================================= -; ============================================================================= -; Hub constants -; USB hub descriptor type -USB_HUB_DESCRIPTOR = 29h - -; Features for CLEAR_FEATURE commands to the hub. -C_HUB_LOCAL_POWER = 0 -C_HUB_OVER_CURRENT = 1 - -; Bits in result of GET_STATUS command for a port. -; Also suitable for CLEAR_FEATURE/SET_FEATURE commands, where applicable, -; except TEST/INDICATOR. -PORT_CONNECTION = 0 -PORT_ENABLE = 1 -PORT_SUSPEND = 2 -PORT_OVER_CURRENT = 3 -PORT_RESET = 4 -PORT_POWER = 8 -PORT_LOW_SPEED = 9 -PORT_HIGH_SPEED = 10 -PORT_TEST_BIT = 11 -PORT_INDICATOR_BIT = 12 -C_PORT_CONNECTION = 16 -C_PORT_ENABLE = 17 -C_PORT_SUSPEND = 18 -C_PORT_OVER_CURRENT = 19 -C_PORT_RESET = 20 -PORT_TEST_FEATURE = 21 -PORT_INDICATOR_FEATURE = 22 - -; Internal constants -; Bits in usb_hub.Actions -HUB_WAIT_POWERED = 1 -; ports were powered, wait until power is stable -HUB_WAIT_CONNECT = 2 -; some device was connected, wait initial debounce interval -HUB_RESET_IN_PROGRESS = 4 -; reset in progress, so buffer for config requests is owned -; by reset process; this includes all stages from initial disconnect test -; to end of setting address (fail on any stage should lead to disabling port, -; which requires a config request) -HUB_RESET_WAITING = 8 -; the port is ready for reset, but another device somewhere on the bus -; is resetting. Implies HUB_RESET_IN_PROGRESS -HUB_RESET_SIGNAL = 10h -; reset signalling is active for some port in the hub -; Implies HUB_RESET_IN_PROGRESS -HUB_RESET_RECOVERY = 20h -; reset recovery is active for some port in the hub -; Implies HUB_RESET_IN_PROGRESS - -; Well, I think that those 5 flags WAIT_CONNECT and RESET_* require additional -; comments. So that is the overview of what happens with a new device assuming -; no errors. -; * device is connected; -; * hub notifies us about connect event; after some processing -; usb_hub_port_change finally processes that event, setting the flag -; HUB_WAIT_CONNECT and storing time when the device was connected; -; * 100 ms delay; -; * usb_hub_process_deferred clears HUB_WAIT_CONNECT, -; sets HUB_RESET_IN_PROGRESS, stores the port index in ConfigBuffer and asks -; the hub whether there was a disconnect event for that port during those -; 100 ms (on the hardware level notifications are obtained using polling -; with some intervals, so it is possible that the corresponding notification -; has not arrived yet); -; * usb_hub_connect_port_status checks that there was no disconnect event -; and sets HUB_RESET_WAITING flag (HUB_RESET_IN_PROGRESS is still set, -; ConfigBuffer still contains the port index); -; * usb_hub_process_deferred checks whether there is another device currently -; resetting. If so, it waits until reset is done -; (with HUB_RESET_WAITING and HUB_RESET_IN_PROGRESS bits set); -; * usb_hub_process_deferred clears HUB_RESET_WAITING, sets HUB_RESET_SIGNAL -; and initiates reset signalling on the port; -; * usb_hub_process_deferred checks the status every tick; -; when reset signalling is stopped by the hub, usb_hub_resetting_port_status -; callback clears HUB_RESET_SIGNAL and sets HUB_RESET_RECOVERY; -; * 10 ms (at least) delay; -; * usb_hub_process_deferred clears HUB_RESET_RECOVERY and notifies other code -; that the new device is ready to be configured; -; * when it is possible to reset another device, the protocol layer -; clears HUB_RESET_IN_PROGRESS bit. - -; ============================================================================= -; ================================ Structures ================================= -; ============================================================================= -; This structure contains all used data for one hub. -struct usb_hub -; All configured hubs are organized in the global usb_hub_list. -; Two following fields give next/prev items in that list. -; While the hub is unconfigured, they point to usb_hub itself. -Next dd ? -Prev dd ? -Controller dd ? -; Pointer to usb_controller for the bus. -; -; Handles of two pipes: configuration control pipe for zero endpoint opened by -; the common code and status interrupt pipe opened by us. -ConfigPipe dd ? -StatusPipe dd ? -NumPorts dd ? -; Number of downstream ports; from 1 to 255. -MaxPacketSize dd ? -; Maximum packet size for interrupt endpoint. -; Usually equals ceil((1+NumPorts)/8), but some hubs give additional bytes. -Actions dd ? -; Bitfield with HUB_* constants. -PoweredOnTime dd ? -; Time (in ticks) when all downstream ports were powered up. -ResetTime dd ? -; Time (in ticks) when the current port was reset; -; when a port is resetting, contains the last tick of status check; -; when reset recovery for a port is active, contains the time when -; reset was completed. -; -; There are two possible reasons for configuration requests: -; synchronous, when certain time is passed after something, -; and asynchronous, when the hub is notifying about some change and -; config request needs to be issued in order to query details. -; Use two different buffers to avoid unnecessary dependencies. -ConfigBuffer rb 8 -; Buffer for configuration requests for synchronous events. -ChangeConfigBuffer rb 8 -; Buffer for configuration requests for status changes. -AccStatusChange db ? -; Accumulated status change. See 11.12.3 of USB2 spec or comments in code. -HubCharacteristics dw ? -; Copy of usb_hub_descr.wHubCharacteristics. -PowerOnInterval db ? -; Copy of usb_hub_descr.bPwrOn2PwrGood. -; -; Two following fields are written at once by GET_STATUS request -; and must remain in this order. -StatusData dw ? -; Bitfield with 1 shl PORT_* indicating status of the current port. -StatusChange dw ? -; Bitfield with 1 shl PORT_* indicating change in status of the current port. -; Two following fields are written at once by GET_STATUS request -; and must remain in this order. -; The meaning is the same as of StatusData/StatusChange; two following fields -; are used by the synchronous requests to avoid unnecessary interactions with -; the asynchronous handler. -ResetStatusData dw ? -ResetStatusChange dw ? -StatusChangePtr dd ? -; Pointer to StatusChangeBuf. -ConnectedDevicesPtr dd ? -; Pointer to ConnectedDevices. -ConnectedTimePtr dd ? -; Pointer to ConnectedTime. -; -; Variable-length parts: -; DeviceRemovable rb (NumPorts+8)/8 -; Bit i+1 = device at port i (zero-based) is non-removable. -; StatusChangeBuf rb (NumPorts+8)/8 -; Buffer for status interrupt pipe. Bit 0 = hub status change, -; other bits = status change of the corresponding ports. -; ConnectedDevices rd NumPorts -; Pointers to config pipes for connected devices or zero if no device connected. -; ConnectedTime rd NumPorts -; For initial debounce interval: -; time (in ticks) when a device was connected at that port. -; Normally: -1 -ends - -; Hub descriptor. -struct usb_hub_descr usb_descr -bNbrPorts db ? -; Number of downstream ports. -wHubCharacteristics dw ? -; Bit 0: 0 = all ports are powered at once, 1 = individual port power switching -; Bit 1: reserved, must be zero -; Bit 2: 1 = the hub is part of a compound device -; Bits 3-4: 00 = global overcurrent protection, -; 01 = individual port overcurrent protection, -; 1x = no overcurrent protection -; Bits 5-6: Transaction Translator Think Time, 8*(value+1) full-speed bit times -; Bit 7: 1 = port indicators supported -; Other bits are reserved. -bPwrOn2PwrGood db ? -; Time in 2ms intervals between powering up a port and a port becoming ready. -bHubContrCurrent db ? -; Maximum current requirements of the Hub Controller electronics in mA. -; DeviceRemovable - variable length -; Bit 0 is reserved, bit i+1 = device at port i is non-removable. -; PortPwrCtrlMask - variable length -; Obsolete, exists for compatibility. We ignore it. -ends - -iglobal -align 4 -; Implementation of struct USBFUNC for hubs. -usb_hub_callbacks: - dd usb_hub_callbacks_end - usb_hub_callbacks - dd usb_hub_init - dd usb_hub_disconnect -usb_hub_callbacks_end: -usb_hub_pseudosrv dd usb_hub_callbacks -endg - -; This procedure is called when new hub is detected. -; It initializes the device. -; Technically, initialization implies sending several USB queries, -; so it is split in several procedures. The first is usb_hub_init, -; other are callbacks which will be called at some time in the future, -; when the device will respond. -; edx = usb_interface_descr, ecx = length rest -proc usb_hub_init - push ebx esi ; save used registers to be stdcall -virtual at esp - rd 2 ; saved registers - dd ? ; return address -.pipe dd ? ; handle of the config pipe -.config dd ? ; pointer to usb_config_descr -.interface dd ? ; pointer to usb_interface_descr -end virtual -; 1. Check that the maximal nesting is not exceeded: -; 5 non-root hubs is the maximum according to the spec. - mov ebx, [.pipe] - push 5 - mov eax, ebx -.count_parents: - mov eax, [eax+usb_pipe.DeviceData] - mov eax, [eax+usb_device_data.Hub] - test eax, eax - jz .depth_ok - mov eax, [eax+usb_hub.ConfigPipe] - dec dword [esp] - jnz .count_parents - pop eax - dbgstr 'Hub chain is too long' - jmp .return0 -.depth_ok: - pop eax -; Hubs use one IN interrupt endpoint for polling the device -; 2. Locate the descriptor of the interrupt endpoint. -; Loop over all descriptors owned by this interface. -.lookep: -; 2a. Skip the current descriptor. - movzx eax, [edx+usb_descr.bLength] - add edx, eax - sub ecx, eax - jb .errorep -; 2b. Length of data left must be at least sizeof.usb_endpoint_descr. - cmp ecx, sizeof.usb_endpoint_descr - jb .errorep -; 2c. If we have found another interface descriptor but not found our endpoint, -; this is an error: all subsequent descriptors belong to that interface -; (or further interfaces). - cmp [edx+usb_endpoint_descr.bDescriptorType], USB_INTERFACE_DESCR - jz .errorep -; 2d. Ignore all interface-related descriptors except endpoint descriptor. - cmp [edx+usb_endpoint_descr.bDescriptorType], USB_ENDPOINT_DESCR - jnz .lookep -; 2e. Length of endpoint descriptor must be at least sizeof.usb_endpoint_descr. - cmp [edx+usb_endpoint_descr.bLength], sizeof.usb_endpoint_descr - jb .errorep -; 2f. Ignore all endpoints except for INTERRUPT IN. - cmp [edx+usb_endpoint_descr.bEndpointAddress], 0 - jge .lookep - mov al, [edx+usb_endpoint_descr.bmAttributes] - and al, 3 - cmp al, INTERRUPT_PIPE - jnz .lookep -; We have located the descriptor for INTERRUPT IN endpoint, -; the pointer is in edx. -; 3. Allocate memory for the hub descriptor. -; Maximum length (assuming 255 downstream ports) is 40 bytes. -; Allocate 4 extra bytes to keep wMaxPacketSize. -; 3a. Save registers. - push edx -; 3b. Call the allocator. - movi eax, 44 - call malloc -; 3c. Restore registers. - pop ecx -; 3d. If failed, say something to the debug board and return error. - test eax, eax - jz .nomemory -; 3e. Store the pointer in esi. xchg eax,r32 is one byte shorter than mov. - xchg esi, eax -; 4. Open a pipe for the status endpoint with descriptor found in step 1. - movzx eax, [ecx+usb_endpoint_descr.bEndpointAddress] - movzx edx, [ecx+usb_endpoint_descr.bInterval] - movzx ecx, [ecx+usb_endpoint_descr.wMaxPacketSize] - test ecx, (1 shl 11) - 1 - jz .free - push ecx - stdcall usb_open_pipe, ebx, eax, ecx, INTERRUPT_PIPE, edx - pop ecx -; If failed, free the memory allocated in step 3, -; say something to the debug board and return error. - test eax, eax - jz .free -; 5. Send control query for the hub descriptor, -; pass status pipe as a callback parameter, -; allow short packets. - and ecx, (1 shl 11) - 1 - mov [esi+40], ecx - mov dword [esi], 0xA0 + \ ; class-specific request - (USB_GET_DESCRIPTOR shl 8) + \ - (0 shl 16) + \ ; descriptor index 0 - (USB_HUB_DESCRIPTOR shl 24) - mov dword [esi+4], 40 shl 16 - stdcall usb_control_async, ebx, esi, esi, 40, usb_hub_got_config, eax, 1 -; 6. If failed, free the memory allocated in step 3, -; say something to the debug board and return error. - test eax, eax - jz .free -; Otherwise, return 1. usb_hub_got_config will overwrite it later. - xor eax, eax - inc eax - jmp .nothing -.free: - xchg eax, esi - call free - jmp .return0 -.errorep: - dbgstr 'Invalid config descriptor for a hub' - jmp .return0 -.nomemory: - dbgstr 'No memory for USB hub data' -.return0: - xor eax, eax -.nothing: - pop esi ebx ; restore used registers to be stdcall - retn 12 -endp - -; This procedure is called when the request for the hub descriptor initiated -; by usb_hub_init is finished, either successfully or unsuccessfully. -proc usb_hub_got_config stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword - push ebx ; save used registers to be stdcall -; 1. If failed, say something to the debug board, free the buffer -; and stop the initialization. - cmp [status], 0 - jnz .invalid -; 2. The length must be at least sizeof.usb_hub_descr. -; Note that [length] includes 8 bytes of setup packet. - cmp [length], 8 + sizeof.usb_hub_descr - jb .invalid -; 3. Sanity checks for the hub descriptor. - mov eax, [buffer] -if USB_DUMP_DESCRIPTORS - mov ecx, [length] - sub ecx, 8 - DEBUGF 1,'K : hub config:' - push eax -@@: - DEBUGF 1,' %x',[eax]:2 - inc eax - dec ecx - jnz @b - DEBUGF 1,'\n' - pop eax -end if - cmp [eax+usb_hub_descr.bLength], sizeof.usb_hub_descr - jb .invalid - cmp [eax+usb_hub_descr.bDescriptorType], USB_HUB_DESCRIPTOR - jnz .invalid - movzx ecx, [eax+usb_hub_descr.bNbrPorts] - test ecx, ecx - jz .invalid -; 4. We use sizeof.usb_hub_descr bytes plus DeviceRemovable info; -; size of DeviceRemovable is (NumPorts+1) bits, this gives -; floor(NumPorts/8)+1 bytes. Check that all data are present in the -; descriptor and were successfully read. - mov edx, ecx - shr edx, 3 - add edx, sizeof.usb_hub_descr + 1 - cmp [eax+usb_hub_descr.bLength], dl - jb .invalid - sub [length], 8 - cmp [length], edx - jb .invalid -; 5. Allocate the memory for usb_hub structure. -; Total size of variable-length data is ALIGN_UP(floor(NumPorts/8)+1+MaxPacketSize,4)+8*NumPorts. - add edx, [eax+40] - add edx, sizeof.usb_hub - sizeof.usb_hub_descr + 3 - and edx, not 3 - lea eax, [edx+ecx*8] - push ecx edx - call malloc - pop edx ecx - test eax, eax - jz .nomemory - xchg eax, ebx -; 6. Fill usb_hub structure. - mov [ebx+usb_hub.NumPorts], ecx - add edx, ebx - mov [ebx+usb_hub.ConnectedDevicesPtr], edx - mov eax, [pipe] - mov [ebx+usb_hub.ConfigPipe], eax - mov edx, [eax+usb_pipe.Controller] - mov [ebx+usb_hub.Controller], edx - mov eax, [calldata] - mov [ebx+usb_hub.StatusPipe], eax - push esi edi - mov esi, [buffer] - mov eax, [esi+40] - mov [ebx+usb_hub.MaxPacketSize], eax -; The following commands load bNbrPorts, wHubCharacteristics, bPwrOn2PwrGood. - mov edx, dword [esi+usb_hub_descr.bNbrPorts] - mov dl, 0 -; The following command zeroes AccStatusChange and stores -; HubCharacteristics and PowerOnInterval. - mov dword [ebx+usb_hub.AccStatusChange], edx - xor eax, eax - mov [ebx+usb_hub.Actions], eax -; Copy DeviceRemovable data. - lea edi, [ebx+sizeof.usb_hub] - add esi, sizeof.usb_hub_descr - mov edx, ecx - shr ecx, 3 - inc ecx - rep movsb - mov [ebx+usb_hub.StatusChangePtr], edi -; Zero ConnectedDevices. - mov edi, [ebx+usb_hub.ConnectedDevicesPtr] - mov ecx, edx - rep stosd - mov [ebx+usb_hub.ConnectedTimePtr], edi -; Set ConnectedTime to -1. - dec eax - mov ecx, edx - rep stosd - pop edi esi -; 7. Replace value of 1 returned from usb_hub_init to the real value. -; Note: hubs are part of the core USB code, so this code can work with -; internals of other parts. Another way, the only possible one for external -; drivers, is to use two memory allocations: one (returned from AddDevice and -; fixed after that) for pointer, another for real data. That would work also, -; but wastes one allocation. - mov eax, [pipe] - mov eax, [eax+usb_pipe.DeviceData] - add eax, [eax+usb_device_data.Interfaces] -.scan: - cmp [eax+usb_interface_data.DriverData], 1 - jnz @f - cmp [eax+usb_interface_data.DriverFunc], usb_hub_pseudosrv - USBSRV.usb_func - jz .scan_found -@@: - add eax, sizeof.usb_interface_data - jmp .scan -.scan_found: - mov [eax+usb_interface_data.DriverData], ebx -; 8. Insert the hub structure to the tail of the overall list of all hubs. - mov ecx, usb_hubs_list - mov edx, [ecx+usb_hub.Prev] - mov [ecx+usb_hub.Prev], ebx - mov [edx+usb_hub.Next], ebx - mov [ebx+usb_hub.Prev], edx - mov [ebx+usb_hub.Next], ecx -; 9. Start powering up all ports. - DEBUGF 1,'K : found hub with %d ports\n',[ebx+usb_hub.NumPorts] - lea eax, [ebx+usb_hub.ConfigBuffer] - xor ecx, ecx - mov dword [eax], 23h + \ ; class-specific request to hub port - (USB_SET_FEATURE shl 8) + \ - (PORT_POWER shl 16) - mov edx, [ebx+usb_hub.NumPorts] - mov dword [eax+4], edx - stdcall usb_control_async, [ebx+usb_hub.ConfigPipe], eax, ecx, ecx, usb_hub_port_powered, ebx, ecx -.freebuf: -; 10. Free the buffer for hub descriptor and return. - mov eax, [buffer] - call free - pop ebx ; restore used registers to be stdcall - ret -.nomemory: - dbgstr 'No memory for USB hub data' - jmp .freebuf -.invalid: - dbgstr 'Invalid hub descriptor' - jmp .freebuf -endp - -; This procedure is called when the request to power up some port is completed, -; either successfully or unsuccessfully. -proc usb_hub_port_powered stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword -; 1. Check whether the operation was successful. -; If not, say something to the debug board and ssstop the initialization. - cmp [status], 0 - jnz .invalid -; 2. Check whether all ports were powered. -; If so, go to 4. Otherwise, proceed to 3. - mov eax, [calldata] - dec dword [eax+usb_hub.ConfigBuffer+4] - jz .done -; 3. Power up the next port and return. - lea edx, [eax+usb_hub.ConfigBuffer] - xor ecx, ecx - stdcall usb_control_async, [eax+usb_hub.ConfigPipe], edx, ecx, ecx, usb_hub_port_powered, eax, ecx -.nothing: - ret -.done: -; 4. All ports were powered. -; The hub requires some delay until power will be stable, the delay value -; is provided in the hub descriptor; we have copied that value to -; usb_hub.PowerOnInterval. Note the time and set the corresponding flag -; for usb_hub_process_deferred. - mov ecx, [timer_ticks] - mov [eax+usb_hub.PoweredOnTime], ecx - or [eax+usb_hub.Actions], HUB_WAIT_POWERED - jmp .nothing -.invalid: - dbgstr 'Error while powering hub ports' - jmp .nothing -endp - -; Requests notification about any changes in hub/ports configuration. -; Called when initial configuration is done and when a previous notification -; has been processed. -proc usb_hub_wait_change - stdcall usb_normal_transfer_async, [eax+usb_hub.StatusPipe], \ - [eax+usb_hub.StatusChangePtr], [eax+usb_hub.MaxPacketSize], usb_hub_changed, eax, 1 - ret -endp - -; This procedure is called when something has changed on the hub. -proc usb_hub_changed stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword -; DEBUGF 1,'K : [%d] int pipe for hub %x\n',[timer_ticks],[calldata] -; 1. Check whether our request has failed. -; If so, say something to the debug board and stop processing notifications. - xor ecx, ecx - cmp [status], ecx - jnz .failed -; 2. If no data were retrieved, restart waiting. - mov eax, [calldata] - cmp [length], ecx - jz .continue -; 3. If size of data retrieved is less than maximal, pad with zeroes; -; this corresponds to 'state of other ports was not changed' - mov ecx, [eax+usb_hub.NumPorts] - shr ecx, 3 - inc ecx - sub ecx, [length] - jbe .restart - push eax edi - mov edi, [buffer] - add edi, [length] - xor eax, eax - rep stosb - pop edi eax -.restart: -; State of some elements of the hub was changed. -; Find the first element that was changed, -; ask the hub about nature of the change, -; clear the corresponding change, -; reask the hub about status+change (it is possible that another change -; occurs between the first ask and clearing the change; we won't see that -; change, so we need to query the status after clearing the change), -; continue two previous steps until nothing changes, -; process all changes which were registered. -; When all changes for one element will be processed, return to here and look -; for other changed elements. - mov edx, [eax+usb_hub.StatusChangePtr] -; We keep all observed changes in the special var usb_hub.AccStatusChange; -; it will be logical OR of all observed StatusChange's. -; 4. No observed changes yet, zero usb_hub.AccStatusChange. - xor ecx, ecx - mov [eax+usb_hub.AccStatusChange], cl -; 5. Test whether there was a change in the hub itself. -; If so, query hub state. - btr dword [edx], ecx - jnc .no_hub_change -.next_hub_change: -; DEBUGF 1,'K : [%d] querying status of hub %x\n',[timer_ticks],eax - lea edx, [eax+usb_hub.ChangeConfigBuffer] - lea ecx, [eax+usb_hub.StatusData] - mov dword [edx], 0A0h + \ ; class-specific request from hub itself - (USB_GET_STATUS shl 8) - mov dword [edx+4], 4 shl 16 ; get 4 bytes - stdcall usb_control_async, [eax+usb_hub.ConfigPipe], edx, ecx, 4, usb_hub_status, eax, 0 - jmp .nothing -.no_hub_change: -; 6. Find the first port with changed state and clear the corresponding bit -; (so next scan after .restart will not consider this port again). -; If found, go to 8. Otherwise, advance to 7. - inc ecx -.test_port_change: - btr [edx], ecx - jc .found_port_change - inc ecx - cmp ecx, [eax+usb_hub.NumPorts] - jbe .test_port_change -.continue: -; 7. All changes have been processed. Wait for next notification. - call usb_hub_wait_change -.nothing: - ret -.found_port_change: - mov dword [eax+usb_hub.ChangeConfigBuffer+4], ecx -.next_port_change: -; 8. Query port state. Continue work in usb_hub_port_status callback. -; movzx ecx, [eax+usb_hub.ChangeConfigBuffer+4] -; dec ecx -; DEBUGF 1,'K : [%d] querying status of hub %x port %d\n',[timer_ticks],eax,ecx - lea edx, [eax+usb_hub.ChangeConfigBuffer] - mov dword [edx], 0A3h + \ ; class-specific request from hub port - (USB_GET_STATUS shl 8) - mov byte [edx+6], 4 ; data length = 4 bytes - lea ecx, [eax+usb_hub.StatusData] - stdcall usb_control_async, [eax+usb_hub.ConfigPipe], edx, ecx, 4, usb_hub_port_status, eax, 0 - jmp .nothing -.failed: - cmp [status], USB_STATUS_CLOSED - jz .nothing - dbgstr 'Querying hub notification failed' - jmp .nothing -endp - -; This procedure is called when the request of hub status is completed, -; either successfully or unsuccessfully. -proc usb_hub_status stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword -; 1. Check whether our request has failed. -; If so, say something to the debug board and stop processing notifications. - cmp [status], 0 - jnz .failed -; 2. Accumulate observed changes. - mov eax, [calldata] - mov dl, byte [eax+usb_hub.StatusChange] - or [eax+usb_hub.AccStatusChange], dl -.next_change: -; 3. Find the first change. If found, advance to 4. Otherwise, go to 5. - mov cl, C_HUB_OVER_CURRENT - btr dword [eax+usb_hub.StatusChange], 1 - jc .clear_hub_change - mov cl, C_HUB_LOCAL_POWER - btr dword [eax+usb_hub.StatusChange], 0 - jnc .final -.clear_hub_change: -; 4. Clear the change and continue in usb_hub_change_cleared callback. - lea edx, [eax+usb_hub.ChangeConfigBuffer] - mov dword [edx], 20h + \ ; class-specific request to hub itself - (USB_CLEAR_FEATURE shl 8) - mov [edx+2], cl ; feature selector - and dword [edx+4], 0 - stdcall usb_control_async, [eax+usb_hub.ConfigPipe], edx, 0, 0, usb_hub_change_cleared, eax, 0 -.nothing: - ret -.final: -; 5. All changes cleared and accumulated, now process them. -; Note: that needs work. - DEBUGF 1,'K : hub status %x\n',[eax+usb_hub.AccStatusChange]:2 - test [eax+usb_hub.AccStatusChange], 1 - jz .no_local_power - test [eax+usb_hub.StatusData], 1 - jz .local_power_lost - dbgstr 'Hub local power is now good' - jmp .no_local_power -.local_power_lost: - dbgstr 'Hub local power is now lost' -.no_local_power: - test [eax+usb_hub.AccStatusChange], 2 - jz .no_overcurrent - test [eax+usb_hub.StatusData], 2 - jz .no_overcurrent - dbgstr 'Hub global overcurrent' -.no_overcurrent: -; 6. Process possible changes for other ports. - jmp usb_hub_changed.restart -.failed: - dbgstr 'Querying hub status failed' - jmp .nothing -endp - -; This procedure is called when the request to clear hub change is completed, -; either successfully or unsuccessfully. -proc usb_hub_change_cleared stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword -; 1. Check whether our request has failed. -; If so, say something to the debug board and stop processing notifications. - cmp [status], 0 - jnz .failed -; 2. If there is a change which was observed, but not yet cleared, -; go to the code which clears it. - mov eax, [calldata] - cmp [eax+usb_hub.StatusChange], 0 - jnz usb_hub_status.next_change -; 3. Otherwise, go to the code which queries the status. - jmp usb_hub_changed.next_hub_change -.failed: - dbgstr 'Clearing hub change failed' - ret -endp - -; This procedure is called when the request of port status is completed, -; either successfully or unsuccessfully. -proc usb_hub_port_status stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword -; 1. Check whether our request has failed. -; If so, say something to the debug board and stop processing notifications. - cmp [status], 0 - jnz .failed -; 2. Accumulate observed changes. - mov eax, [calldata] -; movzx ecx, [eax+usb_hub.ChangeConfigBuffer+4] -; dec ecx -; DEBUGF 1,'K : [%d] hub %x port %d status %x change %x\n',[timer_ticks],eax,ecx,[eax+usb_hub.StatusData]:4,[eax+usb_hub.StatusChange]:4 - mov dl, byte [eax+usb_hub.StatusChange] - or [eax+usb_hub.AccStatusChange], dl -.next_change: -; 3. Find the first change. If found, advance to 4. Otherwise, go to 5. -; Ignore change in reset status; it is cleared by synchronous code -; (usb_hub_process_deferred), so avoid unnecessary interference. -; mov cl, C_PORT_RESET - btr dword [eax+usb_hub.StatusChange], PORT_RESET -; jc .clear_port_change - mov cl, C_PORT_OVER_CURRENT - btr dword [eax+usb_hub.StatusChange], PORT_OVER_CURRENT - jc .clear_port_change - mov cl, C_PORT_SUSPEND - btr dword [eax+usb_hub.StatusChange], PORT_SUSPEND - jc .clear_port_change - mov cl, C_PORT_ENABLE - btr dword [eax+usb_hub.StatusChange], PORT_ENABLE - jc .clear_port_change - mov cl, C_PORT_CONNECTION - btr dword [eax+usb_hub.StatusChange], PORT_CONNECTION - jnc .final -.clear_port_change: -; 4. Clear the change and continue in usb_hub_port_changed callback. - call usb_hub_clear_port_change - jmp .nothing -.final: -; All changes cleared and accumulated, now process them. - movzx ecx, byte [eax+usb_hub.ChangeConfigBuffer+4] - dec ecx - DEBUGF 1,'K : final: hub %x port %d status %x change %x\n',eax,ecx,[eax+usb_hub.StatusData]:4,[eax+usb_hub.AccStatusChange]:2 -; 5. Process connect/disconnect events. -; 5a. Test whether there is such event. - test byte [eax+usb_hub.AccStatusChange], 1 shl PORT_CONNECTION - jz .nodisconnect -; 5b. If there was a connected device, notify the main code about disconnect. - push ebx - mov edx, [eax+usb_hub.ConnectedDevicesPtr] - xor ebx, ebx - xchg ebx, [edx+ecx*4] - test ebx, ebx - jz @f - push eax ecx - call usb_device_disconnected - pop ecx eax -@@: - pop ebx -; 5c. If the disconnect event corresponds to the port which is currently -; resetting, then another request from synchronous code could be in the fly, -; so aborting reset immediately would lead to problems with those requests. -; Thus, just set the corresponding status and let the synchronous code process. - test byte [eax+usb_hub.Actions], (HUB_RESET_SIGNAL or HUB_RESET_RECOVERY) - jz @f - mov edx, [eax+usb_hub.Controller] - cmp [edx+usb_controller.ResettingPort], cl - jnz @f - mov [edx+usb_controller.ResettingStatus], -1 -@@: -; 5d. If the current status is 'connected', store the current time as connect -; time and set the corresponding bit for usb_hub_process_deferred. -; Otherwise, set connect time to -1. -; If current time is -1, pretend that the event occured one tick later and -; store zero. - mov edx, [eax+usb_hub.ConnectedTimePtr] - test byte [eax+usb_hub.StatusData], 1 shl PORT_CONNECTION - jz .disconnected - or [eax+usb_hub.Actions], HUB_WAIT_CONNECT - push eax - call usb_hub_store_connected_time - pop eax - jmp @f -.disconnected: - or dword [edx+ecx*4], -1 -@@: -.nodisconnect: -; 6. Process port disabling. - test [eax+usb_hub.AccStatusChange], 1 shl PORT_ENABLE - jz .nodisable - test byte [eax+usb_hub.StatusData], 1 shl PORT_ENABLE - jnz .nodisable -; Note: that needs work. - dbgstr 'Port disabled' -.nodisable: -; 7. Process port overcurrent. - test [eax+usb_hub.AccStatusChange], 1 shl PORT_OVER_CURRENT - jz .noovercurrent - test byte [eax+usb_hub.StatusData], 1 shl PORT_OVER_CURRENT - jz .noovercurrent -; Note: that needs work. - dbgstr 'Port over-current' -.noovercurrent: -; 8. Process possible changes for other ports. - jmp usb_hub_changed.restart -.failed: - dbgstr 'Querying port status failed' -.nothing: - ret -endp - -; Helper procedure to store current time in ConnectedTime, -; advancing -1 to zero if needed. -proc usb_hub_store_connected_time - mov eax, [timer_ticks] -; transform -1 to 0, leave other values as is - cmp eax, -1 - sbb eax, -1 - mov [edx+ecx*4], eax - ret -endp - -; Helper procedure for several parts of hub code. -; Sends a request to clear the given feature of the port. -; eax -> usb_hub, cl = feature; -; as is should be called from async code, sync code should set -; edx to ConfigBuffer and call usb_hub_clear_port_change.buffer; -; port number (1-based) should be filled in [edx+4] by previous requests. -proc usb_hub_clear_port_change - lea edx, [eax+usb_hub.ChangeConfigBuffer] -.buffer: -; push edx -; movzx edx, byte [edx+4] -; dec edx -; DEBUGF 1,'K : [%d] hub %x port %d clear feature %d\n',[timer_ticks],eax,edx,cl -; pop edx - mov dword [edx], 23h + \ ; class-specific request to hub port - (USB_CLEAR_FEATURE shl 8) - mov byte [edx+2], cl - and dword [edx+4], 0xFF - stdcall usb_control_async, [eax+usb_hub.ConfigPipe], edx, edx, 0, usb_hub_port_changed, eax, 0 - ret -endp - -; This procedure is called when the request to clear port change is completed, -; either successfully or unsuccessfully. -proc usb_hub_port_changed stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword -; 1. Check whether our request has failed. -; If so, say something to the debug board and stop processing notifications. - cmp [status], 0 - jnz .failed -; 2. If the request was originated by synchronous code, no further processing -; is required. - mov eax, [calldata] - lea edx, [eax+usb_hub.ConfigBuffer] - cmp [buffer], edx - jz .nothing -; 3. If there is a change which was observed, but not yet cleared, -; go to the code which clears it. - cmp [eax+usb_hub.StatusChange], 0 - jnz usb_hub_port_status.next_change -; 4. Otherwise, go to the code which queries the status. - jmp usb_hub_changed.next_port_change -.failed: - dbgstr 'Clearing port change failed' -.nothing: - ret -endp - -; This procedure is called in the USB thread from usb_thread_proc, -; contains synchronous code which should be activated at certain time -; (e.g. reset a recently connected device after debounce interval 100ms). -; Returns the number of ticks when it should be called next time. -proc usb_hub_process_deferred -; 1. Top-of-stack will contain return value; initialize to infinite timeout. - push -1 -; 2. If wait for stable power is active, then -; either reschedule wakeup (if time is not over) -; or start processing notifications. - test byte [esi+usb_hub.Actions], HUB_WAIT_POWERED - jz .no_powered - movzx eax, [esi+usb_hub.PowerOnInterval] -; three following instructions are equivalent to edx = ceil(eax / 5) + 1 -; 1 extra tick is added to make sure that the interval is at least as needed -; (it is possible that PoweredOnTime was set just before timer interrupt, and -; this test goes on just after timer interrupt) - add eax, 9 -; two following instructions are equivalent to edx = floor(eax / 5) -; for any 0 <= eax < 40000000h - mov ecx, 33333334h - mul ecx - mov eax, [timer_ticks] - sub eax, [esi+usb_hub.PoweredOnTime] - sub eax, edx - jge .powered_on - neg eax - pop ecx - push eax - jmp .no_powered -.powered_on: - and [esi+usb_hub.Actions], not HUB_WAIT_POWERED - mov eax, esi - call usb_hub_wait_change -.no_powered: -; 3. If reset is pending, check whether we can start it and start it, if so. - test byte [esi+usb_hub.Actions], HUB_RESET_WAITING - jz .no_wait_reset - mov eax, [esi+usb_hub.Controller] - cmp [eax+usb_controller.ResettingPort], -1 - jnz .no_wait_reset - call usb_hub_initiate_reset -.no_wait_reset: -; 4. If reset signalling is active, wait for end of reset signalling -; and schedule wakeup in 1 tick. - test byte [esi+usb_hub.Actions], HUB_RESET_SIGNAL - jz .no_resetting_port -; It has no sense to query status several times per tick. - mov eax, [timer_ticks] - cmp eax, [esi+usb_hub.ResetTime] - jz @f - mov [esi+usb_hub.ResetTime], eax - movzx ecx, byte [esi+usb_hub.ConfigBuffer+4] - mov eax, usb_hub_resetting_port_status - call usb_hub_query_port_status -@@: - pop eax - push 1 -.no_resetting_port: -; 5. If reset recovery is active and time is not over, reschedule wakeup. - test byte [esi+usb_hub.Actions], HUB_RESET_RECOVERY - jz .no_reset_recovery - mov eax, [timer_ticks] - sub eax, [esi+usb_hub.ResetTime] - sub eax, USB_RESET_RECOVERY_TIME - jge .reset_done - neg eax - cmp [esp], eax - jb @f - mov [esp], eax -@@: - jmp .no_reset_recovery -.reset_done: -; 6. If reset recovery is active and time is over, clear 'reset recovery' flag, -; notify other code about a new device and let it do further steps. -; If that fails, stop reset process for this port and disable that port. - and [esi+usb_hub.Actions], not HUB_RESET_RECOVERY -; Bits 9-10 of port status encode port speed. -; If PORT_LOW_SPEED is set, the device is low-speed. Otherwise, -; PORT_HIGH_SPEED bit distinguishes full-speed and high-speed devices. -; This corresponds to values of USB_SPEED_FS=0, USB_SPEED_LS=1, USB_SPEED_HS=2. - mov eax, dword [esi+usb_hub.ResetStatusData] - shr eax, PORT_LOW_SPEED - and eax, 3 - test al, 1 - jz @f - mov al, 1 -@@: -; movzx ecx, [esi+usb_hub.ConfigBuffer+4] -; dec ecx -; DEBUGF 1,'K : [%d] hub %x port %d speed %d\n',[timer_ticks],esi,ecx,eax - push esi - mov esi, [esi+usb_hub.Controller] - cmp [esi+usb_controller.ResettingStatus], -1 - jz .disconnected_while_reset - mov edx, [esi+usb_controller.HardwareFunc] - call [edx+usb_hardware_func.NewDevice] - pop esi - test eax, eax - jnz .no_reset_recovery - mov eax, esi - call usb_hub_disable_resetting_port - jmp .no_reset_recovery -.disconnected_while_reset: - pop esi - mov eax, esi - call usb_hub_reset_aborted -.no_reset_recovery: -; 7. Handle recent connection events. -; Note: that should be done after step 6, because step 6 can clear -; HUB_RESET_IN_PROGRESS flag. -; 7a. Test whether there is such an event pending. If no, skip this step. - test byte [esi+usb_hub.Actions], HUB_WAIT_CONNECT - jz .no_wait_connect -; 7b. If we have started reset process for another port in the same hub, -; skip this step: the buffer for config requests can be used for that port. - test byte [esi+usb_hub.Actions], HUB_RESET_IN_PROGRESS - jnz .no_wait_connect -; 7c. Clear flag 'there are connection events which should be processed'. -; If there are another connection events, this flag will be set again. - and [esi+usb_hub.Actions], not HUB_WAIT_CONNECT -; 7d. Prepare for loop over all ports. - xor ecx, ecx -.test_wait_connect: -; 7e. For every port test for recent connection event. -; If none, continue the loop for the next port. - mov edx, [esi+usb_hub.ConnectedTimePtr] - mov eax, [edx+ecx*4] - cmp eax, -1 - jz .next_wait_connect - or [esi+usb_hub.Actions], HUB_WAIT_CONNECT -; 7f. Test whether initial delay is over. - sub eax, [timer_ticks] - neg eax - sub eax, USB_CONNECT_DELAY - jge .connect_delay_over -; 7g. The initial delay is not over; -; set the corresponding flag again, reschedule wakeup and continue the loop. - neg eax - cmp [esp], eax - jb @f - mov [esp], eax -@@: - jmp .next_wait_connect -.connect_delay_over: -; The initial delay is over. -; It is possible that there was disconnect event during that delay, probably -; with connect event after that. If so, we should restart the waiting. However, -; on the hardware level connect/disconnect events from hubs are implemented -; using polling with interval selected by the hub, so it is possible that -; we have not yet observed that disconnect event. -; Thus, we query port status+change data before all further processing. -; 7h. Send the request for status+change data. - push ecx -; Hub requests expect 1-based port number, not zero-based we operate with. - inc ecx - mov eax, usb_hub_connect_port_status - call usb_hub_query_port_status - pop ecx -; 3i. If request has been submitted successfully, set the flag -; 'reset in progress, config buffer is owned by reset process' and break -; from the loop. - test eax, eax - jz .next_wait_connect - or [esi+usb_hub.Actions], HUB_RESET_IN_PROGRESS - jmp .no_wait_connect -.next_wait_connect: -; 7j. Continue the loop for next port. - inc ecx - cmp ecx, [esi+usb_hub.NumPorts] - jb .test_wait_connect -.no_wait_connect: -; 8. Pop return value from top-of-stack and return. - pop eax - ret -endp - -; Helper procedure for other code. Called when reset process is aborted. -proc usb_hub_reset_aborted -; Clear 'reset in progress' flag and test for other devices which could be -; waiting for reset. - and [eax+usb_hub.Actions], not HUB_RESET_IN_PROGRESS - push esi - mov esi, [eax+usb_hub.Controller] - call usb_test_pending_port - pop esi - ret -endp - -; Helper procedure for usb_hub_process_deferred. -; Sends a request to query port status. -; esi -> usb_hub, eax = callback, ecx = 1-based port. -proc usb_hub_query_port_status -; dec ecx -; DEBUGF 1,'K : [%d] [main] hub %x port %d query status\n',[timer_ticks],esi,ecx -; inc ecx - add ecx, 4 shl 16 ; data length = 4 - lea edx, [esi+usb_hub.ConfigBuffer] - mov dword [edx], 0A3h + \ ; class-specific request from hub port - (USB_GET_STATUS shl 8) - mov dword [edx+4], ecx - lea ecx, [esi+usb_hub.ResetStatusData] - stdcall usb_control_async, [esi+usb_hub.ConfigPipe], edx, ecx, 4, eax, esi, 0 - ret -endp - -; This procedure is called when the request to query port status -; initiated by usb_hub_process_deferred for testing connection is completed, -; either successfully or unsuccessfully. -proc usb_hub_connect_port_status stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword - push esi ; save used register to be stdcall - mov eax, [calldata] - mov esi, [pipe] -; movzx ecx, [eax+usb_hub.ConfigBuffer+4] -; dec ecx -; DEBUGF 1,'K : [%d] [connect test] hub %x port %d status %x change %x\n',[timer_ticks],eax,ecx,[eax+usb_hub.ResetStatusData]:4,[eax+usb_hub.ResetStatusChange]:4 -; 1. In any case, clear 'reset in progress' flag. -; If everything is ok, it would be set again. - and [eax+usb_hub.Actions], not HUB_RESET_IN_PROGRESS -; 2. If the request has failed, stop reset process. - cmp [status], 0 - jnz .nothing - mov edx, [eax+usb_hub.ConnectedTimePtr] - movzx ecx, byte [eax+usb_hub.ConfigBuffer+4] - dec ecx -; 3. Test whether there was a disconnect event. - test byte [eax+usb_hub.ResetStatusChange], 1 shl PORT_CONNECTION - jz .reset -; 4. There was a disconnect event. -; There is another handler of connect/disconnect events, usb_hub_port_status. -; However, we do not know whether it has already processed this event -; or it will process it sometime later. -; If ConnectedTime is -1, then another handler has already run, -; there was no connection event, so just leave the value as -1. -; Otherwise, there are two possibilities: either another handler has not yet -; run (which is quite likely), or there was a connection event and the other -; handler has run exactly while our request was processed (otherwise our -; request would not been submitted; this is quite unlikely due to timing -; requirements, but not impossible). In this case, set ConnectedTime to the -; current time: in the likely case it prevents usb_hub_process_deferred from immediate -; issuing of another requests (which would be just waste of time); -; in the unlikely case it is still correct (although slightly increases -; the debounce interval). - cmp dword [edx+ecx*4], -1 - jz .nothing - call usb_hub_store_connected_time - jmp .nothing -.reset: -; 5. The device remained connected for the entire debounce interval; -; we can proceed with initialization. -; Clear connected time for this port and notify usb_hub_process_deferred that -; the new port is waiting for reset. - or dword [edx+ecx*4], -1 - or [eax+usb_hub.Actions], HUB_RESET_IN_PROGRESS + HUB_RESET_WAITING -.nothing: - pop esi ; restore used register to be stdcall - ret -endp - -; This procedure is called when the request to query port status -; initiated by usb_hub_process_deferred for testing reset status is completed, -; either successfully or unsuccessfully. -proc usb_hub_resetting_port_status stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword -; 1. If the request has failed, do nothing. - cmp [status], 0 - jnz .nothing -; 2. If reset signalling is still active, do nothing. - mov eax, [calldata] -; movzx ecx, [eax+usb_hub.ConfigBuffer+4] -; dec ecx -; DEBUGF 1,'K : hub %x port %d ResetStatusData = %x change = %x\n',eax,ecx,[eax+usb_hub.ResetStatusData]:4,[eax+usb_hub.ResetStatusChange]:4 - test byte [eax+usb_hub.ResetStatusData], 1 shl PORT_RESET - jnz .nothing -; 3. Store the current time to start reset recovery interval -; and clear 'reset signalling active' flag. - mov edx, [timer_ticks] - mov [eax+usb_hub.ResetTime], edx - and [eax+usb_hub.Actions], not HUB_RESET_SIGNAL -; 4. If the device has not been disconnected, set 'reset recovery active' bit. -; Otherwise, terminate reset process. - test byte [eax+usb_hub.ResetStatusChange], 1 shl PORT_CONNECTION - jnz .disconnected - or [eax+usb_hub.Actions], HUB_RESET_RECOVERY -.common: -; In any case, clear change of resetting status. - lea edx, [eax+usb_hub.ConfigBuffer] - mov cl, C_PORT_RESET - call usb_hub_clear_port_change.buffer -.nothing: - ret -.disconnected: - call usb_hub_reset_aborted - jmp .common -endp - -; Helper procedure for usb_hub_process_deferred. Initiates reset signalling -; on the current port (given by 1-based value [ConfigBuffer+4]). -; esi -> usb_hub, eax -> usb_controller -proc usb_hub_initiate_reset -; 1. Store hub+port data in the controller structure. - movzx ecx, [esi+usb_hub.ConfigBuffer+4] - dec ecx - mov [eax+usb_controller.ResettingPort], cl - mov [eax+usb_controller.ResettingHub], esi -; 2. Store the current time and set 'reset signalling active' flag. - mov eax, [timer_ticks] - mov [esi+usb_hub.ResetTime], eax - and [esi+usb_hub.Actions], not HUB_RESET_WAITING - or [esi+usb_hub.Actions], HUB_RESET_SIGNAL -; 3. Send request to the hub to initiate request signalling. - lea edx, [esi+usb_hub.ConfigBuffer] -; DEBUGF 1,'K : [%d] hub %x port %d initiate reset\n',[timer_ticks],esi,ecx - mov dword [edx], 23h + \ - (USB_SET_FEATURE shl 8) + \ - (PORT_RESET shl 16) - and dword [edx+4], 0xFF - stdcall usb_control_async, [esi+usb_hub.ConfigPipe], edx, 0, 0, usb_hub_reset_started, esi, 0 - test eax, eax - jnz @f - mov eax, esi - call usb_hub_reset_aborted -@@: - ret -endp - -; This procedure is called when the request to start reset signalling initiated -; by usb_hub_initiate_reset is completed, either successfully or unsuccessfully. -proc usb_hub_reset_started stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword -; If the request is successful, do nothing. -; Otherwise, clear 'reset signalling' flag and abort reset process. - mov eax, [calldata] -; movzx ecx, [eax+usb_hub.ConfigBuffer+4] -; dec ecx -; DEBUGF 1,'K : [%d] hub %x port %d reset started\n',[timer_ticks],eax,ecx - cmp [status], 0 - jz .nothing - and [eax+usb_hub.Actions], not HUB_RESET_SIGNAL - dbgstr 'Failed to reset hub port' - call usb_hub_reset_aborted -.nothing: - ret -endp - -; This procedure is called by the protocol layer if something has failed during -; initial stages of the configuration process, so the device should be disabled -; at hub level. -proc usb_hub_disable_resetting_port - and [eax+usb_hub.Actions], not HUB_RESET_IN_PROGRESS -; movzx ecx, [eax+usb_hub.ConfigBuffer+4] -; dec ecx -; DEBUGF 1,'K : [%d] hub %x port %d disable\n',[timer_ticks],eax,ecx - lea edx, [eax+usb_hub.ConfigBuffer] - mov cl, PORT_ENABLE - jmp usb_hub_clear_port_change.buffer -endp - -; This procedure is called when the hub is disconnected. -proc usb_hub_disconnect -virtual at esp - dd ? ; return address -.hubdata dd ? -end virtual -; 1. If the hub is disconnected during initial configuration, -; 1 is stored as hub data and there is nothing to do. - mov eax, [.hubdata] - cmp eax, 1 - jz .nothing -; 2. Remove the hub from the overall list. - mov ecx, [eax+usb_hub.Next] - mov edx, [eax+usb_hub.Prev] - mov [ecx+usb_hub.Prev], edx - mov [edx+usb_hub.Next], ecx -; 3. If some child is in reset process, abort reset. - push esi - mov esi, [eax+usb_hub.Controller] - cmp [esi+usb_controller.ResettingHub], eax - jnz @f - cmp [esi+usb_controller.ResettingPort], -1 - jz @f - push eax - call usb_test_pending_port - pop eax -@@: - pop esi -; 4. Loop over all children and notify other code that they were disconnected. - push ebx - xor ecx, ecx -.disconnect_children: - mov ebx, [eax+usb_hub.ConnectedDevicesPtr] - mov ebx, [ebx+ecx*4] - test ebx, ebx - jz @f - push eax ecx - call usb_device_disconnected - pop ecx eax -@@: - inc ecx - cmp ecx, [eax+usb_hub.NumPorts] - jb .disconnect_children -; 4. Free memory allocated for the hub data. - call free - pop ebx -.nothing: - retn 4 -endp - -; Helper function for USB2 scheduler. -; in: eax -> usb_hub -; out: ecx = TT think time for the hub in FS-bytes -proc usb_get_tt_think_time - movzx ecx, [eax+usb_hub.HubCharacteristics] - shr ecx, 5 - and ecx, 3 - inc ecx - ret -endp diff --git a/kernel/branches/Kolibri-F/bus/usb/init.inc b/kernel/branches/Kolibri-F/bus/usb/init.inc deleted file mode 100644 index b1ddf8012..000000000 --- a/kernel/branches/Kolibri-F/bus/usb/init.inc +++ /dev/null @@ -1,268 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; Initialization of the USB subsystem. -; Provides usb_init procedure, includes all needed files. - -; General notes: -; * There is one entry point for external kernel code: usb_init is called -; from initialization code and initializes USB subsystem. -; * There are several entry points for API; see the docs for description. -; * There are several functions which are called from controller-specific -; parts of USB subsystem. The most important is usb_new_device, -; which is called when a new device has been connected (over some time), -; has been reset and is ready to start configuring. -; * IRQ handlers are very restricted. They can not take any locks, -; since otherwise a deadlock is possible: imagine that a code has taken the -; lock and was interrupted by IRQ handler. Now IRQ handler would wait for -; releasing the lock, and a lock owner would wait for exiting IRQ handler -; to get the control. -; * Thus, there is the special USB thread which processes almost all activity. -; IRQ handlers do the minimal processing and wake this thread. -; * Also the USB thread wakes occasionally to process tasks which can be -; predicted without interrupts. These include e.g. a periodic roothub -; scanning in UHCI and initializing in USB_CONNECT_DELAY ticks -; after connecting a new device. -; * The main procedure of USB thread, usb_thread_proc, does all its work -; by querying usb_hardware_func.ProcessDeferred for every controller -; and usb_hub_process_deferred for every hub. -; ProcessDeferred does controller-specific actions and calculates the time -; when it should be invoked again, possibly infinite. -; usb_thread_proc selects the minimum from all times returned by -; ProcessDeferred and sleeps until this moment is reached or the thread -; is awakened by IRQ handler. - -iglobal -uhci_service_name: - db 'UHCI',0 -ohci_service_name: - db 'OHCI',0 -ehci_service_name: - db 'EHCI',0 -endg - -; Initializes the USB subsystem. -proc usb_init -; 1. Initialize all locks. - mov ecx, usb_controllers_list_mutex - call mutex_init -; 2. Kick off BIOS from all USB controllers, calling the corresponding function -; *hci_kickoff_bios. Also count USB controllers for the next step. -; Note: USB1 companion(s) must go before the corresponding EHCI controller, -; otherwise BIOS could see a device moving from EHCI to a companion; -; first, this always wastes time; -; second, some BIOSes are buggy, do not expect that move and try to refer to -; previously-assigned controller instead of actual; sometimes that leads to -; hangoff. -; Thus, process controllers in PCI order. - mov esi, pcidev_list - push 0 -.kickoff: - mov esi, [esi+PCIDEV.fd] - cmp esi, pcidev_list - jz .done_kickoff - cmp word [esi+PCIDEV.class+1], 0x0C03 - jnz .kickoff - mov ebx, uhci_service_name - cmp byte [esi+PCIDEV.class], 0x00 - jz .do_kickoff - mov ebx, ohci_service_name - cmp byte [esi+PCIDEV.class], 0x10 - jz .do_kickoff - mov ebx, ehci_service_name - cmp byte [esi+PCIDEV.class], 0x20 - jnz .kickoff -.do_kickoff: - inc dword [esp] - push ebx esi - stdcall get_service, ebx - pop esi ebx - test eax, eax - jz .driver_fail - mov edx, [eax+USBSRV.usb_func] - cmp [edx+usb_hardware_func.Version], USBHC_VERSION - jnz .driver_invalid - mov [esi+PCIDEV.owner], eax - call [edx+usb_hardware_func.BeforeInit] - jmp .kickoff -.driver_fail: - DEBUGF 1,'K : failed to load driver %s\n',ebx - jmp .kickoff -.driver_invalid: - DEBUGF 1,'K : driver %s has wrong version\n',ebx - jmp .kickoff -.done_kickoff: - pop eax -; 3. If no controllers were found, exit. -; Otherwise, run the USB thread. - test eax, eax - jz .nothing - call create_usb_thread - jz .nothing -; 4. Initialize all USB controllers, calling usb_init_controller for each. -; Note: USB1 companion(s) should go before the corresponding EHCI controller, -; although this is not strictly necessary (this way, a companion would not try -; to initialize high-speed device only to see a disconnect when EHCI takes -; control). -; Thus, process all EHCI controllers in the first loop, all USB1 controllers -; in the second loop. (One loop in reversed PCI order could also be used, -; but seems less natural.) -; 4a. Loop over all PCI devices, call usb_init_controller -; for all EHCI controllers. - mov eax, pcidev_list -.scan_ehci: - mov eax, [eax+PCIDEV.fd] - cmp eax, pcidev_list - jz .done_ehci - cmp [eax+PCIDEV.class], 0x0C0320 - jnz .scan_ehci - call usb_init_controller - jmp .scan_ehci -.done_ehci: -; 4b. Loop over all PCI devices, call usb_init_controller -; for all UHCI and OHCI controllers. - mov eax, pcidev_list -.scan_usb1: - mov eax, [eax+PCIDEV.fd] - cmp eax, pcidev_list - jz .done_usb1 - cmp [eax+PCIDEV.class], 0x0C0300 - jz @f - cmp [eax+PCIDEV.class], 0x0C0310 - jnz .scan_usb1 -@@: - call usb_init_controller - jmp .scan_usb1 -.done_usb1: -.nothing: - ret -endp - -uglobal -align 4 -usb_event dd ? -endg - -; Helper function for usb_init. Creates and initializes the USB thread. -proc create_usb_thread -; 1. Create the thread. - push edi - movi ebx, 1 - mov ecx, usb_thread_proc - xor edx, edx - call new_sys_threads - pop edi -; If failed, say something to the debug board and return with ZF set. - test eax, eax - jns @f - DEBUGF 1,'K : cannot create kernel thread for USB, error %d\n',eax -.clear: - xor eax, eax - jmp .nothing -@@: -; 2. Wait while the USB thread initializes itself. -@@: - call change_task - cmp [usb_event], 0 - jz @b -; 3. If initialization failed, the USB thread sets [usb_event] to -1. -; Return with ZF set or cleared corresponding to the result. - cmp [usb_event], -1 - jz .clear -.nothing: - ret -endp - -; Helper function for IRQ handlers. Wakes the USB thread if ebx is nonzero. -proc usb_wakeup_if_needed - test ebx, ebx - jz usb_wakeup.nothing -usb_wakeup: - xor edx, edx - mov eax, [usb_event] - mov ebx, [eax+EVENT.id] - xor esi, esi - call raise_event -.nothing: - ret -endp - -; Main loop of the USB thread. -proc usb_thread_proc -; 1. Initialize: create event to allow wakeup by interrupt handlers. - xor esi, esi - mov ecx, MANUAL_DESTROY - call create_event - test eax, eax - jnz @f -; If failed, set [usb_event] to -1 and terminate myself. - dbgstr 'cannot create event for USB thread' - or [usb_event], -1 - jmp syscall_end -@@: - mov [usb_event], eax - push -1 ; initial timeout: infinite -usb_thread_wait: -; 2. Main loop: wait for either wakeup event or timeout. - pop ecx ; get timeout - mov eax, [usb_event] - mov ebx, [eax+EVENT.id] - call wait_event_timeout - push -1 ; default timeout: infinite -; 3. Main loop: call worker functions of all controllers; -; if some function schedules wakeup in timeout less than the current value, -; replace that value with the returned timeout. - mov esi, usb_controllers_list -@@: - mov esi, [esi+usb_controller.Next] - cmp esi, usb_controllers_list - jz .controllers_done - mov eax, [esi+usb_controller.HardwareFunc] - call [eax+usb_hardware_func.ProcessDeferred] - cmp [esp], eax - jb @b - mov [esp], eax - jmp @b -.controllers_done: -; 4. Main loop: call hub worker function for all hubs, -; similarly calculating minimum of all returned timeouts. -; When done, continue to 2. - mov esi, usb_hubs_list -@@: - mov esi, [esi+usb_hub.Next] - cmp esi, usb_hubs_list - jz usb_thread_wait - call usb_hub_process_deferred - cmp [esp], eax - jb @b - mov [esp], eax - jmp @b -endp - -iglobal -align 4 -usb_controllers_list: - dd usb_controllers_list - dd usb_controllers_list -usb_hubs_list: - dd usb_hubs_list - dd usb_hubs_list -endg -uglobal -align 4 -usb_controllers_list_mutex MUTEX -endg - -include "memory.inc" -include "common.inc" -include "hccommon.inc" -include "pipe.inc" -include "protocol.inc" -include "hub.inc" diff --git a/kernel/branches/Kolibri-F/bus/usb/memory.inc b/kernel/branches/Kolibri-F/bus/usb/memory.inc deleted file mode 100644 index 1a68336ac..000000000 --- a/kernel/branches/Kolibri-F/bus/usb/memory.inc +++ /dev/null @@ -1,43 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; Memory management for USB structures. -; Protocol layer uses the common kernel heap malloc/free. -; Hardware layer has special requirements: -; * memory blocks should be properly aligned -; * memory blocks should not cross page boundary -; Hardware layer allocates fixed-size blocks. -; Thus, hardware layer uses the system slab allocator. - -; Helper procedure: translate physical address in ecx -; of some transfer descriptor to linear address. -; in: eax = address of first page -proc usb_td_to_virt -; Traverse all pages used for transfer descriptors, looking for the one -; with physical address as in ecx. -@@: - test eax, eax - jz .zero - push eax - call get_pg_addr - sub eax, ecx - jz .found - cmp eax, -0x1000 - ja .found - pop eax - mov eax, [eax+0x1000-4] - jmp @b -.found: -; When found, combine page address from eax with page offset from ecx. - pop eax - and ecx, 0xFFF - add eax, ecx -.zero: - ret -endp diff --git a/kernel/branches/Kolibri-F/bus/usb/pipe.inc b/kernel/branches/Kolibri-F/bus/usb/pipe.inc deleted file mode 100644 index 312594f4b..000000000 --- a/kernel/branches/Kolibri-F/bus/usb/pipe.inc +++ /dev/null @@ -1,860 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; Functions for USB pipe manipulation: opening/closing, sending data etc. -; -USB_STDCALL_VERIFY = 1 -macro stdcall_verify [arg] -{ -common -if USB_STDCALL_VERIFY - pushad - stdcall arg - call verify_regs - popad -else - stdcall arg -end if -} -if USB_STDCALL_VERIFY -STDCALL_VERIFY_EXTRA = 20h -else -STDCALL_VERIFY_EXTRA = 0 -end if - -; Initialization of usb_static_ep structure, -; called from controller-specific initialization; edi -> usb_static_ep -proc usb_init_static_endpoint - mov [edi+usb_static_ep.NextVirt], edi - mov [edi+usb_static_ep.PrevVirt], edi - ret -endp - -; Part of API for drivers, see documentation for USBOpenPipe. -proc usb_open_pipe stdcall uses ebx esi edi,\ - config_pipe:dword, endpoint:dword, maxpacket:dword, type:dword, interval:dword -locals -tt_vars rd 24 ; should be enough for ehci_select_tt_interrupt_list -targetsmask dd ? ; S-Mask for USB2 -bandwidth dd ? -target dd ? -endl -; 1. Verify type of pipe: it must be one of *_PIPE constants. -; Isochronous pipes are not supported yet. - mov eax, [type] - cmp eax, INTERRUPT_PIPE - ja .badtype - cmp al, ISOCHRONOUS_PIPE - jnz .goodtype -.badtype: - dbgstr 'unsupported type of USB pipe' - jmp .return0 -.goodtype: -; 2. Allocate memory for pipe and transfer queue. -; Empty transfer queue consists of one inactive TD. - mov ebx, [config_pipe] - mov esi, [ebx+usb_pipe.Controller] - mov edx, [esi+usb_controller.HardwareFunc] - call [edx+usb_hardware_func.AllocPipe] - test eax, eax - jz .nothing - mov edi, eax - mov edx, [esi+usb_controller.HardwareFunc] - call [edx+usb_hardware_func.AllocTD] - test eax, eax - jz .free_and_return0 -; 3. Initialize transfer queue: pointer to transfer descriptor, -; pointers in transfer descriptor, queue lock. - mov [edi+usb_pipe.LastTD], eax - mov [eax+usb_gtd.NextVirt], eax - mov [eax+usb_gtd.PrevVirt], eax - mov [eax+usb_gtd.Pipe], edi - lea ecx, [edi+usb_pipe.Lock] - call mutex_init -; 4. Initialize software part of pipe structure, except device-related fields. - mov al, byte [type] - mov [edi+usb_pipe.Type], al - xor eax, eax - mov [edi+usb_pipe.Flags], al - mov [edi+usb_pipe.DeviceData], eax - mov [edi+usb_pipe.Controller], esi - or [edi+usb_pipe.NextWait], -1 -; 5. Initialize device-related fields: -; for zero endpoint, set .NextSibling = .PrevSibling = this; -; for other endpoins, copy device data, take the lock guarding pipe list -; for the device and verify that disconnect processing has not yet started -; for the device. (Since disconnect processing also takes that lock, -; either it has completed or it will not start until we release the lock.) -; Note: usb_device_disconnected should not see the new pipe until -; initialization is complete, so that lock will be held during next steps -; (disconnect processing should either not see it at all, or see fully -; initialized pipe). - cmp [endpoint], eax - jz .zero_endpoint - mov ecx, [ebx+usb_pipe.DeviceData] - mov [edi+usb_pipe.DeviceData], ecx - call mutex_lock - test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED - jz .common -.fail: -; If disconnect processing has completed, unlock the mutex, free memory -; allocated in step 2 and return zero. - call mutex_unlock - mov edx, [esi+usb_controller.HardwareFunc] - stdcall [edx+usb_hardware_func.FreeTD], [edi+usb_pipe.LastTD] -.free_and_return0: - mov edx, [esi+usb_controller.HardwareFunc] - stdcall [edx+usb_hardware_func.FreePipe], edi -.return0: - xor eax, eax - jmp .nothing -.zero_endpoint: - mov [edi+usb_pipe.NextSibling], edi - mov [edi+usb_pipe.PrevSibling], edi -.common: -; 6. Initialize hardware part of pipe structure. -; 6a. Acquire the corresponding mutex. - lea ecx, [esi+usb_controller.ControlLock] - cmp [type], BULK_PIPE - jb @f ; control pipe - lea ecx, [esi+usb_controller.BulkLock] - jz @f ; bulk pipe - lea ecx, [esi+usb_controller.PeriodicLock] -@@: - call mutex_lock -; 6b. Let the controller-specific code do its job. - push ecx - mov edx, [esi+usb_controller.HardwareFunc] - mov eax, [edi+usb_pipe.LastTD] - mov ecx, [config_pipe] - call [edx+usb_hardware_func.InitPipe] - pop ecx -; 6c. Release the mutex. - push eax - call mutex_unlock - pop eax -; 6d. If controller-specific code indicates failure, -; release the lock taken in step 5, free memory allocated in step 2 -; and return zero. - test eax, eax - jz .fail -; 7. The pipe is initialized. If this is not the first pipe for the device, -; insert it to the tail of pipe list for the device, -; increment number of pipes, -; release the lock taken at step 5. - mov ecx, [edi+usb_pipe.DeviceData] - test ecx, ecx - jz @f - mov eax, [ebx+usb_pipe.PrevSibling] - mov [edi+usb_pipe.NextSibling], ebx - mov [edi+usb_pipe.PrevSibling], eax - mov [ebx+usb_pipe.PrevSibling], edi - mov [eax+usb_pipe.NextSibling], edi - inc [ecx+usb_device_data.NumPipes] - call mutex_unlock -@@: -; 8. Return pointer to usb_pipe. - mov eax, edi -.nothing: - ret -endp - -; This procedure is called several times during initial device configuration, -; when usb_device_data structure is reallocated. -; It (re)initializes all pointers in usb_device_data. -; ebx -> usb_pipe -proc usb_reinit_pipe_list - push eax -; 1. (Re)initialize the lock guarding pipe list. - mov ecx, [ebx+usb_pipe.DeviceData] - call mutex_init -; 2. Initialize list of opened pipes: two entries, the head and ebx. - add ecx, usb_device_data.OpenedPipeList - usb_pipe.NextSibling - mov [ecx+usb_pipe.NextSibling], ebx - mov [ecx+usb_pipe.PrevSibling], ebx - mov [ebx+usb_pipe.NextSibling], ecx - mov [ebx+usb_pipe.PrevSibling], ecx -; 3. Initialize list of closed pipes: empty list, only the head is present. - add ecx, usb_device_data.ClosedPipeList - usb_device_data.OpenedPipeList - mov [ecx+usb_pipe.NextSibling], ecx - mov [ecx+usb_pipe.PrevSibling], ecx - pop eax - ret -endp - -; Part of API for drivers, see documentation for USBClosePipe. -proc usb_close_pipe - push ebx esi ; save used registers to be stdcall -virtual at esp - rd 2 ; saved registers - dd ? ; return address -.pipe dd ? -end virtual -; 1. Lock the pipe list for the device. - mov ebx, [.pipe] - mov esi, [ebx+usb_pipe.Controller] - mov ecx, [ebx+usb_pipe.DeviceData] - call mutex_lock -; 2. Set the flag "the driver has abandoned this pipe, free it at any time". - lea ecx, [ebx+usb_pipe.Lock] - call mutex_lock - or [ebx+usb_pipe.Flags], USB_FLAG_CAN_FREE - call mutex_unlock -; 3. Call the worker function. - call usb_close_pipe_nolock -; 4. Unlock the pipe list for the device. - mov ecx, [ebx+usb_pipe.DeviceData] - call mutex_unlock -; 5. Wakeup the USB thread so that it can proceed with releasing that pipe. - push edi - call usb_wakeup - pop edi -; 6. Return. - pop esi ebx ; restore used registers to be stdcall - retn 4 -endp - -; Worker function for pipe closing. Called by usb_close_pipe API and -; from disconnect processing. -; The lock guarding pipe list for the device should be held by the caller. -; ebx -> usb_pipe, esi -> usb_controller -proc usb_close_pipe_nolock -; 1. Set the flag "pipe is closed, ignore new transfers". -; If it was already set, do nothing. - lea ecx, [ebx+usb_pipe.Lock] - call mutex_lock - bts dword [ebx+usb_pipe.Flags], USB_FLAG_CLOSED_BIT - jc .closed - call mutex_unlock -; 2. Remove the pipe from the list of opened pipes. - mov eax, [ebx+usb_pipe.NextSibling] - mov edx, [ebx+usb_pipe.PrevSibling] - mov [eax+usb_pipe.PrevSibling], edx - mov [edx+usb_pipe.NextSibling], eax -; 3. Unlink the pipe from hardware structures. -; 3a. Acquire the corresponding lock. - lea edx, [esi+usb_controller.WaitPipeListAsync] - lea ecx, [esi+usb_controller.ControlLock] - cmp [ebx+usb_pipe.Type], BULK_PIPE - jb @f ; control pipe - lea ecx, [esi+usb_controller.BulkLock] - jz @f ; bulk pipe - add edx, usb_controller.WaitPipeListPeriodic - usb_controller.WaitPipeListAsync - lea ecx, [esi+usb_controller.PeriodicLock] -@@: - push edx - call mutex_lock - push ecx -; 3b. Let the controller-specific code do its job. - test [ebx+usb_pipe.Flags], USB_FLAG_DISABLED - jnz @f - mov eax, [esi+usb_controller.HardwareFunc] - call [eax+usb_hardware_func.DisablePipe] -@@: - mov eax, [esi+usb_controller.HardwareFunc] - call [eax+usb_hardware_func.UnlinkPipe] - mov edx, [ebx+usb_pipe.NextVirt] - mov eax, [ebx+usb_pipe.PrevVirt] - mov [edx+usb_pipe.PrevVirt], eax - mov [eax+usb_pipe.NextVirt], edx -; 3c. Release the corresponding lock. - pop ecx - call mutex_unlock -; 4. Put the pipe into wait queue. - pop edx - cmp [ebx+usb_pipe.NextWait], -1 - jz .insert_new - or [ebx+usb_pipe.Flags], USB_FLAG_EXTRA_WAIT - jmp .inserted -.insert_new: - mov eax, [edx] - mov [ebx+usb_pipe.NextWait], eax - mov [edx], ebx -.inserted: -; 5. Return. - ret -.closed: - call mutex_unlock - xor eax, eax - ret -endp - -; This procedure is called when all transfers are aborted -; either due to call to usb_abort_pipe or due to pipe closing. -; It notifies all callbacks and frees all transfer descriptors. -; ebx -> usb_pipe, esi -> usb_controller, edi -> usb_hardware_func -; three stack parameters: status code for callback functions -; and descriptors where to start and stop. -proc usb_pipe_aborted -virtual at esp - dd ? ; return address -.status dd ? ; USB_STATUS_CLOSED or USB_STATUS_CANCELLED -.first_td dd ? -.last_td dd ? -end virtual -; Loop over all transfers, calling the driver with the given status -; and freeing all descriptors except the last one. -.loop: - mov edx, [.first_td] - cmp edx, [.last_td] - jz .done - mov ecx, [edx+usb_gtd.Callback] - test ecx, ecx - jz .no_callback - stdcall_verify ecx, ebx, [.status+12+STDCALL_VERIFY_EXTRA], \ - [edx+usb_gtd.Buffer], 0, [edx+usb_gtd.UserData] - mov edx, [.first_td] -.no_callback: - mov eax, [edx+usb_gtd.NextVirt] - mov [.first_td], eax - stdcall [edi+usb_hardware_func.FreeTD], edx - jmp .loop -.done: - ret 12 -endp - -; This procedure is called when a pipe with USB_FLAG_CLOSED is removed from the -; corresponding wait list. It means that the hardware has fully forgot about it. -; ebx -> usb_pipe, esi -> usb_controller -proc usb_pipe_closed - push edi - mov edi, [esi+usb_controller.HardwareFunc] -; 1. Notify all registered callbacks with status USB_STATUS_CLOSED, if any, -; and free all transfer descriptors, including the last one. - lea ecx, [ebx+usb_pipe.Lock] - call mutex_lock - mov edx, [ebx+usb_pipe.LastTD] - test edx, edx - jz .no_transfer - mov eax, [edx+usb_gtd.NextVirt] - push edx - push eax - call mutex_unlock - push USB_STATUS_CLOSED - call usb_pipe_aborted -; It is safe to free LastTD here: -; usb_*_transfer_async do not enqueue new transfers if USB_FLAG_CLOSED is set. - stdcall [edi+usb_hardware_func.FreeTD], [ebx+usb_pipe.LastTD] - jmp @f -.no_transfer: - call mutex_unlock -@@: -; 2. Decrement number of pipes for the device. -; If this pipe is the last pipe, go to 5. - mov ecx, [ebx+usb_pipe.DeviceData] - call mutex_lock - dec [ecx+usb_device_data.NumPipes] - jz .last_pipe - call mutex_unlock -; 3. If the flag "the driver has abandoned this pipe" is set, -; free memory and return. - test [ebx+usb_pipe.Flags], USB_FLAG_CAN_FREE - jz .nofree - stdcall [edi+usb_hardware_func.FreePipe], ebx - pop edi - ret -; 4. Otherwise, add it to the list of closed pipes and return. -.nofree: - add ecx, usb_device_data.ClosedPipeList - usb_pipe.NextSibling - mov edx, [ecx+usb_pipe.PrevSibling] - mov [ebx+usb_pipe.NextSibling], ecx - mov [ebx+usb_pipe.PrevSibling], edx - mov [ecx+usb_pipe.PrevSibling], ebx - mov [edx+usb_pipe.NextSibling], ebx - pop edi - ret -.last_pipe: -; That was the last pipe for the device. -; 5. Notify device driver(s) about disconnect. - call mutex_unlock - mov eax, [ecx+usb_device_data.NumInterfaces] - test eax, eax - jz .notify_done - add ecx, [ecx+usb_device_data.Interfaces] -.notify_loop: - mov edx, [ecx+usb_interface_data.DriverFunc] - test edx, edx - jz @f - mov edx, [edx+USBSRV.usb_func] - cmp [edx+USBFUNC.strucsize], USBFUNC.device_disconnect + 4 - jb @f - mov edx, [edx+USBFUNC.device_disconnect] - test edx, edx - jz @f - push eax ecx - stdcall_verify edx, [ecx+usb_interface_data.DriverData] - pop ecx eax -@@: - add ecx, sizeof.usb_interface_data - dec eax - jnz .notify_loop -.notify_done: -; 6. Kill the timer, if active. -; (Usually not; possible if device is disconnected -; while processing SET_ADDRESS request). - mov eax, [ebx+usb_pipe.DeviceData] - cmp [eax+usb_device_data.Timer], 0 - jz @f - stdcall cancel_timer_hs, [eax+usb_device_data.Timer] - mov [eax+usb_device_data.Timer], 0 -@@: -; 7. Bus address, if assigned, can now be reused. - call [edi+usb_hardware_func.GetDeviceAddress] - test eax, eax - jz @f - bts [esi+usb_controller.ExistingAddresses], eax -@@: - dbgstr 'USB device disconnected' -; 8. All drivers have returned from disconnect callback, -; so all drivers should not use any device-related pipes. -; Free the remaining pipes. - mov eax, [ebx+usb_pipe.DeviceData] - add eax, usb_device_data.ClosedPipeList - usb_pipe.NextSibling - push eax - mov eax, [eax+usb_pipe.NextSibling] -.free_loop: - cmp eax, [esp] - jz .free_done - push [eax+usb_pipe.NextSibling] - stdcall [edi+usb_hardware_func.FreePipe], eax - pop eax - jmp .free_loop -.free_done: - stdcall [edi+usb_hardware_func.FreePipe], ebx - pop eax -; 9. Free the usb_device_data structure. - sub eax, usb_device_data.ClosedPipeList - usb_pipe.NextSibling - call free -; 10. Return. -.nothing: - pop edi - ret -endp - -; This procedure is called when a pipe with USB_FLAG_DISABLED is removed from the -; corresponding wait list. It means that the hardware has fully forgot about it. -; ebx -> usb_pipe, esi -> usb_controller -proc usb_pipe_disabled - push edi - mov edi, [esi+usb_controller.HardwareFunc] -; 1. Acquire pipe lock. - lea ecx, [ebx+usb_pipe.Lock] - call mutex_lock -; 2. Clear USB_FLAG_DISABLED in pipe state. - and [ebx+usb_pipe.Flags], not USB_FLAG_DISABLED -; 3. Sanity check: ignore uninitialized pipes. - cmp [ebx+usb_pipe.LastTD], 0 - jz .no_transfer -; 4. Acquire the first and last to-be-cancelled transfer descriptor, -; save them in stack for the step 6, -; ask the controller driver to enable the pipe for hardware, -; removing transfers between first and last to-be-cancelled descriptors. - lea ecx, [esi+usb_controller.ControlLock] - cmp [ebx+usb_pipe.Type], BULK_PIPE - jb @f ; control pipe - lea ecx, [esi+usb_controller.BulkLock] - jz @f ; bulk pipe - lea ecx, [esi+usb_controller.PeriodicLock] -@@: - call mutex_lock - mov eax, [ebx+usb_pipe.BaseList] - mov edx, [eax+usb_pipe.NextVirt] - mov [ebx+usb_pipe.NextVirt], edx - mov [ebx+usb_pipe.PrevVirt], eax - mov [edx+usb_pipe.PrevVirt], ebx - mov [eax+usb_pipe.NextVirt], ebx - mov eax, [ebx+usb_pipe.LastTD] - mov edx, [eax+usb_gtd.NextVirt] - mov [eax+usb_gtd.NextVirt], eax - mov [eax+usb_gtd.PrevVirt], eax - push eax - push edx - push ecx - call [edi+usb_hardware_func.EnablePipe] - pop ecx - call mutex_unlock -; 5. Release pipe lock acquired at step 1. -; Callbacks called at step 6 can insert new transfers, -; so we cannot call usb_pipe_aborted while holding pipe lock. - lea ecx, [ebx+usb_pipe.Lock] - call mutex_unlock -; 6. Notify all registered callbacks with status USB_STATUS_CANCELLED, if any. -; Two arguments describing transfers range were pushed at step 4. - push USB_STATUS_CANCELLED - call usb_pipe_aborted - pop edi - ret -.no_transfer: - call mutex_unlock - pop edi - ret -endp - -; Part of API for drivers, see documentation for USBNormalTransferAsync. -proc usb_normal_transfer_async stdcall uses ebx edi,\ - pipe:dword, buffer:dword, size:dword, callback:dword, calldata:dword, flags:dword -; 1. Sanity check: callback must be nonzero. -; (It is important for other parts of code.) - xor eax, eax - cmp [callback], eax - jz .nothing -; 2. Lock the transfer queue. - mov ebx, [pipe] - lea ecx, [ebx+usb_pipe.Lock] - call mutex_lock -; 3. If the pipe has already been closed (presumably due to device disconnect), -; release the lock taken in step 2 and return zero. - xor eax, eax - test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED - jnz .unlock -; 4. Allocate and initialize TDs for the transfer. - mov edx, [ebx+usb_pipe.Controller] - mov edi, [edx+usb_controller.HardwareFunc] - stdcall [edi+usb_hardware_func.AllocTransfer], [buffer], [size], [flags], [ebx+usb_pipe.LastTD], 0 -; If failed, release the lock taken in step 2 and return zero. - test eax, eax - jz .unlock -; 5. Store callback and its parameters in the last descriptor for this transfer. - mov ecx, [eax+usb_gtd.PrevVirt] - mov edx, [callback] - mov [ecx+usb_gtd.Callback], edx - mov edx, [calldata] - mov [ecx+usb_gtd.UserData], edx - mov edx, [buffer] - mov [ecx+usb_gtd.Buffer], edx -; 6. Advance LastTD pointer and activate transfer. - push [ebx+usb_pipe.LastTD] - mov [ebx+usb_pipe.LastTD], eax - call [edi+usb_hardware_func.InsertTransfer] - pop eax -; 7. Release the lock taken in step 2 and -; return pointer to the first descriptor for the new transfer. -.unlock: - push eax - lea ecx, [ebx+usb_pipe.Lock] - call mutex_unlock - pop eax -.nothing: - ret -endp - -; Part of API for drivers, see documentation for USBControlTransferAsync. -proc usb_control_async stdcall uses ebx edi,\ - pipe:dword, config:dword, buffer:dword, size:dword, callback:dword, calldata:dword, flags:dword -locals -last_td dd ? -endl -; 1. Sanity check: callback must be nonzero. -; (It is important for other parts of code.) - cmp [callback], 0 - jz .return0 -; 2. Lock the transfer queue. - mov ebx, [pipe] - lea ecx, [ebx+usb_pipe.Lock] - call mutex_lock -; 3. If the pipe has already been closed (presumably due to device disconnect), -; release the lock taken in step 2 and return zero. - test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED - jnz .unlock_return0 -; A control transfer contains two or three stages: -; Setup stage, optional Data stage, Status stage. -; 4. Allocate and initialize TDs for the Setup stage. -; Payload is 8 bytes from [config]. - mov edx, [ebx+usb_pipe.Controller] - mov edi, [edx+usb_controller.HardwareFunc] - stdcall [edi+usb_hardware_func.AllocTransfer], [config], 8, 0, [ebx+usb_pipe.LastTD], (2 shl 2) + 0 - ; short transfer is an error, direction is DATA0, token is SETUP - mov [last_td], eax - test eax, eax - jz .fail -; 5. Allocate and initialize TDs for the Data stage, if [size] is nonzero. -; Payload is [size] bytes from [buffer]. - mov edx, [config] - mov ecx, (3 shl 2) + 1 ; DATA1, token is OUT - cmp byte [edx], 0 - jns @f - cmp [size], 0 - jz @f - inc ecx ; token is IN -@@: - cmp [size], 0 - jz .nodata - push ecx - stdcall [edi+usb_hardware_func.AllocTransfer], [buffer], [size], [flags], eax, ecx - pop ecx - test eax, eax - jz .fail - mov [last_td], eax -.nodata: -; 6. Allocate and initialize TDs for the Status stage. -; No payload. - xor ecx, 3 ; IN becomes OUT, OUT becomes IN - stdcall [edi+usb_hardware_func.AllocTransfer], 0, 0, 0, eax, ecx - test eax, eax - jz .fail -; 7. Store callback and its parameters in the last descriptor for this transfer. - mov ecx, [eax+usb_gtd.PrevVirt] - mov edx, [callback] - mov [ecx+usb_gtd.Callback], edx - mov edx, [calldata] - mov [ecx+usb_gtd.UserData], edx - mov edx, [buffer] - mov [ecx+usb_gtd.Buffer], edx -; 8. Advance LastTD pointer and activate transfer. - push [ebx+usb_pipe.LastTD] - mov [ebx+usb_pipe.LastTD], eax - call [edi+usb_hardware_func.InsertTransfer] -; 9. Release the lock taken in step 2 and -; return pointer to the first descriptor for the new transfer. - lea ecx, [ebx+usb_pipe.Lock] - call mutex_unlock - pop eax - ret -.fail: - mov eax, [last_td] - test eax, eax - jz .unlock_return0 - stdcall usb_undo_tds, [ebx+usb_pipe.LastTD] -.unlock_return0: - lea ecx, [ebx+usb_pipe.Lock] - call mutex_unlock -.return0: - xor eax, eax - ret -endp - -; Part of API for drivers, see documentation for USBAbortPipe. -proc usb_abort_pipe - push ebx esi ; save used registers to be stdcall -virtual at esp - rd 2 ; saved registers - dd ? ; return address -.pipe dd ? -end virtual - mov ebx, [.pipe] -; 1. Acquire pipe lock. - lea ecx, [ebx+usb_pipe.Lock] - call mutex_lock -; 2. If the pipe is already closed or abort is in progress, -; just release pipe lock and return. - test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED + USB_FLAG_DISABLED - jnz .nothing -; 3. Mark the pipe as aborting. - or [ebx+usb_pipe.Flags], USB_FLAG_DISABLED -; 4. We cannot do anything except adding new transfers concurrently with hardware. -; Ask the controller driver to (temporarily) remove the pipe from hardware queue. - mov esi, [ebx+usb_pipe.Controller] -; 4a. Acquire queue lock. - lea ecx, [esi+usb_controller.ControlLock] - cmp [ebx+usb_pipe.Type], BULK_PIPE - jb @f ; control pipe - lea ecx, [esi+usb_controller.BulkLock] - jz @f ; bulk pipe - lea ecx, [esi+usb_controller.PeriodicLock] -@@: - call mutex_lock - push ecx -; 4b. Call the driver. - mov eax, [esi+usb_controller.HardwareFunc] - call [eax+usb_hardware_func.DisablePipe] -; 4c. Remove the pipe from software list. - mov eax, [ebx+usb_pipe.NextVirt] - mov edx, [ebx+usb_pipe.PrevVirt] - mov [eax+usb_pipe.PrevVirt], edx - mov [edx+usb_pipe.NextVirt], eax -; 4c. Register the pipe in corresponding wait list. - test [ebx+usb_pipe.Type], 1 - jz .control_bulk - call usb_subscribe_periodic - jmp @f -.control_bulk: - call usb_subscribe_control -@@: -; 4d. Release queue lock. - pop ecx - call mutex_unlock -; 4e. Notify the USB thread about new work. - push ebx esi edi - call usb_wakeup - pop edi esi ebx -; That's all for now. To be continued in usb_pipe_disabled. -; 5. Release pipe lock acquired at step 1 and return. -.nothing: - lea ecx, [ebx+usb_pipe.Lock] - call mutex_unlock - pop esi ebx - ret 4 -endp - -; Part of API for drivers, see documentation for USBGetParam. -proc usb_get_param -virtual at esp - dd ? ; return address -.pipe dd ? -.param dd ? -end virtual - mov edx, [.param] - mov ecx, [.pipe] - mov eax, [ecx+usb_pipe.DeviceData] - test edx, edx - jz .get_device_descriptor - dec edx - jz .get_config_descriptor - dec edx - jz .get_speed - or eax, -1 - ret 8 -.get_device_descriptor: - add eax, usb_device_data.DeviceDescriptor - ret 8 -.get_config_descriptor: - movzx ecx, [eax+usb_device_data.DeviceDescrSize] - lea eax, [eax+ecx+usb_device_data.DeviceDescriptor] - ret 8 -.get_speed: - movzx eax, [eax+usb_device_data.Speed] - ret 8 -endp - -; Initialize software part of usb_gtd. Called from controller-specific code -; somewhere in AllocTransfer with eax -> next (inactive) usb_gtd, -; ebx -> usb_pipe, ebp frame from call to AllocTransfer with [.td] -> -; current (initializing) usb_gtd. -; Returns ecx = [.td]. -proc usb_init_transfer -virtual at ebp-4 -.Size dd ? - rd 2 -.Buffer dd ? - dd ? -.Flags dd ? -.td dd ? -end virtual - mov [eax+usb_gtd.Pipe], ebx - mov ecx, [.td] - mov [eax+usb_gtd.PrevVirt], ecx - mov edx, [ecx+usb_gtd.NextVirt] - mov [ecx+usb_gtd.NextVirt], eax - mov [eax+usb_gtd.NextVirt], edx - mov [edx+usb_gtd.PrevVirt], eax - mov edx, [.Size] - mov [ecx+usb_gtd.Length], edx - xor edx, edx - mov [ecx+usb_gtd.Callback], edx - mov [ecx+usb_gtd.UserData], edx - ret -endp - -; Free all TDs for the current transfer if something has failed -; during initialization (e.g. no memory for the next TD). -; Stdcall with one stack argument = first TD for the transfer -; and eax = last initialized TD for the transfer. -proc usb_undo_tds - push [eax+usb_gtd.NextVirt] -@@: - cmp eax, [esp+8] - jz @f - push [eax+usb_gtd.PrevVirt] - stdcall [edi+usb_hardware_func.FreeTD], eax - pop eax - jmp @b -@@: - pop ecx - mov [eax+usb_gtd.NextVirt], ecx - mov [ecx+usb_gtd.PrevVirt], eax - ret 4 -endp - -; Helper procedure for handling short packets in controller-specific code. -; Returns with CF cleared if this is the final packet in some stage: -; for control transfers that means one of Data and Status stages, -; for other transfers - the final packet in the only stage. -proc usb_is_final_packet - cmp [ebx+usb_gtd.Callback], 0 - jnz .nothing - mov eax, [ebx+usb_gtd.NextVirt] - cmp [eax+usb_gtd.Callback], 0 - jz .stc - mov eax, [ebx+usb_gtd.Pipe] - cmp [eax+usb_pipe.Type], CONTROL_PIPE - jz .nothing -.stc: - stc -.nothing: - ret -endp - -; Helper procedure for controller-specific code: -; removes one TD from the transfer queue, ebx -> usb_gtd to remove. -proc usb_unlink_td - mov ecx, [ebx+usb_gtd.Pipe] - add ecx, usb_pipe.Lock - call mutex_lock - mov eax, [ebx+usb_gtd.PrevVirt] - mov edx, [ebx+usb_gtd.NextVirt] - mov [edx+usb_gtd.PrevVirt], eax - mov [eax+usb_gtd.NextVirt], edx - call mutex_unlock - ret -endp - -; One part of transfer is completed, run the associated callback -; or update total length in the next part of transfer. -; in: ebx -> usb_gtd, ecx = status, edx = length -proc usb_process_gtd -; 1. Test whether it is the last descriptor in the transfer -; <=> it has an associated callback. - mov eax, [ebx+usb_gtd.Callback] - test eax, eax - jz .nocallback -; 2. It has an associated callback; call it with corresponding parameters. - stdcall_verify eax, [ebx+usb_gtd.Pipe], ecx, \ - [ebx+usb_gtd.Buffer], edx, [ebx+usb_gtd.UserData] - ret -.nocallback: -; 3. It is an intermediate descriptor. Add its length to the length -; in the following descriptor. - mov eax, [ebx+usb_gtd.NextVirt] - add [eax+usb_gtd.Length], edx - ret -endp - -if USB_STDCALL_VERIFY -proc verify_regs -virtual at esp - dd ? ; return address -.edi dd ? -.esi dd ? -.ebp dd ? -.esp dd ? -.ebx dd ? -.edx dd ? -.ecx dd ? -.eax dd ? -end virtual - cmp ebx, [.ebx] - jz @f - dbgstr 'ERROR!!! ebx changed' -@@: - cmp esi, [.esi] - jz @f - dbgstr 'ERROR!!! esi changed' -@@: - cmp edi, [.edi] - jz @f - dbgstr 'ERROR!!! edi changed' -@@: - cmp ebp, [.ebp] - jz @f - dbgstr 'ERROR!!! ebp changed' -@@: - ret -endp -end if diff --git a/kernel/branches/Kolibri-F/bus/usb/protocol.inc b/kernel/branches/Kolibri-F/bus/usb/protocol.inc deleted file mode 100644 index 011f07b93..000000000 --- a/kernel/branches/Kolibri-F/bus/usb/protocol.inc +++ /dev/null @@ -1,1019 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; Implementation of the USB protocol for device enumeration. -; Manage a USB device when it becomes ready for USB commands: -; configure, enumerate, load the corresponding driver(s), -; pass device information to the driver. - -; ============================================================================= -; ================================= Constants ================================= -; ============================================================================= -; USB standard request codes -USB_GET_STATUS = 0 -USB_CLEAR_FEATURE = 1 -USB_SET_FEATURE = 3 -USB_SET_ADDRESS = 5 -USB_GET_DESCRIPTOR = 6 -USB_SET_DESCRIPTOR = 7 -USB_GET_CONFIGURATION = 8 -USB_SET_CONFIGURATION = 9 -USB_GET_INTERFACE = 10 -USB_SET_INTERFACE = 11 -USB_SYNCH_FRAME = 12 - -; USB standard descriptor types -USB_DEVICE_DESCR = 1 -USB_CONFIG_DESCR = 2 -USB_STRING_DESCR = 3 -USB_INTERFACE_DESCR = 4 -USB_ENDPOINT_DESCR = 5 -USB_DEVICE_QUALIFIER_DESCR = 6 -USB_OTHER_SPEED_CONFIG_DESCR = 7 -USB_INTERFACE_POWER_DESCR = 8 - -; Compile-time setting. If set, the code will dump all descriptors as they are -; read to the debug board. -USB_DUMP_DESCRIPTORS = 1 - -; According to the USB specification (9.2.6.3), -; any device must response to SET_ADDRESS in 50 ms, or 5 timer ticks. -; Of course, our world is far from ideal. -; I have seen devices that just NAK everything when being reset from working -; state, but start to work after second reset. -; Our strategy is as follows: give 2 seconds for the first attempt, -; this should be enough for normal devices and not too long to detect buggy ones. -; If the device continues NAKing, reset it and retry several times, -; doubling the interval: 2s -> 4s -> 8s -> 16s. Give up after that. -; Numbers are quite arbitrary. -TIMEOUT_SET_ADDRESS_INITIAL = 200 -TIMEOUT_SET_ADDRESS_LAST = 1600 - -; ============================================================================= -; ================================ Structures ================================= -; ============================================================================= -; USB descriptors. See USB specification for detailed explanations. -; First two bytes of every descriptor have the same meaning. -struct usb_descr -bLength db ? -; Size of this descriptor in bytes -bDescriptorType db ? -; One of USB_*_DESCR constants. -ends - -; USB device descriptor -struct usb_device_descr usb_descr -bcdUSB dw ? -; USB Specification Release number in BCD, e.g. 110h = USB 1.1 -bDeviceClass db ? -; USB Device Class Code -bDeviceSubClass db ? -; USB Device Subclass Code -bDeviceProtocol db ? -; USB Device Protocol Code -bMaxPacketSize0 db ? -; Maximum packet size for zero endpoint -idVendor dw ? -; Vendor ID -idProduct dw ? -; Product ID -bcdDevice dw ? -; Device release number in BCD -iManufacturer db ? -; Index of string descriptor describing manufacturer -iProduct db ? -; Index of string descriptor describing product -iSerialNumber db ? -; Index of string descriptor describing serial number -bNumConfigurations db ? -; Number of possible configurations -ends - -; USB configuration descriptor -struct usb_config_descr usb_descr -wTotalLength dw ? -; Total length of data returned for this configuration -bNumInterfaces db ? -; Number of interfaces in this configuration -bConfigurationValue db ? -; Value for SET_CONFIGURATION control request -iConfiguration db ? -; Index of string descriptor describing this configuration -bmAttributes db ? -; Bit 6 is SelfPowered, bit 5 is RemoteWakeupSupported, -; bit 7 must be 1, other bits must be 0 -bMaxPower db ? -; Maximum power consumption from the bus in 2mA units -ends - -; USB interface descriptor -struct usb_interface_descr usb_descr -; The following two fields work in pair. Sometimes one interface can work -; in different modes; e.g. videostream from web-cameras requires different -; bandwidth depending on resolution/quality/compression settings. -; Each mode of each interface has its own descriptor with its own endpoints -; following; all descriptors for one interface have the same bInterfaceNumber, -; and different bAlternateSetting. -; By default, any interface operates in mode with bAlternateSetting = 0. -; Often this is the only mode. If there are another modes, the active mode -; is selected by SET_INTERFACE(bAlternateSetting) control request. -bInterfaceNumber db ? -bAlternateSetting db ? -bNumEndpoints db ? -; Number of endpoints used by this interface, excluding zero endpoint -bInterfaceClass db ? -; USB Interface Class Code -bInterfaceSubClass db ? -; USB Interface Subclass Code -bInterfaceProtocol db ? -; USB Interface Protocol Code -iInterface db ? -; Index of string descriptor describing this interface -ends - -; USB endpoint descriptor -struct usb_endpoint_descr usb_descr -bEndpointAddress db ? -; Lower 4 bits form endpoint number, -; upper bit is 0 for OUT endpoints and 1 for IN endpoints, -; other bits must be zero -bmAttributes db ? -; Lower 2 bits form transfer type, one of *_PIPE, -; other bits must be zero for non-isochronous endpoints; -; refer to the USB specification for meaning in isochronous case -wMaxPacketSize dw ? -; Lower 11 bits form maximum packet size, -; next two bits specify the number of additional transactions per microframe -; for high-speed periodic endpoints, other bits must be zero. -bInterval db ? -; Interval for polling endpoint for data transfers. -; Isochronous and high-speed interrupt endpoints: poll every 2^(bInterval-1) -; (micro)frames -; Full/low-speed interrupt endpoints: poll every bInterval frames -; High-speed bulk/control OUT endpoints: maximum NAK rate -ends - -; ============================================================================= -; =================================== Code ==================================== -; ============================================================================= - -; When a new device is ready to be configured, a controller-specific code -; calls usb_new_device. -; The sequence of further actions: -; * open pipe for the zero endpoint (usb_new_device); -; maximum packet size is not known yet, but it must be at least 8 bytes, -; so it is safe to send packets with <= 8 bytes -; * issue SET_ADDRESS control request (usb_new_device) -; * set the new device address in the pipe (usb_set_address_callback) -; * notify a controller-specific code that initialization of other ports -; can be started (usb_set_address_callback) -; * issue GET_DESCRIPTOR control request for first 8 bytes of device descriptor -; (usb_after_set_address) -; * first 8 bytes of device descriptor contain the true packet size for zero -; endpoint, so set the true packet size (usb_get_descr8_callback) -; * first 8 bytes of a descriptor contain the full size of this descriptor, -; issue GET_DESCRIPTOR control request for the full device descriptor -; (usb_after_set_endpoint_size) -; * issue GET_DESCRIPTOR control request for first 8 bytes of configuration -; descriptor (usb_get_descr_callback) -; * issue GET_DESCRIPTOR control request for full configuration descriptor -; (usb_know_length_callback) -; * issue SET_CONFIGURATION control request (usb_set_config_callback) -; * parse configuration descriptor, load the corresponding driver(s), -; pass the configuration descriptor to the driver and let the driver do -; the further work (usb_got_config_callback) - -; This function is called from controller-specific part -; when a new device is ready to be configured. -; in: ecx -> pseudo-pipe, part of usb_pipe -; in: esi -> usb_controller -; in: [esi+usb_controller.ResettingHub] is the pointer to usb_hub for device, -; NULL if the device is connected to the root hub -; in: [esi+usb_controller.ResettingPort] is the port for the device, zero-based -; in: [esi+usb_controller.ResettingSpeed] is the speed of the device, one of -; USB_SPEED_xx. -; out: eax = 0 <=> failed, the caller should disable the port. -proc usb_new_device - push ebx edi ; save used registers to be stdcall -; 1. Check whether we're here because we were trying to reset -; already-registered device in hope to fix something serious. -; If so, skip allocation and go to 6. - movzx eax, [esi+usb_controller.ResettingPort] - mov edx, [esi+usb_controller.ResettingHub] - test edx, edx - jz .test_roothub - mov edx, [edx+usb_hub.ConnectedDevicesPtr] - mov ebx, [edx+eax*4] - jmp @f -.test_roothub: - mov ebx, [esi+usb_controller.DevicesByPort+eax*4] -@@: - test ebx, ebx - jnz .try_set_address -; 2. Allocate resources. Any device uses the following resources: -; - device address in the bus -; - memory for device data -; - pipe for zero endpoint -; If some allocation fails, we must undo our actions. Closing the pipe -; is a hard task, so we avoid it and open the pipe as the last resource. -; The order for other two allocations is quite arbitrary. -; 2a. Allocate a bus address. - push ecx - call usb_set_address_request - pop ecx -; 2b. If failed, just return zero. - test eax, eax - jz .nothing -; 2c. Allocate memory for device data. -; For now, we need sizeof.usb_device_data and extra 8 bytes for GET_DESCRIPTOR -; input and output, see usb_after_set_address. Later we will reallocate it -; to actual size needed for descriptors. - movi eax, sizeof.usb_device_data + 8 - push ecx - call malloc - pop ecx -; 2d. If failed, free the bus address and return zero. - test eax, eax - jz .nomemory -; 2e. Open pipe for endpoint zero. -; For now, we do not know the actual maximum packet size; -; for full-speed devices it can be any of 8, 16, 32, 64 bytes, -; low-speed devices must have 8 bytes, high-speed devices must have 64 bytes. -; Thus, we must use some fake "maximum packet size" until the actual size -; will be known. However, the maximum packet size must be at least 8, and -; initial stages of the configuration process involves only packets of <= 8 -; bytes, they will be transferred correctly as long as -; the fake "maximum packet size" is also at least 8. -; Thus, any number >= 8 is suitable for actual hardware. -; However, software emulation of EHCI in VirtualBox assumes that high-speed -; control transfers are those originating from pipes with max packet size = 64, -; even on early stages of the configuration process. This is incorrect, -; but we have no specific preferences, so let VirtualBox be happy and use 64 -; as the fake "maximum packet size". - push eax -; We will need many zeroes. -; "push edi" is one byte, "push 0" is two bytes; save space, use edi. - xor edi, edi - stdcall usb_open_pipe, ecx, edi, 64, edi, edi -; Put pointer to pipe into ebx. "xchg eax,reg" is one byte, mov is two bytes. - xchg eax, ebx - pop eax -; 2f. If failed, free the memory, the bus address and return zero. - test ebx, ebx - jz .freememory -; 3. Store pointer to device data in the pipe structure. - mov [ebx+usb_pipe.DeviceData], eax -; 4. Init device data, using usb_controller.Resetting* variables. - mov [eax+usb_device_data.Timer], edi - mov dword [eax+usb_device_data.DeviceDescriptor], TIMEOUT_SET_ADDRESS_INITIAL - mov [eax+usb_device_data.TTHub], edi - mov [eax+usb_device_data.TTPort], 0 - mov [eax+usb_device_data.NumInterfaces], edi - mov [eax+usb_device_data.DeviceDescrSize], 0 - mov dl, [esi+usb_controller.ResettingSpeed] - mov [eax+usb_device_data.Speed], dl - mov [eax+usb_device_data.NumPipes], 1 - push ebx - cmp dl, USB_SPEED_HS - jz .nott - mov ebx, [esi+usb_controller.ResettingHub] - test ebx, ebx - jz .nott - mov cl, [esi+usb_controller.ResettingPort] - mov edx, [ebx+usb_hub.ConfigPipe] - mov edx, [edx+usb_pipe.DeviceData] - cmp [edx+usb_device_data.TTHub], 0 - jz @f - mov cl, [edx+usb_device_data.TTPort] - mov ebx, [edx+usb_device_data.TTHub] - jmp .has_tt -@@: - cmp [edx+usb_device_data.Speed], USB_SPEED_HS - jnz .nott -.has_tt: - mov [eax+usb_device_data.TTHub], ebx - mov [eax+usb_device_data.TTPort], cl -.nott: - pop ebx - mov [eax+usb_device_data.ConfigDataSize], edi - mov [eax+usb_device_data.Interfaces], edi - movzx ecx, [esi+usb_controller.ResettingPort] - mov [eax+usb_device_data.Port], cl - mov edx, [esi+usb_controller.ResettingHub] - mov [eax+usb_device_data.Hub], edx -; 5. Store pointer to the config pipe in the hub data. -; Config pipe serves as device identifier. -; Root hubs use the array inside usb_controller structure, -; non-root hubs use the array immediately after usb_hub structure. - test edx, edx - jz .roothub - mov edx, [edx+usb_hub.ConnectedDevicesPtr] - mov [edx+ecx*4], ebx - jmp @f -.roothub: - mov [esi+usb_controller.DevicesByPort+ecx*4], ebx -@@: - call usb_reinit_pipe_list -; 6. Issue SET_ADDRESS control request, using buffer filled in step 2a. -; 6a. Configure timer to force reset after timeout. -; Note: we can't use self-destructing timer, because we need to be able to cancel it, -; and for self-destructing timer we could have race condition in cancelling/destructing. -; DEBUGF 1,'K : pipe %x\n',ebx -.try_set_address: - xor edi, edi - mov edx, [ebx+usb_pipe.DeviceData] - stdcall timer_hs, [edx+usb_device_data.DeviceDescriptor], 7FFFFFFFh, usb_abort_pipe, ebx - test eax, eax - jz .nothing - mov edx, [ebx+usb_pipe.DeviceData] - mov [edx+usb_device_data.Timer], eax -; 6b. If it succeeded, setup timer to configure wait timeout. - lea eax, [esi+usb_controller.SetAddressBuffer] - stdcall usb_control_async, ebx, eax, edi, edi, usb_set_address_callback, edi, edi -; Use the return value from usb_control_async as our return value; -; if it is zero, then something has failed. -.nothing: -; 7. Return. - pop edi ebx ; restore used registers to be stdcall - ret -; Handlers of failures in steps 2b, 2d, 2f. -.freememory: - call free - jmp .freeaddr -.nomemory: - dbgstr 'No memory for device data' -.freeaddr: - mov ecx, dword [esi+usb_controller.SetAddressBuffer+2] - bts [esi+usb_controller.ExistingAddresses], ecx - xor eax, eax - jmp .nothing -endp - -; Helper procedure for usb_new_device. -; Allocates a new USB address and fills usb_controller.SetAddressBuffer -; with data for SET_ADDRESS(allocated_address) request. -; out: eax = 0 <=> failed -; Destroys edi. -proc usb_set_address_request -; There are 128 bits, one for each possible address. -; Note: only the USB thread works with usb_controller.ExistingAddresses, -; so there is no need for synchronization. -; We must find a bit set to 1 and clear it. -; 1. Find the first dword which has a nonzero bit = which is nonzero. - mov ecx, 128/32 - lea edi, [esi+usb_controller.ExistingAddresses] - xor eax, eax - repz scasd -; 2. If all dwords are zero, return an error. - jz .error -; 3. The dword at [edi-4] is nonzero. Find the lowest nonzero bit. - bsf eax, [edi-4] -; Now eax = bit number inside the dword at [edi-4]. -; 4. Clear the bit. - btr [edi-4], eax -; 5. Generate the address by edi = memory address and eax = bit inside dword. -; Address = eax + 8 * (edi-4 - (esi+usb_controller.ExistingAddress)). - sub edi, esi - lea edi, [eax+(edi-4-usb_controller.ExistingAddresses)*8] -; 6. Store the allocated address in SetAddressBuffer and fill remaining fields. -; Note that usb_controller is zeroed at allocation, so only command byte needs -; to be filled. - mov byte [esi+usb_controller.SetAddressBuffer+1], USB_SET_ADDRESS - mov dword [esi+usb_controller.SetAddressBuffer+2], edi -; 7. Return non-zero value in eax. - inc eax -.nothing: - ret -.error: - dbgstr 'cannot allocate USB address' - xor eax, eax - jmp .nothing -endp - -; This procedure is called by USB stack when SET_ADDRESS request initiated by -; usb_new_device is completed, either successfully or unsuccessfully. -; Note that USB stack uses esi = pointer to usb_controller. -proc usb_set_address_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword - push ebx ; save ebx to be stdcall - mov ebx, [pipe] -; 1. In any case, cancel the timer. - mov eax, [ebx+usb_pipe.DeviceData] - stdcall cancel_timer_hs, [eax+usb_device_data.Timer] - mov eax, [ebx+usb_pipe.DeviceData] - mov [eax+usb_device_data.Timer], 0 -; Load data to registers for further references. - mov ecx, dword [esi+usb_controller.SetAddressBuffer+2] - mov eax, [esi+usb_controller.HardwareFunc] -; 2. Check whether the device has accepted new address. If so, proceed to 3. -; Otherwise, go to 4 if killed by usb_set_address_timeout or to 5 otherwise. - cmp [status], USB_STATUS_CANCELLED - jz .timeout - cmp [status], 0 - jnz .error -; 3. Address accepted. -; 3a. The controller-specific structure for the control pipe still uses -; zero address. Call the controller-specific function to change it to -; the actual address. -; Note that the hardware could cache the controller-specific structure, -; so setting the address could take some time until the cache is evicted. -; Thus, the call is asynchronous; meet us in usb_after_set_address when it will -; be safe to continue. -; dbgstr 'address set in device' - call [eax+usb_hardware_func.SetDeviceAddress] -; 3b. If the port is in non-root hub, clear 'reset in progress' flag. -; In any case, proceed to 6. - mov eax, [esi+usb_controller.ResettingHub] - test eax, eax - jz .return - and [eax+usb_hub.Actions], not HUB_RESET_IN_PROGRESS -.return: -; 6. Address configuration done, we can proceed with other ports. -; Call the worker function for that. - call usb_test_pending_port -.wakeup: - push esi edi - call usb_wakeup - pop edi esi -.nothing: - pop ebx ; restore ebx to be stdcall - ret -.timeout: -; 4. Device continues to NAK the request. Reset it and retry. - mov edx, [ebx+usb_pipe.DeviceData] - mov ecx, [edx+usb_device_data.DeviceDescriptor] - add ecx, ecx - cmp ecx, TIMEOUT_SET_ADDRESS_LAST - ja .error - mov [edx+usb_device_data.DeviceDescriptor], ecx - dbgstr 'Timeout in USB device initialization, trying to reset...' - cmp [esi+usb_controller.ResettingHub], 0 - jz .reset_roothub - push esi - mov esi, [esi+usb_controller.ResettingHub] - call usb_hub_initiate_reset - pop esi - jmp .nothing -.reset_roothub: - movzx ecx, [esi+usb_controller.ResettingPort] - call [eax+usb_hardware_func.InitiateReset] - jmp .wakeup -.error: -; 5. Device error: device not responding, disconnect etc. - DEBUGF 1,'K : error %d in SET_ADDRESS, USB device disabled\n',[status] -; 5a. The address has not been accepted. Mark it as free. - bts dword [esi+usb_controller.ExistingAddresses], ecx -; 5b. Disable the port with bad device. -; For the root hub, call the controller-specific function and go to 6. -; For non-root hubs, let the hub code do its work and return (the request -; could take some time, the hub code is responsible for proceeding). - cmp [esi+usb_controller.ResettingHub], 0 - jz .roothub - mov eax, [esi+usb_controller.ResettingHub] - call usb_hub_disable_resetting_port - jmp .nothing -.roothub: - movzx ecx, [esi+usb_controller.ResettingPort] - call [eax+usb_hardware_func.PortDisable] - jmp .return -endp - -; This procedure is called from usb_subscription_done when the hardware cache -; is cleared after request from usb_set_address_callback. -; in: ebx -> usb_pipe -proc usb_after_set_address -; dbgstr 'address set for controller' -; Issue control transfer GET_DESCRIPTOR(DEVICE_DESCR) for first 8 bytes. -; Remember, we still do not know the actual packet size; -; 8-bytes-request is safe. -; usb_new_device has allocated 8 extra bytes besides sizeof.usb_device_data; -; use them for both input and output. - mov eax, [ebx+usb_pipe.DeviceData] - add eax, usb_device_data.DeviceDescriptor - mov dword [eax], \ - 80h + \ ; device-to-host, standard, device-wide - (USB_GET_DESCRIPTOR shl 8) + \ ; request - (0 shl 16) + \ ; descriptor index: there is only one - (USB_DEVICE_DESCR shl 24) ; descriptor type - mov dword [eax+4], 8 shl 16 ; data length - stdcall usb_control_async, ebx, eax, eax, 8, usb_get_descr8_callback, eax, 0 - ret -endp - -; This procedure is called by USB stack when GET_DESCRIPTOR(DEVICE_DESCR) -; request initiated by usb_after_set_address is completed, either successfully -; or unsuccessfully. -; Note that USB stack uses esi = pointer to usb_controller. -proc usb_get_descr8_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword -; mov eax, [buffer] -; DEBUGF 1,'K : descr8: l=%x; %x %x %x %x %x %x %x %x\n',[length],\ -; [eax]:2,[eax+1]:2,[eax+2]:2,[eax+3]:2,[eax+4]:2,[eax+5]:2,[eax+6]:2,[eax+7]:2 - push edi ebx ; save used registers to be stdcall - mov ebx, [pipe] -; 1. Check whether the operation was successful. -; If not, say something to the debug board and stop the initialization. - cmp [status], 0 - jnz .error -; 2. Length of descriptor must be at least sizeof.usb_device_descr bytes. -; If not, say something to the debug board and stop the initialization. - mov eax, [ebx+usb_pipe.DeviceData] - cmp [eax+usb_device_data.DeviceDescriptor+usb_device_descr.bLength], sizeof.usb_device_descr - jb .error -; 3. Now first 8 bytes of device descriptor are known; -; set DeviceDescrSize accordingly. - mov [eax+usb_device_data.DeviceDescrSize], 8 -; 4. The controller-specific structure for the control pipe still uses -; the fake "maximum packet size". Call the controller-specific function to -; change it to the actual packet size from the device. -; Note that the hardware could cache the controller-specific structure, -; so changing it could take some time until the cache is evicted. -; Thus, the call is asynchronous; meet us in usb_after_set_endpoint_size -; when it will be safe to continue. - movzx ecx, [eax+usb_device_data.DeviceDescriptor+usb_device_descr.bMaxPacketSize0] - mov eax, [esi+usb_controller.HardwareFunc] - call [eax+usb_hardware_func.SetEndpointPacketSize] -.nothing: -; 5. Return. - pop ebx edi ; restore used registers to be stdcall - ret -.error: - dbgstr 'error with USB device descriptor' - jmp .nothing -endp - -; This procedure is called from usb_subscription_done when the hardware cache -; is cleared after request from usb_get_descr8_callback. -; in: ebx -> usb_pipe -proc usb_after_set_endpoint_size -; 1. Reallocate memory for device data: -; add memory for now-known size of device descriptor and extra 8 bytes -; for further actions. -; 1a. Allocate new memory. - mov eax, [ebx+usb_pipe.DeviceData] - movzx eax, [eax+usb_device_data.DeviceDescriptor+usb_device_descr.bLength] -; save length for step 2 - push eax - add eax, sizeof.usb_device_data + 8 - call malloc -; 1b. If failed, say something to the debug board and stop the initialization. - test eax, eax - jz .nomemory -; 1c. Copy data from old memory to new memory and switch the pointer in usb_pipe. - push eax - push esi edi - mov esi, [ebx+usb_pipe.DeviceData] - mov [ebx+usb_pipe.DeviceData], eax - mov edi, eax - mov eax, esi - mov ecx, sizeof.usb_device_data / 4 - rep movsd - pop edi esi - call usb_reinit_pipe_list -; 1d. Free the old memory. - call free - pop eax -; 2. Issue control transfer GET_DESCRIPTOR(DEVICE) for full descriptor. -; restore length saved in step 1a - pop edx - add eax, sizeof.usb_device_data - mov dword [eax], \ - 80h + \ ; device-to-host, standard, device-wide - (USB_GET_DESCRIPTOR shl 8) + \ ; request - (0 shl 16) + \ ; descriptor index: there is only one - (USB_DEVICE_DESCR shl 24) ; descriptor type - and dword [eax+4], 0 - mov [eax+6], dl ; data length - stdcall usb_control_async, ebx, eax, eax, edx, usb_get_descr_callback, eax, 0 -; 3. Return. - ret -.nomemory: - dbgstr 'No memory for device data' - ret -endp - -; This procedure is called by USB stack when GET_DESCRIPTOR(DEVICE) -; request initiated by usb_after_set_endpoint_size is completed, -; either successfully or unsuccessfully. -proc usb_get_descr_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword -; Note: the prolog is the same as in usb_get_descr8_callback. - push edi ebx ; save used registers to be stdcall -; 1. Check whether the operation was successful. -; If not, say something to the debug board and stop the initialization. - cmp [status], 0 - jnz usb_get_descr8_callback.error -; The full descriptor is known, dump it if specified by compile-time option. -if USB_DUMP_DESCRIPTORS - mov eax, [buffer] - mov ecx, [length] - sub ecx, 8 - jbe .skipdebug - DEBUGF 1,'K : device descriptor:' -@@: - DEBUGF 1,' %x',[eax]:2 - inc eax - dec ecx - jnz @b - DEBUGF 1,'\n' -.skipdebug: -end if -; 2. Check that bLength is the same as was in the previous request. -; If not, say something to the debug board and stop the initialization. -; It is important, because usb_after_set_endpoint_size has allocated memory -; according to the old bLength. Note that [length] for control transfers -; includes 8 bytes of setup packet, so data length = [length] - 8. - mov eax, [buffer] - movzx ecx, [eax+usb_device_descr.bLength] - add ecx, 8 - cmp [length], ecx - jnz usb_get_descr8_callback.error -; Amuse the user if she is watching the debug board. - mov cl, [eax+usb_device_descr.bNumConfigurations] - DEBUGF 1,'K : found USB device with ID %x:%x, %d configuration(s)\n',\ - [eax+usb_device_descr.idVendor]:4,\ - [eax+usb_device_descr.idProduct]:4,\ - cl -; 3. If there are no configurations, stop the initialization. - cmp [eax+usb_device_descr.bNumConfigurations], 0 - jz .nothing -; 4. Copy length of device descriptor to device data structure. - movzx edx, [eax+usb_device_descr.bLength] - mov [eax+usb_device_data.DeviceDescrSize-usb_device_data.DeviceDescriptor], dl -; 5. Issue control transfer GET_DESCRIPTOR(CONFIGURATION). We do not know -; the full length of that descriptor, so start with first 8 bytes, they contain -; the full length. -; usb_after_set_endpoint_size has allocated 8 extra bytes after the -; device descriptor, use them for both input and output. - add eax, edx - mov dword [eax], \ - 80h + \ ; device-to-host, standard, device-wide - (USB_GET_DESCRIPTOR shl 8) + \ ; request - (0 shl 16) + \ ; descriptor index: there is only one - (USB_CONFIG_DESCR shl 24) ; descriptor type - mov dword [eax+4], 8 shl 16 ; data length - stdcall usb_control_async, [pipe], eax, eax, 8, usb_know_length_callback, eax, 0 -.nothing: -; 6. Return. - pop ebx edi ; restore used registers to be stdcall - ret -endp - -; This procedure is called by USB stack when GET_DESCRIPTOR(CONFIGURATION) -; request initiated by usb_get_descr_callback is completed, -; either successfully or unsuccessfully. -proc usb_know_length_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword - push ebx ; save used registers to be stdcall -; 1. Check whether the operation was successful. -; If not, say something to the debug board and stop the initialization. - cmp [status], 0 - jnz .error -; 2. Get the total length of data associated with config descriptor and store -; it in device data structure. The total length must be at least -; sizeof.usb_config_descr bytes; if not, say something to the debug board and -; stop the initialization. - mov eax, [buffer] - mov edx, [pipe] - movzx ecx, [eax+usb_config_descr.wTotalLength] - mov eax, [edx+usb_pipe.DeviceData] - cmp ecx, sizeof.usb_config_descr - jb .error - mov [eax+usb_device_data.ConfigDataSize], ecx -; 3. Reallocate memory for device data: -; include usb_device_data structure, device descriptor, -; config descriptor with all associated data, and extra bytes -; sufficient for 8 bytes control packet and for one usb_interface_data struc. -; Align extra bytes to dword boundary. -if sizeof.usb_interface_data > 8 -.extra_size = sizeof.usb_interface_data -else -.extra_size = 8 -end if -; 3a. Allocate new memory. - movzx edx, [eax+usb_device_data.DeviceDescrSize] - lea eax, [ecx+edx+sizeof.usb_device_data+.extra_size+3] - and eax, not 3 - push eax - call malloc - pop edx -; 3b. If failed, say something to the debug board and stop the initialization. - test eax, eax - jz .nomemory -; 3c. Copy data from old memory to new memory and switch the pointer in usb_pipe. - push eax - mov ebx, [pipe] - push esi edi - mov esi, [ebx+usb_pipe.DeviceData] - mov edi, eax - mov [ebx+usb_pipe.DeviceData], eax - mov eax, esi - movzx ecx, [esi+usb_device_data.DeviceDescrSize] - sub edx, .extra_size - mov [esi+usb_device_data.Interfaces], edx - add ecx, sizeof.usb_device_data + 8 - mov edx, ecx - shr ecx, 2 - and edx, 3 - rep movsd - mov ecx, edx - rep movsb - pop edi esi - call usb_reinit_pipe_list -; 3d. Free old memory. - call free - pop eax -; 4. Issue control transfer GET_DESCRIPTOR(CONFIGURATION) for full descriptor. - movzx ecx, [eax+usb_device_data.DeviceDescrSize] - mov edx, [eax+usb_device_data.ConfigDataSize] - lea eax, [eax+ecx+sizeof.usb_device_data] - mov dword [eax], \ - 80h + \ ; device-to-host, standard, device-wide - (USB_GET_DESCRIPTOR shl 8) + \ ; request - (0 shl 16) + \ ; descriptor index: there is only one - (USB_CONFIG_DESCR shl 24) ; descriptor type - and dword [eax+4], 0 - mov word [eax+6], dx ; data length - stdcall usb_control_async, [pipe], eax, eax, edx, usb_set_config_callback, eax, 0 -.nothing: -; 5. Return. - pop ebx ; restore used registers to be stdcall - ret -.error: - dbgstr 'error with USB configuration descriptor' - jmp .nothing -.nomemory: - dbgstr 'No memory for device data' - jmp .nothing -endp - -; This procedure is called by USB stack when GET_DESCRIPTOR(CONFIGURATION) -; request initiated by usb_know_length_callback is completed, -; either successfully or unsuccessfully. -proc usb_set_config_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword -; Note that the prolog is the same as in usb_know_length_callback. - push ebx ; save used registers to be stdcall -; 1. Check whether the operation was successful. -; If not, say something to the debug board and stop the initialization. - xor ecx, ecx - mov ebx, [pipe] - cmp [status], ecx - jnz usb_know_length_callback.error -; The full descriptor is known, dump it if specified by compile-time option. -if USB_DUMP_DESCRIPTORS - mov eax, [buffer] - mov ecx, [length] - sub ecx, 8 - jbe .skip_debug - DEBUGF 1,'K : config descriptor:' -@@: - DEBUGF 1,' %x',[eax]:2 - inc eax - dec ecx - jnz @b - DEBUGF 1,'\n' -.skip_debug: - xor ecx, ecx -end if -; 2. Issue control transfer SET_CONFIGURATION to activate this configuration. -; Usually this is the only configuration. -; Use extra bytes allocated by usb_know_length_callback; -; offset from device data start is stored in Interfaces. - mov eax, [ebx+usb_pipe.DeviceData] - mov edx, [buffer] - add eax, [eax+usb_device_data.Interfaces] - mov dl, [edx+usb_config_descr.bConfigurationValue] - mov dword [eax], USB_SET_CONFIGURATION shl 8 - mov dword [eax+4], ecx - mov byte [eax+2], dl - stdcall usb_control_async, [pipe], eax, ecx, ecx, usb_got_config_callback, [buffer], ecx - pop ebx ; restore used registers to be stdcall - ret -endp - -; This procedure is called by USB stack when SET_CONFIGURATION -; request initiated by usb_set_config_callback is completed, -; either successfully or unsuccessfully. -; If successfully, the device is configured and ready to work, -; pass the device to the corresponding driver(s). -proc usb_got_config_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword -locals -InterfacesData dd ? -NumInterfaces dd ? -driver dd ? -endl -; 1. If there was an error, say something to the debug board and stop the -; initialization. - cmp [status], 0 - jz @f - dbgstr 'USB error in SET_CONFIGURATION' - ret -@@: - push ebx edi ; save used registers to be stdcall -; 2. Sanity checks: the total length must be the same as before (because we -; have allocated memory assuming the old value), length of config descriptor -; must be at least sizeof.usb_config_descr (we use fields from it), -; there must be at least one interface. - mov ebx, [pipe] - mov ebx, [ebx+usb_pipe.DeviceData] - mov eax, [calldata] - mov edx, [ebx+usb_device_data.ConfigDataSize] - cmp [eax+usb_config_descr.wTotalLength], dx - jnz .invalid - cmp [eax+usb_config_descr.bLength], 9 - jb .invalid - movzx edx, [eax+usb_config_descr.bNumInterfaces] - test edx, edx - jnz @f -.invalid: - dbgstr 'error: invalid configuration descriptor' - jmp .nothing -@@: -; 3. Store the number of interfaces in device data structure. - mov [ebx+usb_device_data.NumInterfaces], edx -; 4. If there is only one interface (which happens quite often), -; the memory allocated in usb_know_length_callback is sufficient. -; Otherwise (which also happens quite often), reallocate device data. -; 4a. Check whether there is only one interface. If so, skip this step. - cmp edx, 1 - jz .has_memory -; 4b. Allocate new memory. - mov eax, [ebx+usb_device_data.Interfaces] - lea eax, [eax+edx*sizeof.usb_interface_data] - call malloc -; 4c. If failed, say something to the debug board and -; stop the initialization. - test eax, eax - jnz @f - dbgstr 'No memory for device data' - jmp .nothing -@@: -; 4d. Copy data from old memory to new memory and switch the pointer in usb_pipe. - push eax - push esi - mov ebx, [pipe] - mov edi, eax - mov esi, [ebx+usb_pipe.DeviceData] - mov [ebx+usb_pipe.DeviceData], eax - mov eax, esi - mov ecx, [esi+usb_device_data.Interfaces] - shr ecx, 2 - rep movsd - pop esi - call usb_reinit_pipe_list -; 4e. Free old memory. - call free - pop ebx -.has_memory: -; 5. Initialize interfaces table: zero all contents. - mov edi, [ebx+usb_device_data.Interfaces] - add edi, ebx - mov [InterfacesData], edi - mov ecx, [ebx+usb_device_data.NumInterfaces] -if sizeof.usb_interface_data <> 8 -You have changed sizeof.usb_interface_data? Modify this place too. -end if - add ecx, ecx - xor eax, eax - rep stosd -; No interfaces are found yet. - mov [NumInterfaces], eax -; 6. Get the pointer to config descriptor data. -; Note: if there was reallocation, [buffer] is not valid anymore, -; so calculate value based on usb_device_data. - movzx eax, [ebx+usb_device_data.DeviceDescrSize] - lea eax, [eax+ebx+sizeof.usb_device_data] - mov [calldata], eax - mov ecx, [ebx+usb_device_data.ConfigDataSize] -; 7. Loop over all descriptors, -; scan for interface descriptors with bAlternateSetting = 0, -; load the corresponding driver, call its AddDevice function. -.descriptor_loop: -; While in loop: eax points to the current descriptor, -; ecx = number of bytes left, the iteration starts only if ecx is nonzero, -; edx = size of the current descriptor. -; 7a. The first byte is always accessible; it contains the length of -; the current descriptor. Validate that the length is at least 2 bytes, -; and the entire descriptor is readable (the length is at most number of -; bytes left). - movzx edx, [eax+usb_descr.bLength] - cmp edx, sizeof.usb_descr - jb .invalid - cmp ecx, edx - jb .invalid -; 7b. Check descriptor type. Ignore all non-INTERFACE descriptor. - cmp byte [eax+usb_descr.bDescriptorType], USB_INTERFACE_DESCR - jz .interface -.next_descriptor: -; 7c. Advance pointer, decrease length left, if there is still something left, -; continue the loop. - add eax, edx - sub ecx, edx - jnz .descriptor_loop -.done: -.nothing: - pop edi ebx ; restore used registers to be stdcall - ret -.interface: -; 7d. Validate the descriptor length. - cmp edx, sizeof.usb_interface_descr - jb .next_descriptor -; 7e. If bAlternateSetting is nonzero, this descriptor actually describes -; another mode of already known interface and belongs to the already loaded -; driver; amuse the user and continue to 7c. - cmp byte [eax+usb_interface_descr.bAlternateSetting], 0 - jz @f - DEBUGF 1,'K : note: alternate setting with %x/%x/%x\n',\ - [eax+usb_interface_descr.bInterfaceClass]:2,\ - [eax+usb_interface_descr.bInterfaceSubClass]:2,\ - [eax+usb_interface_descr.bInterfaceProtocol]:2 - jmp .next_descriptor -@@: -; 7f. Check that the new interface does not overflow allocated table. - mov edx, [NumInterfaces] - inc edx - cmp edx, [ebx+usb_device_data.NumInterfaces] - ja .invalid -; 7g. We have found a new interface. Advance bookkeeping vars. - mov [NumInterfaces], edx - add [InterfacesData], sizeof.usb_interface_data -; 7h. Save length left and pointer to the current interface descriptor. - push ecx eax -; Amuse the user if she is watching the debug board. - DEBUGF 1,'K : USB interface class/subclass/protocol = %x/%x/%x\n',\ - [eax+usb_interface_descr.bInterfaceClass]:2,\ - [eax+usb_interface_descr.bInterfaceSubClass]:2,\ - [eax+usb_interface_descr.bInterfaceProtocol]:2 -; 7i. Select the correct driver based on interface class. -; For hubs, go to 7j. Otherwise, go to 7k. -; Note: this should be rewritten as table-based lookup when more drivers will -; be available. - cmp byte [eax+usb_interface_descr.bInterfaceClass], 9 - jz .found_hub - mov edx, usb_hid_name - cmp byte [eax+usb_interface_descr.bInterfaceClass], 3 - jz .load_driver - mov edx, usb_print_name - cmp byte [eax+usb_interface_descr.bInterfaceClass], 7 - jz .load_driver - mov edx, usb_stor_name - cmp byte [eax+usb_interface_descr.bInterfaceClass], 8 - jz .load_driver - mov edx, usb_other_name - jmp .load_driver -.found_hub: -; 7j. Hubs are a part of USB stack, thus, integrated into the kernel. -; Use the pointer to hub callbacks and go to 7m. - mov eax, usb_hub_pseudosrv - USBSRV.usb_func - jmp .driver_loaded -.load_driver: -; 7k. Load the corresponding driver. - push ebx esi edi - stdcall get_service, edx - pop edi esi ebx -; 7l. If failed, say something to the debug board and go to 7p. - test eax, eax - jnz .driver_loaded - dbgstr 'failed to load class driver' - jmp .next_descriptor2 -.driver_loaded: -; 7m. Call AddDevice function of the driver. -; Note that top of stack contains a pointer to the current interface, -; saved by step 7h. - mov [driver], eax - mov eax, [eax+USBSRV.usb_func] - pop edx - push edx -; Note: usb_hub_init assumes that edx points to usb_interface_descr, -; ecx = length rest; if you change the code, modify usb_hub_init also. - stdcall [eax+USBFUNC.add_device], [pipe], [calldata], edx -; 7n. If failed, say something to the debug board and go to 7p. - test eax, eax - jnz .store_data - dbgstr 'USB device initialization failed' - jmp .next_descriptor2 -.store_data: -; 7o. Store the returned value and the driver handle to InterfacesData. -; Note that step 7g has already advanced InterfacesData. - mov edx, [InterfacesData] - mov [edx+usb_interface_data.DriverData-sizeof.usb_interface_data], eax - mov eax, [driver] - mov [edx+usb_interface_data.DriverFunc-sizeof.usb_interface_data], eax -.next_descriptor2: -; 7p. Restore registers saved in step 7h, get the descriptor length and -; continue to 7c. - pop eax ecx - movzx edx, byte [eax+usb_descr.bLength] - jmp .next_descriptor -endp - -; Driver names, see step 7i of usb_got_config_callback. -iglobal -usb_hid_name db 'usbhid',0 -usb_stor_name db 'usbstor',0 -usb_print_name db 'usbprint',0 -usb_other_name db 'usbother',0 -endg diff --git a/kernel/branches/Kolibri-F/const.inc b/kernel/branches/Kolibri-F/const.inc deleted file mode 100644 index 3636518ae..000000000 --- a/kernel/branches/Kolibri-F/const.inc +++ /dev/null @@ -1,984 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2021. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -dpl0 = 10010000b ; data read dpl0 -drw0 = 10010010b ; data read/write dpl0 -drw3 = 11110010b ; data read/write dpl3 -cpl0 = 10011010b ; code read dpl0 -cpl3 = 11111010b ; code read dpl3 - -D32 = 01000000b ; 32bit segment -G32 = 10000000b ; page gran - - -;;;;;;;;;;;;cpu_caps flags;;;;;;;;;;;;;;;; - -CPU_386 = 3 -CPU_486 = 4 -CPU_PENTIUM = 5 -CPU_P6 = 6 -CPU_PENTIUM4 = 0x0F - -CAPS_FPU = 00 ;on-chip x87 floating point unit -CAPS_VME = 01 ;virtual-mode enhancements -CAPS_DE = 02 ;debugging extensions -CAPS_PSE = 03 ;page-size extensions -CAPS_TSC = 04 ;time stamp counter -CAPS_MSR = 05 ;model-specific registers -CAPS_PAE = 06 ;physical-address extensions -CAPS_MCE = 07 ;machine check exception -CAPS_CX8 = 08 ;CMPXCHG8B instruction -CAPS_APIC = 09 ;on-chip advanced programmable - ;interrupt controller -; 10 ;unused -CAPS_SEP = 11 ;SYSENTER and SYSEXIT instructions -CAPS_MTRR = 12 ;memory-type range registers -CAPS_PGE = 13 ;page global extension -CAPS_MCA = 14 ;machine check architecture -CAPS_CMOV = 15 ;conditional move instructions -CAPS_PAT = 16 ;page attribute table - -CAPS_PSE36 = 17 ;page-size extensions -CAPS_PSN = 18 ;processor serial number -CAPS_CLFLUSH = 19 ;CLFUSH instruction - -CAPS_DS = 21 ;debug store -CAPS_ACPI = 22 ;thermal monitor and software - ;controlled clock supported -CAPS_MMX = 23 ;MMX instructions -CAPS_FXSR = 24 ;FXSAVE and FXRSTOR instructions -CAPS_SSE = 25 ;SSE instructions -CAPS_SSE2 = 26 ;SSE2 instructions -CAPS_SS = 27 ;self-snoop -CAPS_HTT = 28 ;hyper-threading technology -CAPS_TM = 29 ;thermal monitor supported -CAPS_IA64 = 30 ;IA64 capabilities -CAPS_PBE = 31 ;pending break enable - -;ecx -CAPS_SSE3 = 32 ;SSE3 instructions -; 33 -; 34 -CAPS_MONITOR = 35 ;MONITOR/MWAIT instructions -CAPS_DS_CPL = 36 ; -CAPS_VMX = 37 ;virtual mode extensions -; 38 ; -CAPS_EST = 39 ;enhansed speed step -CAPS_TM2 = 40 ;thermal monitor2 supported -; 41 -CAPS_CID = 42 ; -; 43 -; 44 -CAPS_CX16 = 45 ;CMPXCHG16B instruction -CAPS_xTPR = 46 ; -CAPS_XSAVE = 32 + 26 ; XSAVE and XRSTOR instructions -CAPS_OSXSAVE = 32 + 27 -; A value of 1 indicates that the OS has set CR4.OSXSAVE[bit 18] to enable -; XSETBV/XGETBV instructions to access XCR0 and to support processor extended -; state management using XSAVE/XRSTOR. -CAPS_AVX = 32 + 28 ; not AVX2 -; -;reserved -; -;ext edx /ecx -CAPS_SYSCAL = 64 ; -CAPS_XD = 65 ;execution disable -CAPS_FFXSR = 66 ; -CAPS_RDTSCP = 67 ; -CAPS_X64 = 68 ; -CAPS_3DNOW = 69 ; -CAPS_3DNOWEXT = 70 ; -CAPS_LAHF = 71 ; -CAPS_CMP_LEG = 72 ; -CAPS_SVM = 73 ;secure virual machine -CAPS_ALTMOVCR8 = 74 ; - -; CPU MSR names -MSR_SYSENTER_CS = 0x174 -MSR_SYSENTER_ESP = 0x175 -MSR_SYSENTER_EIP = 0x176 -MSR_CR_PAT = 0x277 -MSR_MTRR_DEF_TYPE = 0x2FF - -MSR_AMD_EFER = 0xC0000080 ; Extended Feature Enable Register -MSR_AMD_STAR = 0xC0000081 ; SYSCALL/SYSRET Target Address Register - -CR0_PE = 0x00000001 ;protected mode -CR0_MP = 0x00000002 ;monitor fpu -CR0_EM = 0x00000004 ;fpu emulation -CR0_TS = 0x00000008 ;task switch -CR0_ET = 0x00000010 ;extension type hardcoded to 1 -CR0_NE = 0x00000020 ;numeric error -CR0_WP = 0x00010000 ;write protect -CR0_AM = 0x00040000 ;alignment check -CR0_NW = 0x20000000 ;not write-through -CR0_CD = 0x40000000 ;cache disable -CR0_PG = 0x80000000 ;paging - - -CR4_VME = 0x000001 -CR4_PVI = 0x000002 -CR4_TSD = 0x000004 -CR4_DE = 0x000008 -CR4_PSE = 0x000010 -CR4_PAE = 0x000020 -CR4_MCE = 0x000040 -CR4_PGE = 0x000080 -CR4_PCE = 0x000100 -CR4_OSFXSR = 0x000200 -CR4_OSXMMEXPT = 0x000400 -CR4_OSXSAVE = 0x040000 - -XCR0_FPU_MMX = 0x0001 -XCR0_SSE = 0x0002 -XCR0_AVX = 0x0004 -XCR0_MPX = 0x0018 -XCR0_AVX512 = 0x00e0 - -MXCSR_IE = 0x0001 -MXCSR_DE = 0x0002 -MXCSR_ZE = 0x0004 -MXCSR_OE = 0x0008 -MXCSR_UE = 0x0010 -MXCSR_PE = 0x0020 -MXCSR_DAZ = 0x0040 -MXCSR_IM = 0x0080 -MXCSR_DM = 0x0100 -MXCSR_ZM = 0x0200 -MXCSR_OM = 0x0400 -MXCSR_UM = 0x0800 -MXCSR_PM = 0x1000 -MXCSR_FZ = 0x8000 - -MXCSR_INIT = MXCSR_IM + MXCSR_DM + MXCSR_ZM + MXCSR_OM + MXCSR_UM + MXCSR_PM - -EFLAGS_CF = 0x000001 ; carry flag -EFLAGS_PF = 0x000004 ; parity flag -EFLAGS_AF = 0x000010 ; auxiliary flag -EFLAGS_ZF = 0x000040 ; zero flag -EFLAGS_SF = 0x000080 ; sign flag -EFLAGS_TF = 0x000100 ; trap flag -EFLAGS_IF = 0x000200 ; interrupt flag -EFLAGS_DF = 0x000400 ; direction flag -EFLAGS_OF = 0x000800 ; overflow flag -EFLAGS_IOPL = 0x003000 ; i/o priviledge level -EFLAGS_NT = 0x004000 ; nested task flag -EFLAGS_RF = 0x010000 ; resume flag -EFLAGS_VM = 0x020000 ; virtual 8086 mode flag -EFLAGS_AC = 0x040000 ; alignment check flag -EFLAGS_VIF = 0x080000 ; virtual interrupt flag -EFLAGS_VIP = 0x100000 ; virtual interrupt pending -EFLAGS_ID = 0x200000 ; id flag - -IRQ_PIC = 0 -IRQ_APIC = 1 - -struct TSS - _back rw 2 - _esp0 rd 1 - _ss0 rw 2 - _esp1 rd 1 - _ss1 rw 2 - _esp2 rd 1 - _ss2 rw 2 - _cr3 rd 1 - _eip rd 1 - _eflags rd 1 - _eax rd 1 - _ecx rd 1 - _edx rd 1 - _ebx rd 1 - _esp rd 1 - _ebp rd 1 - _esi rd 1 - _edi rd 1 - _es rw 2 - _cs rw 2 - _ss rw 2 - _ds rw 2 - _fs rw 2 - _gs rw 2 - _ldt rw 2 - _trap rw 1 - _io rw 1 - rb 24 - _io_map_0 rb 4096 - _io_map_1 rb 4096 -ends - -DRIVE_DATA_SIZE = 16 - -OS_BASE = 0x80000000 - -window_data = OS_BASE + 0x0001000 - -TASK_TABLE = OS_BASE + 0x0003000 -;CURRENT_TASK = OS_BASE + 0x0003000 -;TASK_COUNT = OS_BASE + 0x0003004 -TASK_BASE = OS_BASE + 0x0003010 -TASK_DATA = OS_BASE + 0x0003020 -;TASK_EVENT = OS_BASE + 0x0003020 - -CDDataBuf = OS_BASE + 0x0005000 - -;unused 0x6000 - 0x8fff - -BOOT_VARS = 0x9000 - -idts = OS_BASE + 0x000B100 -WIN_STACK = OS_BASE + 0x000C000 -WIN_POS = OS_BASE + 0x000C400 -FDD_BUFF = OS_BASE + 0x000D000 ;512 - -WIN_TEMP_XY = OS_BASE + 0x000F300 -KEY_COUNT = OS_BASE + 0x000F400 -KEY_BUFF = OS_BASE + 0x000F401 ; 120*2 + 2*2 = 244 bytes, actually 255 bytes - -BTN_COUNT = OS_BASE + 0x000F500 -BTN_BUFF = OS_BASE + 0x000F501 - - -BTN_ADDR = OS_BASE + 0x000FE88 -MEM_AMOUNT = OS_BASE + 0x000FE8C - -SYS_SHUTDOWN = OS_BASE + 0x000FF00 - - -TMP_STACK_TOP = 0x007CC00 - -sys_proc = OS_BASE + 0x007E000 - -SLOT_BASE = OS_BASE + 0x0080000 - -VGABasePtr = OS_BASE + 0x00A0000 - -virtual at OS_BASE + 0x05FFF80 - tss TSS -end virtual - -HEAP_BASE = OS_BASE + 0x0800000 -HEAP_MIN_SIZE = 0x01000000 - -page_tabs = 0xFDC00000 -app_page_tabs = 0xFDC00000 -kernel_tabs = page_tabs + (OS_BASE shr 10) ;0xFDE00000 -master_tab = page_tabs + (page_tabs shr 10) ;0xFDFF70000 - -LFB_BASE = 0xFE000000 - - -new_app_base = 0; - -twdw = TASK_TABLE - window_data - -std_application_base_address = new_app_base -RING0_STACK_SIZE = 0x2000 - -REG_SS = RING0_STACK_SIZE - 4 -REG_APP_ESP = RING0_STACK_SIZE - 8 -REG_EFLAGS = RING0_STACK_SIZE - 12 -REG_CS = RING0_STACK_SIZE - 16 -REG_EIP = RING0_STACK_SIZE - 20 -REG_EAX = RING0_STACK_SIZE - 24 -REG_ECX = RING0_STACK_SIZE - 28 -REG_EDX = RING0_STACK_SIZE - 32 -REG_EBX = RING0_STACK_SIZE - 36 -REG_ESP = RING0_STACK_SIZE - 40 ;RING0_STACK_SIZE-20 -REG_EBP = RING0_STACK_SIZE - 44 -REG_ESI = RING0_STACK_SIZE - 48 -REG_EDI = RING0_STACK_SIZE - 52 -REG_RET = RING0_STACK_SIZE - 56 ;irq0.return - - -PAGE_SIZE = 4096 - -PG_UNMAP = 0x000 -PG_READ = 0x001 -PG_WRITE = 0x002 -PG_USER = 0x004 -PG_PCD = 0x008 -PG_PWT = 0x010 -PG_ACCESSED = 0x020 -PG_DIRTY = 0x040 -PG_PAT = 0x080 -PG_GLOBAL = 0x100 -PG_SHARED = 0x200 - -PG_SWR = 0x003 ; PG_WRITE + PG_READ -PG_UR = 0x005 ; PG_USER + PG_READ -PG_UWR = 0x007 ; PG_USER + PG_WRITE + PG_READ -PG_NOCACHE = 0x018 ; PG_PCD + PG_PWT - -PDE_LARGE = 0x080 - -MEM_WB = 6 ; write-back memory -MEM_WC = 1 ; write combined memory -MEM_UC = 0 ; uncached memory - -PAT_WB = 0x000 -PAT_WC = 0x008 -PAT_UCM = 0x010 -PAT_UC = 0x018 - -PAT_TYPE_UC = 0 -PAT_TYPE_WC = 1 -PAT_TYPE_WB = 6 -PAT_TYPE_UCM = 7 - -PAT_VALUE = 0x00070106; (UC<<24)|(UCM<<16)|(WC<<8)|WB - -MAX_MEMMAP_BLOCKS = 32 - -EVENT_REDRAW = 0x00000001 -EVENT_KEY = 0x00000002 -EVENT_BUTTON = 0x00000004 -EVENT_BACKGROUND = 0x00000010 -EVENT_MOUSE = 0x00000020 -EVENT_IPC = 0x00000040 -EVENT_NETWORK = 0x00000080 -EVENT_DEBUG = 0x00000100 -EVENT_NETWORK2 = 0x00000200 -EVENT_EXTENDED = 0x00000400 - -EV_INTR = 1 - -STDIN_FILENO = 0 -STDOUT_FILENO = 1 -STDERR_FILENO = 2 - -SYSTEM_SHUTDOWN = 2 -SYSTEM_REBOOT = 3 -SYSTEM_RESTART = 4 - -BLIT_CLIENT_RELATIVE = 0x20000000 - -struct SYSCALL_STACK - _eip dd ? - _edi dd ? ; +4 - _esi dd ? ; +8 - _ebp dd ? ; +12 - _esp dd ? ; +16 - _ebx dd ? ; +20 - _edx dd ? ; +24 - _ecx dd ? ; +28 - _eax dd ? ; +32 -ends - -struct LHEAD - next dd ? ;next object in list - prev dd ? ;prev object in list -ends - -struct MUTEX_WAITER - list LHEAD - task dd ? - type dd ? -ends - -struct MUTEX - wait_list LHEAD - count dd ? -ends - -struct RWSEM - wait_list LHEAD - count dd ? -ends - -struct FUTEX - list LHEAD - magic dd ? - handle dd ? - destroy dd ? - - wait_list LHEAD - pointer dd ? - flags dd ? -ends - -FUTEX_INIT = 0 -FUTEX_DESTROY = 1 -FUTEX_WAIT = 2 -FUTEX_WAKE = 3 - -struct FILED - list LHEAD - magic rd 1 - handle rd 1 - destroy rd 1 - mode rd 1 - file rd 1 -ends - -struct PIPE - pipe_ops rd 1 - buffer rd 1 - readers rd 1 - writers rd 1 - - pipe_lock MUTEX - count rd 1 - - read_end rd 1 - write_end rd 1 - rlist LHEAD - wlist LHEAD -ends - -struct PROC - list LHEAD - thr_list LHEAD - heap_lock MUTEX - heap_base rd 1 - heap_top rd 1 - mem_used rd 1 - dlls_list_ptr rd 1 - pdt_0_phys rd 1 - pdt_1_phys rd 1 - io_map_0 rd 1 - io_map_1 rd 1 - - ht_lock rd 1 - ht_free rd 1 ;htab[0] stdin - ht_next rd 1 ;htab[1] stdout - htab rd 1024-PROC.htab/4 ;htab[2] stderr - pdt_0 rd 1024 -ends - -struct DBG_REGS - dr0 dd ? - dr1 dd ? - dr2 dd ? - dr3 dd ? - dr7 dd ? -ends - -struct POINT - x dd ? - y dd ? -ends - -struct RECT - left dd ? - top dd ? - right dd ? - bottom dd ? -ends - -struct BOX - left dd ? - top dd ? - width dd ? - height dd ? -ends - -; Fields, marked as R now not used, but will be used soon, -; when legacy TASKDATA structure will be deleted -struct APPDATA - app_name rb 11 - rb 5 - - list LHEAD ;+16 - process dd ? ;+24 - fpu_state dd ? ;+28 - exc_handler dd ? ;+32 - except_mask dd ? ;+36 - pl0_stack dd ? ;+40 - cursor dd ? ;+44 - fd_ev dd ? ;+48 - bk_ev dd ? ;+52 - fd_obj dd ? ;+56 - bk_obj dd ? ;+60 - saved_esp dd ? ;+64 - io_map rd 2 ;+68 - dbg_state dd ? ;+76 - cur_dir dd ? ;+80 - wait_timeout dd ? ;+84 - saved_esp0 dd ? ;+88 - wait_begin dd ? ;+92 +++ - wait_test dd ? ;+96 +++ - wait_param dd ? ;+100 +++ - tls_base dd ? ;+104 - event_mask dd ? ;+108 ; R stores event types allowed for task - tid dd ? ;+112 ; R thread id - draw_bgr_x dd ? ;+116 - draw_bgr_y dd ? ;+120 - state db ? ;+124 ; R thread state - db ? ;+125 - dw ? ;+126 - wnd_shape dd ? ;+128 - wnd_shape_scale dd ? ;+132 - mem_start dd ? ;+136 ; R - counter_sum dd ? ;+140 ; R - saved_box BOX ;+144 - ipc_start dd ? ;+160 - ipc_size dd ? ;+164 - occurred_events dd ? ;+168 ; mask which accumulates occurred events - debugger_slot dd ? ;+172 - terminate_protection dd ? ;+176 - keyboard_mode db ? ;+180 - captionEncoding db ? - rb 2 - exec_params dd ? ;+184 - dbg_event_mem dd ? ;+188 - dbg_regs DBG_REGS ;+192 - wnd_caption dd ? ;+212 - wnd_clientbox BOX ;+216 - priority dd ? ;+232 - in_schedule LHEAD ;+236 - counter_add dd ? ;+244 ; R - cpu_usage dd ? ;+248 ; R - dd ? ;+252 -ends - -assert sizeof.APPDATA = 256 - -APP_OBJ_OFFSET = 48 -APP_EV_OFFSET = 40 - -; Note: in future TASKDATA will be merged into APPDATA -struct TASKDATA - event_mask dd ? ;+0 mask which stores event types allowed for task - pid dd ? ;+4 - dw ? ;+8 - state db ? ;+10 - db ? ;+11 - dw ? ;+12 - wnd_number db ? ;+14 - db ? ;+15 - mem_start dd ? ;+16 - counter_sum dd ? ;+20 - counter_add dd ? ;+24 - cpu_usage dd ? ;+28 -ends - -; Thread states: -TSTATE_RUNNING = 0 -TSTATE_RUN_SUSPENDED = 1 -TSTATE_WAIT_SUSPENDED = 2 -TSTATE_ZOMBIE = 3 -TSTATE_TERMINATING = 4 -TSTATE_WAITING = 5 -TSTATE_FREE = 9 - -; Window constants: -WSTATE_NORMAL = 00000000b -WSTATE_MAXIMIZED = 00000001b -WSTATE_MINIMIZED = 00000010b -WSTATE_ROLLEDUP = 00000100b - -WSTATE_REDRAW = 00000001b -WSTATE_WNDDRAWN = 00000010b - -WSTYLE_HASCAPTION = 00010000b -WSTYLE_CLIENTRELATIVE = 00100000b - -ZPOS_DESKTOP = -2 -ZPOS_ALWAYS_BACK = -1 -ZPOS_NORMAL = 0 -ZPOS_ALWAYS_TOP = 1 ;ZPOS_ALWAYS_TOP is always last and has max number! - -; Window structure: -struct WDATA - box BOX - cl_workarea dd ? - cl_titlebar dd ? - cl_frames dd ? - z_modif db ? - fl_wstate db ? - fl_wdrawn db ? - fl_redraw db ? -ends - -label WDATA.fl_wstyle byte at WDATA.cl_workarea + 3 - -assert sizeof.WDATA = 32 - -struct SYS_VARS - bpp dd ? - scanline dd ? - vesa_mode dd ? - x_res dd ? - y_res dd ? -ends - -struct APPOBJ ; common object header - magic dd ? ; - destroy dd ? ; internal destructor - fd dd ? ; next object in list - bk dd ? ; prev object in list - pid dd ? ; owner id -ends - -struct CURSOR APPOBJ - base dd ? ;allocated memory - hot_x dd ? ;hotspot coords - hot_y dd ? - - list_next dd ? ;next cursor in cursor list - list_prev dd ? ;prev cursor in cursor list - dev_obj dd ? ;device depended data -ends - - -struct EVENT APPOBJ - id dd ? ;event uid - state dd ? ;internal flags - code dd ? - rd 5 -ends - - -struct SMEM - bk dd ? - fd dd ? ;+4 - base dd ? ;+8 - size dd ? ;+12 - access dd ? ;+16 - refcount dd ? ;+20 - name rb 32 ;+24 -ends - -struct SMAP APPOBJ - base dd ? ;mapped base - parent dd ? ;SMEM -ends - -struct DLLDESCR - bk dd ? - fd dd ? ;+4 - data dd ? ;+8 - size dd ? ;+12 - timestamp dq ? - refcount dd ? - defaultbase dd ? - coff_hdr dd ? - symbols_ptr dd ? - symbols_num dd ? - symbols_lim dd ? - exports dd ? ;export table - name rb 260 -ends - -struct HDLL - fd dd ? ;next object in list - bk dd ? ;prev object in list - pid dd ? ;owner id - - base dd ? ;mapped base - size dd ? ;mapped size - refcount dd ? ;reference counter for this process and this lib - parent dd ? ;DLLDESCR -ends - -struct DQ - lo dd ? - hi dd ? -ends - -struct e820entry - addr DQ ? - size DQ ? - type dd ? -ends - -RD_LOAD_FROM_FLOPPY = 1 -RD_LOAD_FROM_HD = 2 -RD_LOAD_FROM_MEMORY = 3 -RD_LOAD_FROM_FORMAT = 4 -RD_LOAD_FROM_NONE = 5 - -struct boot_data - bpp db ? ; bits per pixel - pitch dw ? ; scanline length - db ? - dd ? - vesa_mode dw ? - x_res dw ? - y_res dw ? - dw ? - dd ? - bank_switch dd ? ; Vesa 1.2 pm bank switch - lfb dd ? ; Vesa 2.0 LFB address - mtrr db ? ; 0 or 1: enable MTRR graphics acceleration - launcher_start db ? ; 0 or 1: start the first app (right now it's - ; LAUNCHER) after kernel is loaded - debug_print db ? ; if nonzero, duplicates debug output to the screen - dma db ? ; DMA write: 1=yes, 2=no - pci_data rb 8 - rb 8 - shutdown_type db ? ; see sysfn 18.9 - rb 15 - apm_entry dd ? ; entry point of APM BIOS - apm_version dw ? ; BCD - apm_flags dw ? - rb 8 - apm_code_32 dw ? - apm_code_16 dw ? - apm_data_16 dw ? - rd_load_from db ? ; Device to load ramdisk from, RD_LOAD_FROM_* - db ? - kernel_restart dw ? - sys_disk dw ? ; Device to mount on /sys/, see loader_doc.txt for details - acpi_rsdp dd ? - syspath rb 0x17 - devicesdat_data dd ? - devicesdat_size dd ? - bios_hd_cnt db ? ; number of BIOS hard disks - bios_hd rb 0x80 ; BIOS hard disks - memmap_block_cnt dd ? ; available physical memory map: number of blocks - memmap_blocks e820entry - rb sizeof.e820entry * (MAX_MEMMAP_BLOCKS - 1) -ends - -virtual at BOOT_VARS - BOOT_LO boot_data -end virtual -virtual at OS_BASE + BOOT_VARS - BOOT boot_data -end virtual - -MAX_SCREEN_WIDTH = 3840 -MAX_SCREEN_HEIGHT = 2160 - -struct display_t - x dd ? - y dd ? - width dd ? - height dd ? - bits_per_pixel dd ? - vrefresh dd ? - current_lfb dd ? - lfb_pitch dd ? - - win_map_lock RWSEM - win_map dd ? - win_map_pitch dd ? - win_map_size dd ? - - modes dd ? - ddev dd ? - connector dd ? - crtc dd ? - - cr_list.next dd ? - cr_list.prev dd ? - - cursor dd ? - - init_cursor dd ? - select_cursor dd ? - show_cursor dd ? - move_cursor dd ? - restore_cursor dd ? - disable_mouse dd ? - mask_seqno dd ? - check_mouse dd ? - check_m_pixel dd ? - - bytes_per_pixel dd ? -ends - -struct DISPMODE - width dw ? - height dw ? - bpp dw ? - freq dw ? -ends - - -struct PCIDEV - bk dd ? - fd dd ? - vendor_device_id dd ? - class dd ? - devfn db ? - bus db ? - rb 2 - owner dd ? ; pointer to SRV or 0 -ends - -struct IDE_DATA - ProgrammingInterface dd ? - Interrupt dw ? - RegsBaseAddres dw ? - BAR0_val dw ? - BAR1_val dw ? - BAR2_val dw ? - BAR3_val dw ? - dma_hdd_channel_1 db ? - dma_hdd_channel_2 db ? - pcidev dd ? ; pointer to corresponding PCIDEV structure -ends - -struct IDE_CACHE - pointer dd ? - size dd ? ; not use - data_pointer dd ? - system_data_size dd ? ; not use - appl_data_size dd ? ; not use - system_data dd ? - appl_data dd ? - system_sad_size dd ? - appl_sad_size dd ? - search_start dd ? - appl_search_start dd ? -ends - -struct IDE_DEVICE - UDMA_possible_modes db ? - UDMA_set_mode db ? -ends - -; The following macro assume that we are on uniprocessor machine. -; Serious work is needed for multiprocessor machines. -macro spin_lock_irqsave spinlock -{ - pushf - cli -} -macro spin_unlock_irqrestore spinlock -{ - popf -} -macro spin_lock_irq spinlock -{ - cli -} -macro spin_unlock_irq spinlock -{ - sti -} - -struct MEM_STATE - mutex MUTEX - smallmap dd ? - treemap dd ? - topsize dd ? - top dd ? - smallbins rd 4*32 - treebins rd 32 -ends - -struct PG_DATA - mem_amount dd ? - vesa_mem dd ? - pages_count dd ? - pages_free dd ? - pages_faults dd ? - pagemap_size dd ? - kernel_pages dd ? - kernel_tables dd ? - sys_page_dir dd ? - mutex MUTEX -ends - -struct SRV - srv_name rb 16 ;ASCIIZ string - magic dd ? ;+0x10 ;'SRV ' - size dd ? ;+0x14 ;size of structure SRV - fd dd ? ;+0x18 ;next SRV descriptor - bk dd ? ;+0x1C ;prev SRV descriptor - base dd ? ;+0x20 ;service base address - entry dd ? ;+0x24 ;service START function - srv_proc dd ? ;+0x28 ;user mode service handler - srv_proc_ex dd ? ;+0x2C ;kernel mode service handler -ends - -struct USBSRV - srv SRV - usb_func dd ? -ends - -struct USBFUNC - strucsize dd ? - add_device dd ? - device_disconnect dd ? -ends - -DRV_ENTRY = 1 -DRV_EXIT = -1 - -struct COFF_HEADER - machine dw ? - nSections dw ? - DataTime dd ? - pSymTable dd ? - nSymbols dd ? - optHeader dw ? - flags dw ? -ends - -struct COFF_SECTION - Name rb 8 - VirtualSize dd ? - VirtualAddress dd ? - SizeOfRawData dd ? - PtrRawData dd ? - PtrReloc dd ? - PtrLinenumbers dd ? - NumReloc dw ? - NumLinenum dw ? - Characteristics dd ? -ends - -struct COFF_RELOC - VirtualAddress dd ? - SymIndex dd ? - Type dw ? -ends - -struct COFF_SYM - Name rb 8 - Value dd ? - SectionNumber dw ? - Type dw ? - StorageClass db ? - NumAuxSymbols db ? -ends - -struct STRIPPED_PE_HEADER - Signature dw ? - Characteristics dw ? - AddressOfEntryPoint dd ? - ImageBase dd ? - SectionAlignmentLog db ? - FileAlignmentLog db ? - MajorOSVersion db ? - MinorOSVersion db ? - SizeOfImage dd ? - SizeOfStackReserve dd ? - SizeOfHeapReserve dd ? - SizeOfHeaders dd ? - Subsystem db ? - NumberOfRvaAndSizes db ? - NumberOfSections dw ? -ends -STRIPPED_PE_SIGNATURE = 0x4503 ; 'PE' xor 'S' -SPE_DIRECTORY_IMPORT = 0 -SPE_DIRECTORY_EXPORT = 1 -SPE_DIRECTORY_BASERELOC = 2 - -struct IOCTL - handle dd ? - io_code dd ? - input dd ? - inp_size dd ? - output dd ? - out_size dd ? -ends - -struct IRQH - list LHEAD - handler dd ? ;handler roututine - data dd ? ;user-specific data - num_ints dd ? ;how many times handled -ends - diff --git a/kernel/branches/Kolibri-F/core/Tupfile.lua b/kernel/branches/Kolibri-F/core/Tupfile.lua deleted file mode 100644 index 7e1761c88..000000000 --- a/kernel/branches/Kolibri-F/core/Tupfile.lua +++ /dev/null @@ -1,3 +0,0 @@ -if tup.getconfig("NO_FASM") ~= "" then return end -tup.rule("mtrrtest.asm", "fasm %f %o", "mtrrtest.exe") -tup.rule("test_malloc.asm", "fasm %f %o", "test_malloc") diff --git a/kernel/branches/Kolibri-F/core/apic.inc b/kernel/branches/Kolibri-F/core/apic.inc deleted file mode 100644 index 21fa3c4b3..000000000 --- a/kernel/branches/Kolibri-F/core/apic.inc +++ /dev/null @@ -1,567 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -MAX_IOAPICS = 2 - -uglobal -IRQ_COUNT rd MAX_IOAPICS -irq_mode rd 1 ; PIC/(IO)APIC -IOAPIC_base rd MAX_IOAPICS -ioapic_gsi_base rd MAX_IOAPICS ; zero-based, i.e. not vector -ioapic_cnt dd ? ; from MADT aka APIC table -ioapic_cur dd ? -LAPIC_BASE rd 1 -endg - -APIC_ID = 0x20 -APIC_TPR = 0x80 -APIC_EOI = 0xb0 -APIC_LDR = 0xd0 -APIC_DFR = 0xe0 -APIC_SVR = 0xf0 -APIC_ISR = 0x100 -APIC_ESR = 0x280 -APIC_ICRL = 0x300 -APIC_ICRH = 0x310 -APIC_LVT_LINT0 = 0x350 -APIC_LVT_LINT1 = 0x360 -APIC_LVT_err = 0x370 - -; APIC timer -APIC_LVT_timer = 0x320 -APIC_timer_div = 0x3e0 -APIC_timer_init = 0x380 -APIC_timer_cur = 0x390 -; IOAPIC -IOAPIC_ID = 0x0 -IOAPIC_VER = 0x1 -IOAPIC_ARB = 0x2 -IOAPIC_REDTBL = 0x10 - -align 4 -APIC_init: - push ebx - mov [irq_mode], IRQ_PIC - - cmp [acpi_ioapic_base], 0 - jz .no_apic - - cmp [acpi_lapic_base], 0 - jz .no_apic - -; non-UEFI loaders don't load DEVICES.DAT and don't initialize [acpi_dev_size] -if defined UEFI - cmp [acpi_dev_size], 0 - jz @f - stdcall map_io_mem, [acpi_dev_data], [acpi_dev_size], PG_SWR - mov [acpi_dev_data], eax - jmp .loaded -@@: -end if - - stdcall load_file, dev_data_path - test eax, eax - jz .no_apic - - mov [acpi_dev_data], eax - mov [acpi_dev_size], ebx -.loaded: - -; IOAPIC init - xor ebx, ebx -@@: - stdcall map_io_mem, [acpi_ioapic_base+ebx*4], 0x20, PG_GLOBAL+PG_NOCACHE+PG_SWR - mov [IOAPIC_base+ebx*4], eax - inc ebx - cmp ebx, [ioapic_cnt] - jnz @b - - call IRQ_mask_all - mov [ioapic_cur], 0 -.next_ioapic: - mov edx, [ioapic_cur] - mov eax, IOAPIC_VER - call IOAPIC_read - shr eax, 16 - inc al - movzx eax, al - mov ecx, [ioapic_gsi_base+edx*4] - cmp ecx, IRQ_RESERVED - jae .lapic_init - add ecx, eax - sub ecx, IRQ_RESERVED - jbe @f - sub eax, ecx -@@: - mov [IRQ_COUNT+edx*4], eax - - ; Reroute IOAPIC & mask all interrupts - xor ecx, ecx - mov eax, IOAPIC_REDTBL -.next_irq: - mov ebx, eax - call IOAPIC_read - mov ah, 0x08; Delivery Mode: Fixed, Destination Mode: Logical - mov al, cl - add al, 0x20; vector - add eax, [ioapic_gsi_base+edx*4] - or eax, 0x1a000; Mask Interrupt, level-triggered active-low - cmp [ioapic_cur], 0 - jnz @f - cmp ecx, 16 - jae @f - and eax, NOT 0xa000 ; edge-triggered active-high for IRQ0-15 -@@: - xchg eax, ebx - call IOAPIC_write - inc eax - mov ebx, eax - call IOAPIC_read - or eax, 0xff000000; Destination Field - xchg eax, ebx - call IOAPIC_write - inc eax - inc ecx - cmp ecx, [IRQ_COUNT+edx*4] - jb .next_irq - - inc [ioapic_cur] - inc edx - cmp edx, [ioapic_cnt] - jnz .next_ioapic - -.lapic_init: - call LAPIC_init - - mov [irq_mode], IRQ_APIC - - mov al, 0x70 - out 0x22, al - mov al, 1 - out 0x23, al - - call pci_irq_fixup -.no_apic: - pop ebx - ret - -;=========================================================== -align 4 -LAPIC_init: - - mov eax, [LAPIC_BASE] - test eax, eax - jnz @f - stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_GLOBAL+PG_NOCACHE+PG_SWR - mov [LAPIC_BASE], eax -@@: - mov esi, eax - - ; Program Destination Format Register for Flat mode. - mov eax, [esi + APIC_DFR] - or eax, 0xf0000000 - mov [esi + APIC_DFR], eax - - ; Program Logical Destination Register. - mov eax, [esi + APIC_LDR] - ;and eax, 0xff000000 - and eax, 0x00ffffff - or eax, 0x01000000;!!!!!!!!!!!! - mov [esi + APIC_LDR], eax - - ; Task Priority Register initialization. - mov eax, [esi + APIC_TPR] - and eax, 0xffffff00 - mov [esi + APIC_TPR], eax - - ; Flush the queue - mov edx, 0 -.nxt2: - mov ecx, 32 - mov eax, [esi + APIC_ISR + edx] -.nxt: - shr eax, 1 - jnc @f - mov dword [esi + APIC_EOI], 0; EOI -@@: - loop .nxt - - add edx, 0x10 - cmp edx, 0x170 - jbe .nxt2 - - ; Spurious-Interrupt Vector Register initialization. - mov eax, [esi + APIC_SVR] - or eax, 0x1ff - and eax, 0xfffffdff - mov [esi + APIC_SVR], eax - - ; Initialize LVT LINT0 register. (INTR) - mov eax, 0x00700 - ; mov eax, 0x10700 - mov [esi + APIC_LVT_LINT0], eax - - ; Initialize LVT LINT1 register. (NMI) - mov eax, 0x00400 - mov [esi + APIC_LVT_LINT1], eax - - ; Initialize LVT Error register. - mov eax, [esi + APIC_LVT_err] - or eax, 0x10000; bit 16 - mov [esi + APIC_LVT_err], eax - - ; LAPIC timer - ; pre init - mov dword[esi + APIC_timer_div], 1011b; 1 - mov dword[esi + APIC_timer_init], 0xffffffff; max val - push esi - mov esi, 640 ; wait 0.64 sec - call delay_ms - pop esi - mov eax, [esi + APIC_timer_cur]; read current tick couner - xor eax, 0xffffffff ; eax = 0xffffffff - eax - shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec - - ; Start (every 0.01 sec) - mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20 - mov dword[esi + APIC_timer_init], eax - -.done: - ret - -;=========================================================== -; IOAPIC implementation -align 4 -IOAPIC_read: -; in : EAX - IOAPIC register -; out: EAX - readed value - push esi - mov esi, [ioapic_cur] - mov esi, [IOAPIC_base+esi*4] - mov [esi], eax - mov eax, [esi + 0x10] - pop esi - ret - -align 4 -IOAPIC_write: -; in : EAX - IOAPIC register -; EBX - value -; out: none - push esi - mov esi, [ioapic_cur] - mov esi, [IOAPIC_base+esi*4] - mov [esi], eax - mov [esi + 0x10], ebx - pop esi - ret -;=========================================================== -; Remap all IRQ to 0x20+ Vectors -; IRQ0 to vector 0x20, IRQ1 to vector 0x21.... -align 4 -PIC_init: - mov [IRQ_COUNT], 16 - cli - mov al, 0x11 ; icw4, edge triggered - out 0x20, al - out 0xA0, al - - mov al, 0x20 ; generate 0x20 + - out 0x21, al - mov al, 0x28 ; generate 0x28 + - out 0xA1, al - - mov al, 0x04 ; slave at irq2 - out 0x21, al - mov al, 0x02 ; at irq9 - out 0xA1, al - - mov al, 0x01 ; 8086 mode - out 0x21, al - out 0xA1, al - - call IRQ_mask_all - ret - -; ----------------------------------------- -; TIMER SET TO 1/100 S -align 4 -PIT_init: - mov al, 0x34 ; set to 100Hz - out 0x43, al - mov al, 0x9b ; lsb 1193180 / 1193 - out 0x40, al - mov al, 0x2e ; msb - out 0x40, al - ret - -; ----------------------------------------- -align 4 -unmask_timer: - cmp [irq_mode], IRQ_APIC - je @f - - stdcall enable_irq, 0 - ret -@@: - ; use PIT - ; in some systems PIT no connected to IOAPIC - ; mov eax, 0x14 - ; call IOAPIC_read - ; mov ah, 0x09 ; Delivery Mode: Lowest Priority, Destination Mode: Logical - ; mov al, 0x20 - ; or eax, 0x10000 ; Mask Interrupt - ; mov ebx, eax - ; mov eax, 0x14 - ; call IOAPIC_write - ; stdcall enable_irq, 2 - ; ret - - ; use LAPIC timer - mov esi, [LAPIC_BASE] - mov eax, [esi + APIC_LVT_timer] - and eax, 0xfffeffff - mov [esi + APIC_LVT_timer], eax - ret - -; ----------------------------------------- -; Disable all IRQ -align 4 -IRQ_mask_all: - cmp [irq_mode], IRQ_APIC - je .APIC - - mov al, 0xFF - out 0x21, al - out 0xA1, al - mov ecx, 0x1000 - ret -.APIC: - cmp [IOAPIC_base], 0 - jz .done - mov [ioapic_cur], 0 -.next_ioapic: - mov edx, [ioapic_cur] - mov ecx, [IRQ_COUNT+edx*4] - mov eax, 0x10 -@@: - mov ebx, eax - call IOAPIC_read - or eax, 0x10000; bit 16 - xchg eax, ebx - call IOAPIC_write - inc eax - inc eax - loop @b - - inc [ioapic_cur] - inc edx - cmp edx, [ioapic_cnt] - jnz .next_ioapic -.done: - ret - -; ----------------------------------------- -; End Of Interrupt -; cl - IRQ number -align 4 -irq_eoi: ; __fastcall - cmp [irq_mode], IRQ_APIC - je .APIC - - cmp cl, 8 - mov al, 0x20 - jb @f - out 0xa0, al -@@: - out 0x20, al - ret - -.APIC: - mov eax, [LAPIC_BASE] - mov dword [eax + APIC_EOI], 0; EOI - ret - -; ----------------------------------------- -; from dll.inc -align 4 -proc enable_irq stdcall, irq_line:dword - mov ebx, [irq_line] - cmp [irq_mode], IRQ_APIC - je .APIC - - mov edx, 0x21 - cmp ebx, 8 - jb @F - - mov edx, 0xA1 - sub ebx, 8 -@@: - in al, dx - btr eax, ebx - out dx, al - ret -.APIC: - push [ioapic_cur] - xor eax, eax -.next_ioapic: - mov ecx, [ioapic_gsi_base+eax*4] - add ecx, [IRQ_COUNT+eax*4] - cmp ebx, ecx - jb .found - inc eax - cmp eax, [ioapic_cnt] - jnz .next_ioapic - jmp .done -.found: - mov [ioapic_cur], eax - sub ebx, [ioapic_gsi_base+eax*4] - shl ebx, 1 - add ebx, 0x10 - mov eax, ebx - call IOAPIC_read - and eax, 0xfffeffff; bit 16 - xchg eax, ebx - call IOAPIC_write -.done: - pop [ioapic_cur] - ret -endp - -proc disable_irq stdcall, irq_line:dword - mov ebx, [irq_line] - cmp [irq_mode], IRQ_APIC - je .APIC - - mov edx, 0x21 - cmp ebx, 8 - jb @F - - mov edx, 0xA1 - sub ebx, 8 -@@: - in al, dx - bts eax, ebx - out dx, al - ret -.APIC: - push [ioapic_cur] - xor eax, eax -.next_ioapic: - mov ecx, [ioapic_gsi_base+eax*4] - add ecx, [IRQ_COUNT+eax*4] - cmp ebx, ecx - jae .found - inc eax - cmp eax, [ioapic_cnt] - jnz .next_ioapic - jmp .done -.found: - mov [ioapic_cur], eax - sub ebx, [ioapic_gsi_base+eax*4] - shl ebx, 1 - add ebx, 0x10 - mov eax, ebx - call IOAPIC_read - or eax, 0x10000; bit 16 - xchg eax, ebx - call IOAPIC_write -.done: - pop [ioapic_cur] - ret -endp - -align 4 -pci_irq_fixup: - - push ebp - - mov esi, [acpi_dev_data] - mov ebx, [acpi_dev_size] - - lea edi, [esi+ebx] - -.iterate: - - cmp esi, edi - jae .done - - mov eax, [esi] - - cmp eax, -1 - je .done - - movzx ebx, al - movzx ebp, ah - - stdcall pci_read32, ebp, ebx, 0 - - cmp eax, [esi+4] - jne .skip - - mov eax, [esi+8] - stdcall pci_write8, ebp, ebx, 0x3C, eax -.skip: - add esi, 16 - jmp .iterate - -.done: -.fail: - pop ebp - ret - -align 4 -get_clock_ns: - - mov eax, [hpet_base] - test eax, eax - jz .old_tics - - push ebx - push esi - pushfd - cli - - mov ebx, eax -@@: - mov edx, [ebx+0xF4] - mov eax, [ebx+0xF0] - mov ecx, [ebx+0xF4] - cmp ecx, edx - jne @B - popfd - -;96-bit arithmetic -;ebx - low dword -;esi - medium dword -;edx - high dword - - mul [hpet_period] - mov ebx, eax - mov esi, edx - - mov eax, ecx - mul [hpet_period] - add esi, eax - adc edx, 0 - mov eax, ebx - mov ebx, esi - shrd eax, ebx, 10 - shrd esi, edx, 10 - mov edx, esi - - pop esi - pop ebx - ret - -.old_tics: - mov eax, [timer_ticks] - mov edx, 10000000 - mul edx - ret diff --git a/kernel/branches/Kolibri-F/core/clipboard.inc b/kernel/branches/Kolibri-F/core/clipboard.inc deleted file mode 100644 index da46c9323..000000000 --- a/kernel/branches/Kolibri-F/core/clipboard.inc +++ /dev/null @@ -1,167 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -;------------------------------------------------------------------------------ -align 4 -syscall_clipboard: - xor eax, eax - dec eax -; check availability of main list - cmp [clipboard_main_list], eax - je .exit_1 ; main list area not found - - test ebx, ebx ; 0 - Get the number of slots in the clipboard - jnz .1 -; get the number of slots - mov eax, [clipboard_slots] - jmp .exit_1 -;------------------------------------------------------------------------------ -align 4 -.1: - dec ebx ; 1 - Read the data from the clipboard - jnz .2 -; verify the existence of slot - cmp ecx, [clipboard_slots] - jae .exit_2 -; get a pointer to the data of slot - shl ecx, 2 - add ecx, [clipboard_main_list] - mov esi, [ecx] - mov ecx, [esi] -; allocate memory for application for copy the data of slots - push ecx - stdcall user_alloc, ecx - pop ecx -; copying data of slots - mov edi, eax - cld - rep movsb - jmp .exit_1 -;------------------------------------------------------------------------------ -align 4 -.2: - dec ebx ; 2 - Write the data to the clipboard - jnz .3 - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - stdcall is_region_userspace, edx, ecx - jnz @f - mov eax, -1 - jmp .exit_1 -@@: -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; check the lock - mov ebx, clipboard_write_lock - xor eax, eax - cmp [ebx], eax - jne .exit_2 -; lock last slot - inc eax - mov [ebx], eax -; check the overflow pointer of slots - cmp [clipboard_slots], 1024 - jae .exit_3 -; get memory for new slot - push ebx ecx edx - stdcall kernel_alloc, ecx - pop edx ecx ebx - test eax, eax - jz .exit_3 -; create a new slot - mov edi, eax - mov eax, [clipboard_slots] - shl eax, 2 - add eax, [clipboard_main_list] - mov [eax], edi -; copy the data into the slot - mov esi, edx - mov eax, ecx - cld - stosd ; store size of slot - sub ecx, 4 - add esi, 4 - rep movsb ; store slot data -; increase the counter of slots - inc [clipboard_slots] -; unlock last slot - xor eax, eax - mov [ebx], eax - jmp .exit_1 -;------------------------------------------------------------------------------ -align 4 -.3: - dec ebx ; 3 - Delete the last slot in the clipboard - jnz .4 -; check the availability of slots - mov eax, [clipboard_slots] - test eax, eax - jz .exit_2 -; check the lock - mov ebx, clipboard_write_lock - xor eax, eax - cmp [ebx], eax - jne .exit_2 -; lock last slot - inc eax - mov [ebx], eax -; decrease the counter of slots - mov eax, clipboard_slots - dec dword [eax] -; free of kernel memory allocated for the slot - mov eax, [eax] - shl eax, 2 - add eax, [clipboard_main_list] - mov eax, [eax] - push ebx - stdcall kernel_free, eax - pop ebx -; unlock last slot - xor eax, eax - mov [ebx], eax - jmp .exit_1 -;------------------------------------------------------------------------------ -align 4 -.4: - dec ebx ; 4 - Emergency discharge of clipboard - jnz .exit -; check the lock - mov ebx, clipboard_write_lock - xor eax, eax - cmp [ebx], eax - je .exit_2 - -; there should be a procedure for checking the integrity of the slots -; and I will do so in the future - -; unlock last slot - mov [ebx], eax - jmp .exit -;------------------------------------------------------------------------------ -align 4 -.exit_3: -; unlock last slot - xor eax, eax - mov [ebx], eax -.exit_2: - xor eax, eax - inc eax ; error -.exit_1: - mov [esp + 32], eax -.exit: - ret -;------------------------------------------------------------------------------ -uglobal -align 4 -clipboard_slots dd ? -clipboard_main_list dd ? -clipboard_write_lock dd ? -endg -;------------------------------------------------------------------------------ diff --git a/kernel/branches/Kolibri-F/core/conf_lib-sp.inc b/kernel/branches/Kolibri-F/core/conf_lib-sp.inc deleted file mode 100644 index 396c91fbc..000000000 --- a/kernel/branches/Kolibri-F/core/conf_lib-sp.inc +++ /dev/null @@ -1,21 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; Éste archivo debe ser editado con codificación CP866 - -ugui_mouse_speed cp850 'velocidad del ratón',0 -ugui_mouse_delay cp850 'demora del ratón',0 - -udev cp850 'disp',0 -unet cp850 'red',0 -unet_active cp850 'activa',0 -unet_addr cp850 'direc',0 -unet_mask cp850 'másc',0 -unet_gate cp850 'puer',0 diff --git a/kernel/branches/Kolibri-F/core/conf_lib.inc b/kernel/branches/Kolibri-F/core/conf_lib.inc deleted file mode 100644 index fe56a3ac6..000000000 --- a/kernel/branches/Kolibri-F/core/conf_lib.inc +++ /dev/null @@ -1,254 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;------------------------------------------------------------------------- -;Loading configuration from ini file -; {SPraid.simba} -;------------------------------------------------------------------------- - -$Revision$ - -iglobal -conf_path_sect: - db 'path',0 - -conf_fname db '/sys/sys.conf',0 -endg -; set soke kernel configuration -proc set_kernel_conf - locals - par db 30 dup(?) - endl - - pushad -;[gui] -;mouse_speed - - lea eax, [par] - push eax - invoke ini.get_str, conf_fname, ugui, ugui_mouse_speed, \ - eax,30, ugui_mouse_speed_def - pop eax - stdcall strtoint, eax - mov [mouse_speed_factor], ax - -;mouse_delay - lea eax, [par] - push eax - invoke ini.get_str, conf_fname, ugui, ugui_mouse_delay, \ - eax,30, ugui_mouse_delay_def - pop eax - stdcall strtoint, eax - mov [mouse_delay], eax - - -;midibase - lea eax, [par] - push eax - invoke ini.get_str, conf_fname, udev, udev_midibase, eax, 30, udev_midibase_def - pop eax - stdcall strtoint, eax - - cmp eax, 0x100 - jb @f - cmp eax, 0x10000 - jae @f - mov [midi_base], ax - mov [mididp], eax - inc eax - mov [midisp], eax -@@: - popad - ret -endp -iglobal -ugui db 'gui',0 -ugui_mouse_speed_def db '2',0 -ugui_mouse_delay_def db '0x00A',0 -udev_midibase db 'midibase',0 -udev_midibase_def db '0x320',0 -endg - -iglobal -if lang eq sp - include 'core/conf_lib-sp.inc' -else - ugui_mouse_speed db 'mouse_speed',0 - ugui_mouse_delay db 'mouse_delay',0 - udev db 'dev',0 - unet db 'net',0 - unet_active db 'active',0 - unet_addr db 'addr',0 - unet_mask db 'mask',0 - unet_gate db 'gate',0 -end if -unet_def db 0 -endg -; convert string to DWord -proc strtoint stdcall,strs - pushad - - mov eax, [strs] - inc eax - mov bl, [eax] - cmp bl, 'x' - je .hex - cmp bl, 'X' - je .hex - jmp .dec -.hex: - inc eax - stdcall strtoint_hex, eax - jmp .exit -.dec: - dec eax - stdcall strtoint_dec, eax -.exit: - mov [esp+28], eax - popad - ret -endp - -; convert string to DWord for decimal value -proc strtoint_dec stdcall,strs - pushad - xor edx, edx - ; поиск конца - mov esi, [strs] -@@: - lodsb - or al, al - jnz @b - mov ebx, esi - mov esi, [strs] - dec ebx - sub ebx, esi - mov ecx, 1 - -@@: - dec ebx - or ebx, ebx - jz @f - imul ecx, ecx, 10; порядок - jmp @b -@@: - - xchg ebx, ecx - - - xor ecx, ecx - - -@@: - xor eax, eax - lodsb - cmp al, 0 - je .eend - - sub al, 30h - imul ebx - add ecx, eax - push ecx - xchg eax, ebx - mov ecx, 10 - div ecx - xchg eax, ebx - pop ecx - jmp @b - -.eend: - mov [esp+28], ecx - popad - ret -endp - -;convert string to DWord for hex value -proc strtoint_hex stdcall,strs - pushad - xor edx, edx - - mov esi, [strs] - mov ebx, 1 - add esi, 1 - -@@: - lodsb - or al, al - jz @f - shl ebx, 4 - jmp @b -@@: - xor ecx, ecx - mov esi, [strs] - -@@: - xor eax, eax - lodsb - cmp al, 0 - je .eend - - cmp al, 'a' - jae .bm - cmp al, 'A' - jae .bb - jmp .cc -.bm: ; 57h - sub al, 57h - jmp .do - -.bb: ; 37h - sub al, 37h - jmp .do - -.cc: ; 30h - sub al, 30h - -.do: - imul ebx - add ecx, eax - shr ebx, 4 - - jmp @b - -.eend: - mov [esp+28], ecx - popad - ret -endp - - -; convert string to DWord for IP addres -proc do_inet_adr stdcall,strs - pushad - - mov esi, [strs] - mov ebx, 0 -.next: - push esi -@@: - lodsb - or al, al - jz @f - cmp al, '.' - jz @f - jmp @b -@@: - mov cl, al - mov [esi-1], byte 0 - ;pop eax - call strtoint_dec - rol eax, 24 - ror ebx, 8 - add ebx, eax - or cl, cl - jz @f - jmp .next -@@: - mov [esp+28], ebx - popad - ret -endp diff --git a/kernel/branches/Kolibri-F/core/debug.inc b/kernel/branches/Kolibri-F/core/debug.inc deleted file mode 100644 index 219d36635..000000000 --- a/kernel/branches/Kolibri-F/core/debug.inc +++ /dev/null @@ -1,455 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; diamond, 2006 -syscall_debug_services: - cmp ebx, 9 - ja @f - jmp dword [syscall_debug_service_services_table+ebx*4] -@@: - ret -iglobal -align 4 -syscall_debug_service_services_table: - dd debug_set_event_data - dd debug_getcontext - dd debug_setcontext - dd debug_detach - dd debug_suspend - dd debug_resume - dd debug_read_process_memory - dd debug_write_process_memory - dd debug_terminate - dd debug_set_drx -endg -debug_set_event_data: -; in: ecx = pointer -; destroys eax - mov eax, [current_slot] - mov [eax+APPDATA.dbg_event_mem], ecx - ret - -get_debuggee_slot: -; in: ecx=PID -; out: CF=1 if error -; CF=0 and eax=slot*0x20 if ok -; out: interrupts disabled - cli - mov eax, ecx - call pid_to_slot - test eax, eax - jz .ret_bad - shl eax, 5 - push ebx - mov ebx, [current_slot_idx] - cmp [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx - pop ebx - jnz .ret_bad -; clc ; automatically - ret -.ret_bad: - stc - ret - -debug_detach: -; in: ecx=pid -; destroys eax,ebx - call get_debuggee_slot - jc .ret - and dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0 - call do_resume -.ret: - sti - ret - -debug_terminate: -; in: ecx=pid - call get_debuggee_slot - jc debug_detach.ret - mov ecx, eax - shr ecx, 5 -; push 2 -; pop ebx - mov edx, esi - jmp sysfn_terminate - -debug_suspend: -; in: ecx=pid -; destroys eax,ecx -; { Patch by Coldy (rev. 7125), reason: http://board.kolibrios.org/viewtopic.php?f=1&t=1712&p=75957#p75957 -; cli -; mov eax, ecx -; call pid_to_slot -; shl eax, 5 -; jz .ret - call get_debuggee_slot - jc .ret -; } End patch - mov cl, [TASK_TABLE+eax+TASKDATA.state] ; process state - test cl, cl - jz .1 - cmp cl, 5 - jnz .ret - mov cl, 2 -.2: - mov [TASK_TABLE+eax+TASKDATA.state], cl -.ret: - sti - ret -.1: - inc ecx - jmp .2 - -do_resume: - mov cl, [TASK_TABLE+eax+TASKDATA.state] - cmp cl, 1 - jz .1 - cmp cl, 2 - jnz .ret - mov cl, 5 -.2: - mov [TASK_TABLE+eax+TASKDATA.state], cl -.ret: - ret -.1: - dec ecx - jmp .2 - -debug_resume: -; in: ecx=pid -; destroys eax,ebx - cli - mov eax, ecx - call pid_to_slot - shl eax, 5 - jz .ret - call do_resume -.ret: - sti - ret - -debug_getcontext: -; in: -; ecx=pid -; edx=sizeof(CONTEXT) -; esi->CONTEXT -; destroys eax,ebx,ecx,edx,esi,edi - - xor ebx, ebx ; 0 - get only gp regs - cmp edx, 40 - je .std_ctx - - cmp edx, 48+288 - jne .ret - - inc ebx ; 1 - get sse context - ; TODO legacy 32-bit FPU/MMX context -.std_ctx: - call get_debuggee_slot - jc .ret - - shr eax, 5 - cmp eax, [fpu_owner] - jne @f - inc bh ; set swap context flag -@@: - shl eax, 8 - mov edi, esi - mov eax, [eax+SLOT_BASE+APPDATA.pl0_stack] - lea esi, [eax+RING0_STACK_SIZE] - -.ring0: -; note that following code assumes that all interrupt/exception handlers -; save ring-3 context by pushad in this order -; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), pushad - sub esi, 8+12+20h - lodsd ;edi - mov [edi+24h], eax - lodsd ;esi - mov [edi+20h], eax - lodsd ; ebp - mov [edi+1Ch], eax - lodsd ;esp - lodsd ;ebx - mov [edi+14h], eax - lodsd ;edx - mov [edi+10h], eax - lodsd ;ecx - mov [edi+0Ch], eax - lodsd ;eax - mov [edi+8], eax - lodsd ;eip - mov [edi], eax - lodsd ;cs - lodsd ;eflags - mov [edi+4], eax - lodsd ;esp - mov [edi+18h], eax - - dec bl - js .ret - dec bl - jns .ret - - test bh, bh ; check swap flag - jz @F - - ffree st0 ; swap context -@@: - - add esi, 4 ;top of ring0 stack - ;fpu/sse context saved here - add edi, 40 - mov eax, 1 ;sse context - stosd - xor eax, eax ;reserved dword - stosd - - mov ecx, 288/4 - rep movsd ;copy sse context - -.ret: - sti - ret - -debug_setcontext: -; in: -; ecx=pid -; edx=sizeof(CONTEXT) -; esi->CONTEXT -; destroys eax,ecx,edx,esi,edi - cmp edx, 28h - jnz .ret - - call get_debuggee_slot - jc .stiret -; mov esi, edx - mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack] - lea edi, [eax+RING0_STACK_SIZE] - -.ring0: - sub edi, 8+12+20h - mov eax, [esi+24h] ;edi - stosd - mov eax, [esi+20h] ;esi - stosd - mov eax, [esi+1Ch] ;ebp - stosd - scasd - mov eax, [esi+14h] ;ebx - stosd - mov eax, [esi+10h] ;edx - stosd - mov eax, [esi+0Ch] ;ecx - stosd - mov eax, [esi+8] ;eax - stosd - mov eax, [esi] ;eip - stosd - scasd - mov eax, [esi+4] ;eflags - stosd - mov eax, [esi+18h] ;esp - stosd -.stiret: - sti -.ret: - ret - -debug_set_drx: - call get_debuggee_slot - jc .errret - mov ebp, eax - lea eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs] -; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3 -; [eax+10]=dr7 - cmp esi, OS_BASE - jae .errret - cmp dl, 3 - ja .errret - mov ecx, dr7 -;fix me - xchg ecx, edx - shr edx, cl - shr edx, cl - xchg ecx, edx - - test ecx, 2 ; bit 1+2*index = G0..G3, global break enable - jnz .errret2 - test dh, dh - jns .new -; clear breakpoint - movzx edx, dl - add edx, edx - and dword [eax+edx*2], 0 ; clear DR - btr dword [eax+10h], edx ; clear L bit - test byte [eax+10h], 55h - jnz .okret -; imul eax, ebp, tss_step/32 -; and byte [eax + tss_data + TSS._trap], not 1 - and [ebp*8 + SLOT_BASE+APPDATA.dbg_state], not 1 -.okret: - and dword [esp+32], 0 - sti - ret -.errret: - sti - mov dword [esp+32], 1 - ret -.errret2: - sti - mov dword [esp+32], 2 - ret -.new: -; add new breakpoint -; dl=index; dh=flags; esi=address - test dh, 0xF0 - jnz .errret - mov cl, dh - and cl, 3 - cmp cl, 2 - jz .errret - mov cl, dh - shr cl, 2 - cmp cl, 2 - jz .errret - - mov ebx, esi - test bl, dl - - jnz .errret - or byte [eax+10h+1], 3 ; set GE and LE flags - - movzx edx, dh - movzx ecx, dl - add ecx, ecx - bts dword [eax+10h], ecx ; set L flag - add ecx, ecx - mov [eax+ecx], ebx;esi ; set DR - shl edx, cl - mov ebx, 0xF - shl ebx, cl - not ebx - and [eax+10h+2], bx - or [eax+10h+2], dx ; set R/W and LEN fields -; imul eax, ebp, tss_step/32 -; or byte [eax + tss_data + TSS._trap], 1 - or [ebp*8 + SLOT_BASE+APPDATA.dbg_state], 1 - jmp .okret - -debug_read_process_memory: -; in: -; ecx=pid -; edx=length -; edi->buffer in debugger -; esi=address in debuggee -; out: [esp+36]=sizeof(read) -; destroys all - call get_debuggee_slot - jc .err - shr eax, 5 - mov ecx, edi - call read_process_memory - sti - mov dword [esp+32], eax - ret -.err: - or dword [esp+32], -1 - ret - -debug_write_process_memory: -; in: -; ecx=pid -; edx=length -; edi->buffer in debugger -; esi=address in debuggee -; out: [esp+36]=sizeof(write) -; destroys all - call get_debuggee_slot - jc debug_read_process_memory.err - shr eax, 5 - mov ecx, edi - call write_process_memory - sti - mov [esp+32], eax - ret - -debugger_notify: -; in: eax=debugger slot -; ecx=size of debug message -; [esp+4]..[esp+4+ecx]=message -; interrupts must be disabled! -; destroys all general registers -; interrupts remain disabled - xchg ebp, eax - mov edi, [timer_ticks] - add edi, 500 ; 5 sec timeout -.1: - mov eax, ebp - shl eax, 8 - mov esi, [SLOT_BASE+eax+APPDATA.dbg_event_mem] - test esi, esi - jz .ret -; read buffer header - push ecx - push eax - push eax - mov eax, ebp - mov ecx, esp - mov edx, 8 - call read_process_memory - cmp eax, edx - jz @f - add esp, 12 - jmp .ret -@@: - cmp dword [ecx], 0 - jg @f -.2: - pop ecx - pop ecx - pop ecx - cmp dword [current_slot_idx], 1 - jnz .notos - cmp [timer_ticks], edi - jae .ret -.notos: - sti - call change_task - cli - jmp .1 -@@: - mov edx, [ecx+8] - add edx, [ecx+4] - cmp edx, [ecx] - ja .2 -; advance buffer position - push edx - mov edx, 4 - sub ecx, edx - mov eax, ebp - add esi, edx - call write_process_memory - pop eax -; write message - mov eax, ebp - add esi, edx - add esi, [ecx+8] - add ecx, 20 - pop edx - pop edx - pop edx - call write_process_memory -; new debug event - mov eax, ebp - shl eax, BSF sizeof.APPDATA - or [SLOT_BASE+eax+APPDATA.occurred_events], EVENT_DEBUG -.ret: - ret diff --git a/kernel/branches/Kolibri-F/core/dll.inc b/kernel/branches/Kolibri-F/core/dll.inc deleted file mode 100644 index 8f1f62f49..000000000 --- a/kernel/branches/Kolibri-F/core/dll.inc +++ /dev/null @@ -1,1524 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License. ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -DRV_COMPAT = 5 ;minimal required drivers version -DRV_CURRENT = 6 ;current drivers model version - -DRV_VERSION = (DRV_COMPAT shl 16) or DRV_CURRENT -PID_KERNEL = 1 ;os_idle thread - - - -align 4 -proc get_notify stdcall, p_ev:dword - -.wait: - mov ebx, [current_slot] - test dword [ebx+APPDATA.event_mask], EVENT_NOTIFY - jz @f - and dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY - mov edi, [p_ev] - mov dword [edi], EV_INTR - mov eax, [ebx+APPDATA.event] - mov dword [edi+4], eax - ret -@@: - call change_task - jmp .wait -endp - -align 4 -proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword - push ebx - xor eax, eax - xor ebx, ebx - mov ah, byte [bus] - mov al, 6 - mov bh, byte [devfn] - mov bl, byte [reg] - call pci_read_reg - pop ebx - ret -endp - -align 4 -proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword - push ebx - xor eax, eax - xor ebx, ebx - mov ah, byte [bus] - mov al, 5 - mov bh, byte [devfn] - mov bl, byte [reg] - call pci_read_reg - pop ebx - ret -endp - -align 4 -proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword - push ebx - xor eax, eax - xor ebx, ebx - mov ah, byte [bus] - mov al, 4 - mov bh, byte [devfn] - mov bl, byte [reg] - call pci_read_reg - pop ebx - ret -endp - -align 4 -proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword - push ebx - xor eax, eax - xor ebx, ebx - mov ah, byte [bus] - mov al, 8 - mov bh, byte [devfn] - mov bl, byte [reg] - mov ecx, [val] - call pci_write_reg - pop ebx - ret -endp - -align 4 -proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword - push ebx - xor eax, eax - xor ebx, ebx - mov ah, byte [bus] - mov al, 9 - mov bh, byte [devfn] - mov bl, byte [reg] - mov ecx, [val] - call pci_write_reg - pop ebx - ret -endp - -align 4 -proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword - push ebx - xor eax, eax - xor ebx, ebx - mov ah, byte [bus] - mov al, 10 - mov bh, byte [devfn] - mov bl, byte [reg] - mov ecx, [val] - call pci_write_reg - pop ebx - ret -endp - -handle equ IOCTL.handle -io_code equ IOCTL.io_code -input equ IOCTL.input -inp_size equ IOCTL.inp_size -output equ IOCTL.output -out_size equ IOCTL.out_size - - -align 4 -proc srv_handler stdcall, ioctl:dword - mov esi, [ioctl] - test esi, esi - jz .err - - mov edi, [esi+handle] - cmp [edi+SRV.magic], ' SRV' - jne .fail - - cmp [edi+SRV.size], sizeof.SRV - jne .fail - -; stdcall [edi+SRV.srv_proc], esi - mov eax, [edi+SRV.srv_proc] - test eax, eax - jz .fail - stdcall eax, esi - ret -.fail: - xor eax, eax - not eax - mov [esi+output], eax - mov [esi+out_size], 4 - ret -.err: - xor eax, eax - not eax - ret -endp - -; param -; ecx= io_control -; -; retval -; eax= error code - -align 4 -srv_handlerEx: - cmp ecx, OS_BASE - jae .fail - - mov eax, [ecx+handle] - cmp [eax+SRV.magic], ' SRV' - jne .fail - - cmp [eax+SRV.size], sizeof.SRV - jne .fail - -; stdcall [eax+SRV.srv_proc], ecx - mov eax, [eax+SRV.srv_proc] - test eax, eax - jz .fail - stdcall eax, ecx - ret -.fail: - or eax, -1 - ret - -restore handle -restore io_code -restore input -restore inp_size -restore output -restore out_size - -align 4 -proc get_service stdcall, sz_name:dword - mov eax, [sz_name] - test eax, eax - jnz @F - ret -@@: - mov edx, [srv.fd] -@@: - cmp edx, srv.fd-SRV.fd - je .not_load - - stdcall strncmp, edx, [sz_name], 16 - test eax, eax - mov eax, edx - je .nothing - - mov edx, [edx+SRV.fd] - jmp @B -.not_load: - mov eax, [sz_name] - push edi - sub esp, 36 - mov edi, esp - mov dword [edi], '/sys' - mov dword [edi+4], '/dri' - mov dword [edi+8], 'vers' - mov byte [edi+12], '/' -@@: - mov dl, [eax] - mov [edi+13], dl - inc eax - inc edi - test dl, dl - jnz @b - mov dword [edi+12], '.sys' - mov byte [edi+16], 0 - mov edi, esp - stdcall load_pe_driver, edi, 0 - add esp, 36 - pop edi -.nothing: - ret -endp - -reg_service: - xor eax, eax - mov ecx, [esp+8] - jecxz .nothing - push sizeof.SRV - push ecx - pushd [esp+12] - call reg_service_ex -.nothing: - ret 8 - -reg_usb_driver: - push sizeof.USBSRV - pushd [esp+12] - pushd [esp+12] - call reg_service_ex - test eax, eax - jz .nothing - mov ecx, [esp+12] - mov [eax+USBSRV.usb_func], ecx -.nothing: - ret 12 - -proc reg_service_ex stdcall, name:dword, handler:dword, srvsize:dword - - push ebx - - xor eax, eax - - cmp [name], eax - je .fail - -; cmp [handler], eax -; je .fail - - mov eax, [srvsize] - call malloc - test eax, eax - jz .fail - - push esi - push edi - mov edi, eax - mov esi, [name] - movsd - movsd - movsd - movsd - pop edi - pop esi - - mov [eax+SRV.magic], ' SRV' - mov [eax+SRV.size], sizeof.SRV - - mov ebx, srv.fd-SRV.fd - mov edx, [ebx+SRV.fd] - mov [eax+SRV.fd], edx - mov [eax+SRV.bk], ebx - mov [ebx+SRV.fd], eax - mov [edx+SRV.bk], eax - - mov ecx, [handler] - mov [eax+SRV.srv_proc], ecx - pop ebx - ret -.fail: - xor eax, eax - pop ebx - ret -endp - -align 4 -proc get_proc stdcall, exp:dword, sz_name:dword - - mov edx, [exp] -.next: - mov eax, [edx] - test eax, eax - jz .end - - push edx - stdcall strncmp, eax, [sz_name], 16 - pop edx - test eax, eax - jz .ok - - add edx, 8 - jmp .next -.ok: - mov eax, [edx+4] -.end: - ret -endp - -align 4 -proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword - -@@: - stdcall strncmp, [pSym], [sz_sym], 8 - test eax, eax - jz .ok - add [pSym], 18 - dec [count] - jnz @b - xor eax, eax - ret -.ok: - mov eax, [pSym] - mov eax, [eax+8] - ret -endp - -align 4 -proc get_curr_task - mov eax, [current_slot_idx] - shl eax, 8 - ret -endp - -align 4 -proc get_fileinfo stdcall, file_name:dword, info:dword - locals - cmd dd ? - offset dd ? - dd ? - count dd ? - buff dd ? - db ? - name dd ? - endl - - xor eax, eax - mov ebx, [file_name] - mov ecx, [info] - - mov [cmd], 5 - mov [offset], eax - mov [offset+4], eax - mov [count], eax - mov [buff], ecx - mov byte [buff+4], al - mov [name], ebx - - mov eax, 70 - lea ebx, [cmd] - pushad - cld - call protect_from_terminate - call syscall_file_system_lfn - call unprotect_from_terminate - popad - ret -endp - -align 4 -proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\ - bytes:dword - locals - cmd dd ? - offset dd ? - dd ? - count dd ? - buff dd ? - db ? - name dd ? - endl - - xor eax, eax - mov ebx, [file_name] - mov ecx, [off] - mov edx, [bytes] - mov esi, [buffer] - - mov [cmd], eax - mov [offset], ecx - mov [offset+4], eax - mov [count], edx - mov [buff], esi - mov byte [buff+4], al - mov [name], ebx - - pushad - lea ebx, [cmd] - call syscall_file_system_lfn_protected - popad - ret -endp - -; description -; allocate kernel memory and loads the specified file -; -; param -; file_name= path to file -; -; retval -; eax= file image in kernel memory -; ebx= size of file -; -; warging -; You mast call kernel_free() to delete each file -; loaded by the load_file() function - -align 4 -proc load_file stdcall, file_name:dword - locals - attr dd ? - flags dd ? - cr_time dd ? - cr_date dd ? - acc_time dd ? - acc_date dd ? - mod_time dd ? - mod_date dd ? - file_size dd ? - - file dd ? - file2 dd ? - endl - - push esi - push edi - - lea eax, [attr] - stdcall get_fileinfo, [file_name], eax - test eax, eax - jnz .fail - - mov eax, [file_size] - cmp eax, 1024*1024*16 - ja .fail - - stdcall kernel_alloc, [file_size] - mov [file], eax - test eax, eax - jz .fail - - stdcall read_file, [file_name], eax, dword 0, [file_size] - cmp ebx, [file_size] - jne .cleanup - - mov eax, [file] - cmp dword [eax], 'KPCK' - jne .exit - mov ebx, [eax+4] - mov [file_size], ebx - stdcall kernel_alloc, ebx - - test eax, eax - jz .cleanup - - mov [file2], eax - - pushad - mov ecx, unpack_mutex - call mutex_lock - popad - - stdcall unpack, [file], eax - - pushad - mov ecx, unpack_mutex - call mutex_unlock - popad - - stdcall kernel_free, [file] - mov eax, [file2] - mov ebx, [file_size] -.exit: - push eax - lea edi, [eax+ebx] ;cleanup remain space - mov ecx, 4096 ;from file end - and ebx, 4095 - jz @f - sub ecx, ebx - xor eax, eax - cld - rep stosb -@@: - mov ebx, [file_size] - pop eax - pop edi - pop esi - ret -.cleanup: - stdcall kernel_free, [file] -.fail: - xor eax, eax - xor ebx, ebx - pop edi - pop esi - ret -endp - -; description -; allocate user memory and loads the specified file -; -; param -; file_name= path to file -; -; retval -; eax= file image in user memory -; ebx= size of file -; -; warging -; You mast call kernel_free() to delete each file -; loaded by the load_file() function - -align 4 -proc load_file_umode stdcall, file_name:dword - locals - attr dd ? - flags dd ? - cr_time dd ? - cr_date dd ? - acc_time dd ? - acc_date dd ? - mod_time dd ? - mod_date dd ? - file_size dd ? - - km_file dd ? - um_file dd ? - endl - - push esi - push edi - push ebx - - lea eax, [attr] - stdcall get_fileinfo, [file_name], eax ;find file and get info - test eax, eax - jnz .err_1 - - mov eax, [file_size] - cmp eax, 1024*1024*16 ;to be enough for anybody (c) - ja .err_1 - ;it is very likely that the file is packed - stdcall kernel_alloc, [file_size] ;with kpack, so allocate memory from kernel heap - mov [km_file], eax - test eax, eax - jz .err_1 - - stdcall read_file, [file_name], eax, dword 0, [file_size] - cmp ebx, [file_size] - - jne .err_2 - - mov eax, [km_file] - cmp dword [eax], 'KPCK' ; check kpack signature - jne .raw_file - - mov ebx, [eax+4] ;get real size of file - mov [file_size], ebx - stdcall user_alloc, ebx ;and allocate space from user heap - mov [um_file], eax - test eax, eax - jz .err_2 - - mov edx, [file_size] ;preallocate page memory - shr eax, 10 - lea edi, [page_tabs+eax] - add edx, 4095 - shr edx, 12 -@@: - call alloc_page - test eax, eax - jz .err_3 - - or eax, PG_UWR - stosd - dec edx - jnz @B - - pushad - mov ecx, unpack_mutex - call mutex_lock - - stdcall unpack, [km_file], [um_file] - - mov ecx, unpack_mutex - call mutex_unlock - popad - - stdcall kernel_free, [km_file] ;we don't need packed file anymore -.exit: - - mov edi, [um_file] - mov esi, [um_file] - mov eax, [file_size] - mov edx, eax - - add edi, eax ;cleanup remain space - mov ecx, 4096 ;from file end - and eax, 4095 - jz @f - sub ecx, eax - xor eax, eax - cld - rep stosb -@@: - mov eax, [um_file] - - pop ebx - pop edi - pop esi - ret - -.raw_file: ; sometimes we load unpacked file - stdcall user_alloc, ebx ; allocate space from user heap - mov [um_file], eax - - test eax, eax - jz .err_2 - - shr eax, 10 ; and remap pages. - - mov ecx, [file_size] - add ecx, 4095 - shr ecx, 12 - - mov esi, [km_file] - shr esi, 10 - add esi, page_tabs - - lea edi, [page_tabs+eax] - - cld -@@: - lodsd - and eax, 0xFFFFF000 - or eax, PG_UWR - stosd - loop @B - - stdcall free_kernel_space, [km_file] ; release allocated kernel space - jmp .exit ; physical pages still in use -.err_3: - stdcall user_free, [um_file] -.err_2: - stdcall kernel_free, [km_file] -.err_1: - xor eax, eax - xor edx, edx - - pop ebx - pop edi - pop esi - ret -endp - - -uglobal -align 4 -unpack_mutex MUTEX -endg - -align 4 -proc get_proc_ex stdcall uses ebx esi, proc_name:dword, imports:dword - mov ebx, [imports] - test ebx, ebx - jz .end - xor esi, esi -.look_up: - - mov eax, [ebx+32] - mov eax, [OS_BASE+eax+esi*4] - add eax, OS_BASE - stdcall strncmp, eax, [proc_name], 256 - test eax, eax - jz .ok - - inc esi - cmp esi, [ebx+24] - jb .look_up -.end: - xor eax, eax - ret -.ok: - mov eax, [ebx+28] - mov eax, [OS_BASE+eax+esi*4] - add eax, OS_BASE - ret -endp - -align 4 -proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\ - sym_count:dword, strings:dword, imports:dword - locals - retval dd ? - endl - - mov edi, [symbols] - mov [retval], 1 -.fix: - movzx ebx, [edi+COFF_SYM.SectionNumber] - test ebx, ebx - jnz .internal - mov eax, dword [edi+COFF_SYM.Name] - test eax, eax - jnz @F - - mov edi, [edi+4] - add edi, [strings] -@@: - push edi - stdcall get_proc_ex, edi, [imports] - pop edi - - xor ebx, ebx - test eax, eax - jnz @F - - ; disable debug msg - ;mov esi, msg_unresolved - ;call sys_msg_board_str - ;mov esi, edi - ;call sys_msg_board_str - ;mov esi, msg_CR - ;call sys_msg_board_str - - mov [retval], 0 -@@: - mov edi, [symbols] - mov [edi+COFF_SYM.Value], eax - jmp .next -.internal: - cmp bx, -1 - je .next - cmp bx, -2 - je .next - - dec ebx - shl ebx, 3 - lea ebx, [ebx+ebx*4] - add ebx, [sec] - - mov eax, [ebx+COFF_SECTION.VirtualAddress] - add [edi+COFF_SYM.Value], eax -.next: - add edi, sizeof.COFF_SYM - mov [symbols], edi - dec [sym_count] - jnz .fix - mov eax, [retval] - ret -endp - -align 4 -proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \ - delta:dword - locals - n_sec dd ? - endl - - mov eax, [coff] - movzx ebx, [eax+COFF_HEADER.nSections] - mov [n_sec], ebx - lea esi, [eax+20] -.fix_sec: - mov edi, [esi+COFF_SECTION.PtrReloc] - add edi, [coff] - - movzx ecx, [esi+COFF_SECTION.NumReloc] - test ecx, ecx - jz .next -.reloc_loop: - mov ebx, [edi+COFF_RELOC.SymIndex] - add ebx, ebx - lea ebx, [ebx+ebx*8] - add ebx, [sym] - - mov edx, [ebx+COFF_SYM.Value] - - cmp [edi+COFF_RELOC.Type], 6 - je .dir_32 - - cmp [edi+COFF_RELOC.Type], 20 - jne .next_reloc -.rel_32: - mov eax, [edi+COFF_RELOC.VirtualAddress] - add eax, [esi+COFF_SECTION.VirtualAddress] - sub edx, eax - sub edx, 4 - jmp .fix -.dir_32: - mov eax, [edi+COFF_RELOC.VirtualAddress] - add eax, [esi+COFF_SECTION.VirtualAddress] -.fix: - add eax, [delta] - add [eax], edx -.next_reloc: - add edi, 10 - dec ecx - jnz .reloc_loop -.next: - add esi, sizeof.COFF_SECTION - dec [n_sec] - jnz .fix_sec -.exit: - ret -endp - -align 4 -proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \ - delta:dword - locals - n_sec dd ? - endl - - mov eax, [coff] - movzx ebx, [eax+COFF_HEADER.nSections] - mov [n_sec], ebx - lea esi, [eax+20] - mov edx, [delta] -.fix_sec: - mov edi, [esi+COFF_SECTION.PtrReloc] - add edi, [coff] - - movzx ecx, [esi+COFF_SECTION.NumReloc] - test ecx, ecx - jz .next -.reloc_loop: - cmp [edi+COFF_RELOC.Type], 6 - jne .next_reloc -.dir_32: - mov eax, [edi+COFF_RELOC.VirtualAddress] - add eax, [esi+COFF_SECTION.VirtualAddress] - add [eax+edx], edx -.next_reloc: - add edi, 10 - dec ecx - jnz .reloc_loop -.next: - add esi, sizeof.COFF_SECTION - dec [n_sec] - jnz .fix_sec -.exit: - ret -endp - -; in: edx -> COFF_SECTION struct -; out: eax = alignment as mask for bits to drop -coff_get_align: -; Rules: -; - if alignment is not given, use default = 4K; -; - if alignment is given and is no more than 4K, use it; -; - if alignment is more than 4K, revert to 4K. - push ecx - mov cl, byte [edx+COFF_SECTION.Characteristics+2] - mov eax, 1 - shr cl, 4 - dec cl - js .default - cmp cl, 12 - jbe @f -.default: - mov cl, 12 -@@: - shl eax, cl - pop ecx - dec eax - ret - -align 4 -proc load_library stdcall, file_name:dword, encoding:dword - locals - fullname dd ? - fileinfo rb 40 - coff dd ? - img_base dd ? - endl - -; resolve file name - stdcall kernel_alloc, maxPathLength - mov [fullname], eax - mov edi, eax - mov esi, [file_name] - mov eax, [encoding] - push ebp - call getFullPath - pop ebp - test eax, eax - jz .fail -; scan for required DLL in list of already loaded for this process, -; ignore timestamp - cli - mov esi, [current_process] - mov edi, [fullname] - mov ebx, [esi+PROC.dlls_list_ptr] - test ebx, ebx - jz .not_in_process - mov esi, [ebx+HDLL.fd] -.scan_in_process: - cmp esi, ebx - jz .not_in_process - mov eax, [esi+HDLL.parent] - add eax, DLLDESCR.name - stdcall strncmp, eax, edi, -1 - test eax, eax - jnz .next_in_process -; simple variant: load DLL which is already loaded in this process -; just increment reference counters and return address of exports table - inc [esi+HDLL.refcount] - mov ecx, [esi+HDLL.parent] - inc [ecx+DLLDESCR.refcount] - mov eax, [ecx+DLLDESCR.exports] - sub eax, [ecx+DLLDESCR.defaultbase] - add eax, [esi+HDLL.base] - sti - push eax - stdcall kernel_free, [fullname] - pop eax - ret - -.next_in_process: - mov esi, [esi+HDLL.fd] - jmp .scan_in_process - -.not_in_process: -; scan in full list, compare timestamp - sti - lea eax, [fileinfo] - stdcall get_fileinfo, edi, eax - test eax, eax - jnz .fail - cli - mov esi, [dll_list.fd] -.scan_for_dlls: - cmp esi, dll_list - jz .load_new - lea eax, [esi+DLLDESCR.name] - stdcall strncmp, eax, edi, -1 - test eax, eax - jnz .continue_scan -.test_prev_dll: - mov eax, dword [fileinfo+24]; last modified time - mov edx, dword [fileinfo+28]; last modified date - cmp dword [esi+DLLDESCR.timestamp], eax - jnz .continue_scan - cmp dword [esi+DLLDESCR.timestamp+4], edx - jz .dll_already_loaded -.continue_scan: - mov esi, [esi+DLLDESCR.fd] - jmp .scan_for_dlls - -; new DLL -.load_new: - sti -; load file - stdcall load_file, edi - test eax, eax - jz .fail - mov [coff], eax - mov dword [fileinfo+32], ebx - -; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name - mov esi, edi - mov ecx, -1 - xor eax, eax - repnz scasb - not ecx - lea eax, [ecx+sizeof.DLLDESCR] - push ecx - call malloc - pop ecx - test eax, eax - jz .fail_and_free_coff -; save timestamp - lea edi, [eax+DLLDESCR.name] - rep movsb - mov esi, eax - mov eax, dword [fileinfo+24] - mov dword [esi+DLLDESCR.timestamp], eax - mov eax, dword [fileinfo+28] - mov dword [esi+DLLDESCR.timestamp+4], eax - -; calculate size of loaded DLL - mov edx, [coff] - movzx ecx, [edx+COFF_HEADER.nSections] - xor ebx, ebx - - add edx, 20 -@@: - call coff_get_align - add ebx, eax - not eax - and ebx, eax - add ebx, [edx+COFF_SECTION.SizeOfRawData] - add edx, sizeof.COFF_SECTION - dec ecx - jnz @B -; it must be nonzero and not too big - mov [esi+DLLDESCR.size], ebx - test ebx, ebx - jz .fail_and_free_dll - cmp ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR - ja .fail_and_free_dll -; allocate memory for kernel-side image - stdcall kernel_alloc, ebx - test eax, eax - jz .fail_and_free_dll - mov [esi+DLLDESCR.data], eax -; calculate preferred base address - add ebx, 0x1FFF - and ebx, not 0xFFF - mov ecx, [dll_cur_addr] - lea edx, [ecx+ebx] - cmp edx, MAX_DEFAULT_DLL_ADDR - jb @f - mov ecx, MIN_DEFAULT_DLL_ADDR - lea edx, [ecx+ebx] -@@: - mov [esi+DLLDESCR.defaultbase], ecx - mov [dll_cur_addr], edx - -; copy sections and set correct values for VirtualAddress'es in headers - push esi - mov edx, [coff] - movzx ebx, [edx+COFF_HEADER.nSections] - mov edi, eax - add edx, 20 - cld -@@: - call coff_get_align - add ecx, eax - add edi, eax - not eax - and ecx, eax - and edi, eax - mov [edx+COFF_SECTION.VirtualAddress], ecx - add ecx, [edx+COFF_SECTION.SizeOfRawData] - mov esi, [edx+COFF_SECTION.PtrRawData] - push ecx - mov ecx, [edx+COFF_SECTION.SizeOfRawData] - test esi, esi - jnz .copy - xor eax, eax - rep stosb - jmp .next -.copy: - add esi, [coff] - rep movsb -.next: - pop ecx - add edx, sizeof.COFF_SECTION - dec ebx - jnz @B - pop esi - -; save some additional data from COFF file -; later we will use COFF header, headers for sections and symbol table -; and also relocations table for all sections - mov edx, [coff] - mov ebx, [edx+COFF_HEADER.pSymTable] - mov edi, dword [fileinfo+32] - sub edi, ebx - jc .fail_and_free_data - mov [esi+DLLDESCR.symbols_lim], edi - add ebx, edx - movzx ecx, [edx+COFF_HEADER.nSections] - lea ecx, [ecx*5] - lea edi, [edi+ecx*8+20] - add edx, 20 -@@: - movzx eax, [edx+COFF_SECTION.NumReloc] - lea eax, [eax*5] - lea edi, [edi+eax*2] - add edx, sizeof.COFF_SECTION - sub ecx, 5 - jnz @b - stdcall kernel_alloc, edi - test eax, eax - jz .fail_and_free_data - mov edx, [coff] - movzx ecx, [edx+COFF_HEADER.nSections] - lea ecx, [ecx*5] - lea ecx, [ecx*2+5] - mov [esi+DLLDESCR.coff_hdr], eax - push esi - mov esi, edx - mov edi, eax - rep movsd - pop esi - mov [esi+DLLDESCR.symbols_ptr], edi - push esi - mov ecx, [edx+COFF_HEADER.nSymbols] - mov [esi+DLLDESCR.symbols_num], ecx - mov ecx, [esi+DLLDESCR.symbols_lim] - mov esi, ebx - rep movsb - pop esi - mov ebx, [esi+DLLDESCR.coff_hdr] - push esi - movzx eax, [edx+COFF_HEADER.nSections] - lea edx, [ebx+20] -@@: - movzx ecx, [edx+COFF_SECTION.NumReloc] - lea ecx, [ecx*5] - mov esi, [edx+COFF_SECTION.PtrReloc] - mov [edx+COFF_SECTION.PtrReloc], edi - sub [edx+COFF_SECTION.PtrReloc], ebx - add esi, [coff] - shr ecx, 1 - rep movsd - adc ecx, ecx - rep movsw - add edx, sizeof.COFF_SECTION - dec eax - jnz @b - pop esi - -; fixup symbols - mov edx, ebx - mov eax, [ebx+COFF_HEADER.nSymbols] - add edx, 20 - mov ecx, [esi+DLLDESCR.symbols_num] - lea ecx, [ecx*9] - add ecx, ecx - add ecx, [esi+DLLDESCR.symbols_ptr] - - stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax, \ - ecx, 0 -; test eax, eax -; jnz @F -; -;@@: - - stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], szEXPORTS - test eax, eax - jnz @F - - stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], sz_EXPORTS -@@: - mov [esi+DLLDESCR.exports], eax - -; fix relocs in the hidden copy in kernel memory to default address -; it is first fix; usually this will be enough, but second fix -; can be necessary if real load address will not equal assumption - mov eax, [esi+DLLDESCR.data] - sub eax, [esi+DLLDESCR.defaultbase] - stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax - - stdcall kernel_free, [coff] - - cli -; initialize DLLDESCR struct - and dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented - mov [esi+DLLDESCR.fd], dll_list - mov eax, [dll_list.bk] - mov [dll_list.bk], esi - mov [esi+DLLDESCR.bk], eax - mov [eax+DLLDESCR.fd], esi -.dll_already_loaded: - stdcall kernel_free, [fullname] - inc [esi+DLLDESCR.refcount] - push esi - call init_heap - pop esi - mov edi, [esi+DLLDESCR.size] - stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi - test eax, eax - jnz @f - stdcall user_alloc, edi - test eax, eax - jz .fail_and_dereference -@@: - mov [img_base], eax - mov eax, sizeof.HDLL - call malloc - test eax, eax - jz .fail_and_free_user - mov ebx, [current_slot_idx] - shl ebx, 5 - mov edx, [TASK_TABLE+ebx+TASKDATA.pid] - mov [eax+HDLL.pid], edx - push eax - call init_dlls_in_thread - pop ebx - test eax, eax - jz .fail_and_free_user - mov edx, [eax+HDLL.fd] - mov [ebx+HDLL.fd], edx - mov [ebx+HDLL.bk], eax - mov [eax+HDLL.fd], ebx - mov [edx+HDLL.bk], ebx - mov eax, ebx - mov ebx, [img_base] - mov [eax+HDLL.base], ebx - mov [eax+HDLL.size], edi - mov [eax+HDLL.refcount], 1 - mov [eax+HDLL.parent], esi - mov edx, ebx - shr edx, 12 - or dword [page_tabs+(edx-1)*4], MEM_BLOCK_DONT_FREE -; copy entries of page table from kernel-side image to usermode -; use copy-on-write for user-mode image, so map as readonly - xor edi, edi - mov ecx, [esi+DLLDESCR.data] - shr ecx, 12 -.map_pages_loop: - mov eax, [page_tabs+ecx*4] - and eax, not 0xFFF - or al, PG_UR - xchg eax, [page_tabs+edx*4] - test al, 1 - jz @f - call free_page -@@: - invlpg [ebx+edi] - inc ecx - inc edx - add edi, 0x1000 - cmp edi, [esi+DLLDESCR.size] - jb .map_pages_loop - -; if real user-mode base is not equal to preferred base, relocate image - sub ebx, [esi+DLLDESCR.defaultbase] - jz @f - stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx -@@: - - mov eax, [esi+DLLDESCR.exports] - sub eax, [esi+DLLDESCR.defaultbase] - add eax, [img_base] - sti - ret - -.fail_and_free_data: - stdcall kernel_free, [esi+DLLDESCR.data] -.fail_and_free_dll: - mov eax, esi - call free -.fail_and_free_coff: - stdcall kernel_free, [coff] -.fail: - stdcall kernel_free, [fullname] - xor eax, eax - ret - -.fail_and_free_user: - stdcall user_free, [img_base] -.fail_and_dereference: - mov eax, 1 ; delete 1 reference - call dereference_dll - sti - xor eax, eax - ret -endp - -; initialize [APPDATA.dlls_list_ptr] for given thread -; DLL is per-process object, so APPDATA.dlls_list_ptr must be -; kept in sync for all threads of one process. -; out: eax = APPDATA.dlls_list_ptr if all is OK, -; NULL if memory allocation failed -init_dlls_in_thread: - mov ebx, [current_process] - mov eax, [ebx+PROC.dlls_list_ptr] - test eax, eax - jnz .ret - - mov eax, 8 - call malloc ; FIXME - test eax, eax - jz .ret - - mov [eax], eax - mov [eax+4], eax - - mov ebx, [current_process] - mov [ebx+PROC.dlls_list_ptr], eax -.ret: - ret - -; in: eax = number of references to delete, esi -> DLLDESCR struc -dereference_dll: - sub [esi+DLLDESCR.refcount], eax - jnz .ret - mov eax, [esi+DLLDESCR.fd] - mov edx, [esi+DLLDESCR.bk] - mov [eax+DLLDESCR.bk], edx - mov [edx+DLLDESCR.fd], eax - stdcall kernel_free, [esi+DLLDESCR.coff_hdr] - stdcall kernel_free, [esi+DLLDESCR.data] - mov eax, esi - call free -.ret: - ret - -destroy_hdll: - push ebx ecx esi edi - mov ebx, [eax+HDLL.base] - mov esi, [eax+HDLL.parent] - mov edx, [esi+DLLDESCR.size] - - push eax - mov esi, [eax+HDLL.parent] - mov eax, [eax+HDLL.refcount] - call dereference_dll - pop eax - mov edx, [eax+HDLL.bk] - mov ebx, [eax+HDLL.fd] - mov [ebx+HDLL.bk], edx - mov [edx+HDLL.fd], ebx - call free - pop edi esi ecx ebx - ret - -; ecx -> APPDATA for slot, esi = dlls_list_ptr -destroy_all_hdlls: - test esi, esi - jz .ret -.loop: - mov eax, [esi+HDLL.fd] - cmp eax, esi - jz free - call destroy_hdll - jmp .loop -.ret: - ret - -align 4 -stop_all_services: - push ebp - mov edx, [srv.fd] -.next: - cmp edx, srv.fd-SRV.fd - je .done - cmp [edx+SRV.magic], ' SRV' - jne .next - cmp [edx+SRV.size], sizeof.SRV - jne .next - - mov ebx, [edx+SRV.entry] - mov edx, [edx+SRV.fd] - test ebx, ebx - jz .next - - push edx - mov ebp, esp - push 0 - push -1 - call ebx - mov esp, ebp - pop edx - jmp .next -.done: - pop ebp - ret - -; param -; eax= size -; ebx= pid - -align 4 -create_kernel_object: - - push ebx - call malloc - pop ebx - test eax, eax - jz .fail - - mov ecx, [current_slot] - add ecx, APP_OBJ_OFFSET - - pushfd - cli - mov edx, [ecx+APPOBJ.fd] - mov [eax+APPOBJ.fd], edx - mov [eax+APPOBJ.bk], ecx - mov [eax+APPOBJ.pid], ebx - - mov [ecx+APPOBJ.fd], eax - mov [edx+APPOBJ.bk], eax - popfd -.fail: - ret - -; param -; eax= object - -align 4 -destroy_kernel_object: - - pushfd - cli - mov ebx, [eax+APPOBJ.fd] - mov ecx, [eax+APPOBJ.bk] - mov [ebx+APPOBJ.bk], ecx - mov [ecx+APPOBJ.fd], ebx - popfd - - xor edx, edx ;clear common header - mov [eax], edx - mov [eax+4], edx - mov [eax+8], edx - mov [eax+12], edx - mov [eax+16], edx - - call free ;release object memory - ret - - -;void* __fastcall create_object(size_t size) -; param -; ecx= size - -align 4 -create_object: - - push esi - push edi - pushfd - cli - - mov esi, [current_process] - mov eax, [esi+PROC.ht_free] - mov edi, [esi+PROC.ht_next] - dec eax - js .err0 - - mov [esi+PROC.ht_free], eax - mov eax, [esi+PROC.htab+edi*4] - mov [esi+PROC.ht_next], eax - popfd - - mov eax, ecx - call malloc - test eax, eax - jz .err1 - - mov [eax+FUTEX.handle], edi - mov [esi+PROC.htab+edi*4], eax - pop edi - pop esi - ret - -.err1: - pushfd - cli - - mov eax, [esi+PROC.ht_next] - mov [esi+PROC.htab+edi*4], eax - mov [esi+PROC.ht_next], edi - inc [esi+PROC.ht_free] -.err0: - popfd - pop edi - pop esi - xor eax, eax - ret - - -;int __fastcall destroy_object(struct object *obj) - -align 4 -destroy_object: - push esi - mov esi, [current_process] - mov edx, [ecx+FUTEX.handle] - - pushfd - cli - - mov eax, [esi+PROC.ht_next] - mov [esi+PROC.htab+edx*4], eax - mov [esi+PROC.ht_next], edx - inc [esi+PROC.ht_free] - - popfd - pop esi - - mov eax, ecx - call free - xor eax, eax - ret -.fail: - popfd - pop esi - mov eax, -1 - ret - diff --git a/kernel/branches/Kolibri-F/core/export.inc b/kernel/branches/Kolibri-F/core/export.inc deleted file mode 100644 index 5fb9a9005..000000000 --- a/kernel/branches/Kolibri-F/core/export.inc +++ /dev/null @@ -1,40 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; Macroinstruction for making export section - - -macro export dllname,[label,string] - { common - local module,addresses,names,ordinal,count - count = 0 - forward - count = count+1 - common - dd 0,0,0, (module-OS_BASE) , 1 - dd count,count,(addresses-OS_BASE),(names-OS_BASE),(ordinal-OS_BASE) - addresses: - forward - dd (label-OS_BASE) - common - names: - forward - local name - dd (name-OS_BASE) - common - ordinal: - count = 0 - forward - dw count - count = count+1 - common - module db dllname,0 - forward - name db string,0 - } diff --git a/kernel/branches/Kolibri-F/core/exports.inc b/kernel/branches/Kolibri-F/core/exports.inc deleted file mode 100644 index 41e4f00aa..000000000 --- a/kernel/branches/Kolibri-F/core/exports.inc +++ /dev/null @@ -1,141 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - align 4 -__exports: - export 'KERNEL', \ - alloc_kernel_space, 'AllocKernelSpace', \ ; stdcall - alloc_page, 'AllocPage', \ ; gcc ABI - alloc_pages, 'AllocPages', \ ; stdcall - commit_pages, 'CommitPages', \ ; eax, ebx, ecx -\ - disk_add, 'DiskAdd', \ ;stdcall - disk_del, 'DiskDel', \ - disk_media_changed, 'DiskMediaChanged', \ ;stdcall -\ - create_event, 'CreateEvent', \ ; ecx, esi - destroy_event, 'DestroyEvent', \ ; - raise_event, 'RaiseEvent', \ ; eax, ebx, edx, esi - wait_event, 'WaitEvent', \ ; eax, ebx - wait_event_timeout, 'WaitEventTimeout', \ ; eax, ebx, ecx - get_event_ex, 'GetEvent', \ ; edi - clear_event, 'ClearEvent', \ ;see EVENT.inc for specification - send_event, 'SendEvent', \ ;see EVENT.inc for specification -\ - create_kernel_object, 'CreateObject', \ - create_ring_buffer, 'CreateRingBuffer', \ ; stdcall - destroy_kernel_object, 'DestroyObject', \ - free_kernel_space, 'FreeKernelSpace', \ ; stdcall - free_page, 'FreePage', \ ; eax - kernel_alloc, 'KernelAlloc', \ ; stdcall - kernel_free, 'KernelFree', \ ; stdcall - malloc, 'Kmalloc', \ - free, 'Kfree', \ - map_io_mem, 'MapIoMem', \ ; stdcall - map_page, 'MapPage', \ ; stdcall - get_pg_addr, 'GetPgAddr', \ ; eax - get_phys_addr, 'GetPhysAddr', \ ; eax - map_space, 'MapSpace', \ - release_pages, 'ReleasePages', \ - alloc_dma24, 'AllocDMA24', \ ; stdcall -\ - init_rwsem, 'InitRwsem', \ ; gcc fastcall - down_read, 'DownRead', \ ; gcc fastcall - down_write, 'DownWrite', \ ; gcc fastcall - up_read, 'UpRead', \ ; gcc fastcall - up_write, 'UpWrite', \ ; gcc fastacll - mutex_init, 'MutexInit', \ ; gcc fastcall - mutex_lock, 'MutexLock', \ ; gcc fastcall - mutex_unlock, 'MutexUnlock', \ ; gcc fastcall -\ - get_display, 'GetDisplay', \ - set_screen, 'SetScreen', \ - set_framebuffer, 'SetFramebuffer', \ ; gcc fastcall - window._.get_rect, 'GetWindowRect', \ ; gcc fastcall - pci_api_drv, 'PciApi', \ - pci_read8, 'PciRead8', \ ; stdcall - pci_read16, 'PciRead16', \ ; stdcall - pci_read32, 'PciRead32', \ ; stdcall - pci_write8, 'PciWrite8', \ ; stdcall - pci_write16, 'PciWrite16', \ ; stdcall - pci_write32, 'PciWrite32', \ ; stdcall -\ - get_pid, 'GetPid', \ - get_service, 'GetService', \ ; - reg_service, 'RegService', \ ; stdcall - attach_int_handler, 'AttachIntHandler', \ ; stdcall - user_alloc, 'UserAlloc', \ ; stdcall - user_alloc_at, 'UserAllocAt', \ ; stdcall - user_free, 'UserFree', \ ; stdcall - unmap_pages, 'UnmapPages', \ ; eax, ecx - sys_msg_board_str, 'SysMsgBoardStr', \ - syscall_msg_board, 'SysMsgBoard', \ - get_clock_ns, 'GetClockNs', \ ;retval edx:eax 64-bit value - get_timer_ticks, 'GetTimerTicks', \ - get_stack_base, 'GetStackBase', \ - sys_delay_hs, 'Delay', \ ; ebx - set_mouse_data, 'SetMouseData', \ ; - set_keyboard_data, 'SetKeyboardData', \ ; gcc fastcall - register_keyboard, 'RegKeyboard', \ - delete_keyboard, 'DelKeyboard', \ - get_cpu_freq, 'GetCpuFreq', \ -\ - new_sys_threads, 'CreateThread', \ ; ebx, ecx, edx -\ - srv_handler, 'ServiceHandler', \ - fpu_save, 'FpuSave', \ - fpu_restore, 'FpuRestore', \ - avx_save_size, 'AvxSaveSize', \ - avx_save, 'AvxSave', \ - avx_restore, 'AvxRestore', \ - r_f_port_area, 'ReservePortArea', \ - boot_log, 'Boot_Log', \ -\ - load_cursor, 'LoadCursor', \ ;stdcall -\ - get_curr_task, 'GetCurrentTask', \ - change_task, 'ChangeTask', \ - load_file, 'LoadFile', \ ;retval eax, ebx - delay_ms, 'Sleep', \ -\ - strncat, 'strncat', \ - strncpy, 'strncpy', \ - strncmp, 'strncmp', \ - strnlen, 'strnlen', \ - strchr, 'strchr', \ - strrchr, 'strrchr', \ -\ - timer_hs, 'TimerHS', \ - timer_hs, 'TimerHs', \ ; shit happens - cancel_timer_hs, 'CancelTimerHS', \ -\ - reg_usb_driver, 'RegUSBDriver', \ - usb_open_pipe, 'USBOpenPipe', \ - usb_close_pipe, 'USBClosePipe', \ - usb_normal_transfer_async, 'USBNormalTransferAsync', \ - usb_control_async, 'USBControlTransferAsync', \ - usb_get_param, 'USBGetParam', \ - usb_hc_func, 'USBHCFunc', \ -\ - net_add_device, 'NetRegDev', \ - net_remove_device, 'NetUnRegDev', \ - net_ptr_to_num, 'NetPtrToNum', \ - net_link_changed, 'NetLinkChanged', \ - eth_input, 'EthInput', \ - net_buff_alloc, 'NetAlloc', \ - net_buff_free, 'NetFree', \ -\ - get_pcidev_list, 'GetPCIList', \ -\ - acpi_get_root_ptr, 'AcpiGetRootPtr', \ -\ - 0, 'LFBAddress' ; must be the last one -load kernel_exports_count dword from __exports + 24 -load kernel_exports_addresses dword from __exports + 28 -exp_lfb = OS_BASE + kernel_exports_addresses + (kernel_exports_count - 1) * 4 - 4 diff --git a/kernel/branches/Kolibri-F/core/ext_lib.inc b/kernel/branches/Kolibri-F/core/ext_lib.inc deleted file mode 100644 index 6398729e6..000000000 --- a/kernel/branches/Kolibri-F/core/ext_lib.inc +++ /dev/null @@ -1,476 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; External kernel dependencies (libraries) loading. -; The code currently does not work, requires correcting dll.inc. - -$Revision$ - -if 0 -iglobal -tmp_file_name_size dd 1 -endg - -uglobal -tmp_file_name_table dd ? -s_libname rb 64 -def_val_1 db ? -endg - -macro library [name,fname] -{ - forward - dd __#name#_library_table__,__#name#_library_name__ - common - dd 0 - forward - __#name#_library_name__ db fname,0 -} - -macro import lname,[name,sname] -{ - common - align 4 - __#lname#_library_table__: - forward - name dd __#name#_import_name__ - common - dd 0 - forward - __#name#_import_name__ db sname,0 -} - -macro export [name,sname] -{ -align 4 - forward - dd __#name#_export_name__,name - common - dd 0 - forward - __#name#_export_name__ db sname,0 -} - - - -align 4 ; loading library (use kernel functions) -proc load_k_library stdcall, file_name:dword - locals - coff dd ? - sym dd ? - strings dd ? - img_size dd ? - img_base dd ? - exports dd ? - endl - - cli - - stdcall load_file, [file_name] - test eax, eax - jz .fail - - mov [coff], eax - movzx ecx, [eax+CFH.nSections] - xor ebx, ebx - - lea edx, [eax+20] -@@: - add ebx, [edx+CFS.SizeOfRawData] - add ebx, 15 - and ebx, not 15 - add edx, COFF_SECTION_SIZE - dec ecx - jnz @B - mov [img_size], ebx - - stdcall kernel_alloc, [img_size] - - test eax, eax - jz .fail - mov [img_base], eax - - mov edx, [coff] - movzx ebx, [edx+CFH.nSections] - mov edi, [img_base] - lea eax, [edx+20] -@@: - mov [eax+CFS.VirtualAddress], edi - mov esi, [eax+CFS.PtrRawData] - test esi, esi - jnz .copy - add edi, [eax+CFS.SizeOfRawData] - jmp .next -.copy: - add esi, edx - mov ecx, [eax+CFS.SizeOfRawData] - cld - rep movsb -.next: - add edi, 15 - and edi, not 15 - add eax, COFF_SECTION_SIZE - dec ebx - jnz @B - - mov ebx, [edx+CFH.pSymTable] - add ebx, edx - mov [sym], ebx - mov ecx, [edx+CFH.nSymbols] - add ecx, ecx - lea ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE - add ecx, [sym] - mov [strings], ecx - - lea eax, [edx+20] - - stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols], \ - [strings], dword 0 - test eax, eax - jnz @F - -@@: - mov edx, [coff] - movzx ebx, [edx+CFH.nSections] - mov edi, 0 - lea eax, [edx+20] -@@: - add [eax+CFS.VirtualAddress], edi ;patch user space offset - add eax, COFF_SECTION_SIZE - dec ebx - jnz @B - - add edx, 20 - stdcall fix_coff_relocs, [coff], edx, [sym] - - mov ebx, [coff] - stdcall get_coff_sym, [sym], [ebx+CFH.nSymbols], szEXPORTS - mov [exports], eax - - stdcall kernel_free, [coff] - - mov eax, [exports] - ret -.fail: - xor eax, eax - ret -endp - - -proc dll.Load, import_table:dword - mov esi, [import_table] - .next_lib: - mov edx, [esi] - or edx, edx - jz .exit - push esi - - mov edi, s_libname - - mov al, '/' - stosb - mov esi, sysdir_path - @@: - lodsb - stosb - or al, al - jnz @b - dec edi - mov [edi], dword '/lib' - mov [edi+4], byte '/' - add edi, 5 - pop esi - push esi - mov esi, [esi+4] - @@: - lodsb - stosb - or al, al - jnz @b - - pushad - stdcall load_k_library, s_libname - mov [esp+28], eax - popad - or eax, eax - jz .fail - stdcall dll.Link, eax, edx - stdcall dll.Init, [eax+4] - pop esi - add esi, 8 - jmp .next_lib - .exit: - xor eax, eax - ret - .fail: - add esp, 4 - xor eax, eax - inc eax - ret -endp - -proc dll.Link, exp:dword,imp:dword - push eax - mov esi, [imp] - test esi, esi - jz .done - .next: - lodsd - test eax, eax - jz .done - stdcall dll.GetProcAddress, [exp], eax - or eax, eax - jz @f - mov [esi-4], eax - jmp .next - @@: - mov dword[esp], 0 - .done: - pop eax - ret -endp - -proc dll.Init, dllentry:dword - pushad - mov eax, mem.Alloc - mov ebx, mem.Free - mov ecx, mem.ReAlloc - mov edx, dll.Load - stdcall [dllentry] - popad - ret -endp - -proc dll.GetProcAddress, exp:dword,sz_name:dword - mov edx, [exp] - .next: - test edx, edx - jz .end - stdcall strncmp, [edx], [sz_name], dword -1 - test eax, eax - jz .ok - add edx, 8 - jmp .next - .ok: - mov eax, [edx+4] - .end: - ret -endp - -;----------------------------------------------------------------------------- -proc mem.Alloc size ;///////////////////////////////////////////////////////// -;----------------------------------------------------------------------------- - push ebx ecx -; mov eax,[size] -; lea ecx,[eax+4+4095] -; and ecx,not 4095 -; stdcall kernel_alloc, ecx -; add ecx,-4 -; mov [eax],ecx -; add eax,4 - - stdcall kernel_alloc, [size] - - pop ecx ebx - ret -endp - -;----------------------------------------------------------------------------- -proc mem.ReAlloc mptr,size;/////////////////////////////////////////////////// -;----------------------------------------------------------------------------- - push ebx ecx esi edi eax - mov eax, [mptr] - mov ebx, [size] - or eax, eax - jz @f - lea ecx, [ebx+4+4095] - and ecx, not 4095 - add ecx, -4 - cmp ecx, [eax-4] - je .exit - @@: - mov eax, ebx - call mem.Alloc - xchg eax, [esp] - or eax, eax - jz .exit - mov esi, eax - xchg eax, [esp] - mov edi, eax - mov ecx, [esi-4] - cmp ecx, [edi-4] - jbe @f - mov ecx, [edi-4] - @@: - add ecx, 3 - shr ecx, 2 - cld - rep movsd - xchg eax, [esp] - call mem.Free - .exit: - pop eax edi esi ecx ebx - ret -endp - -;----------------------------------------------------------------------------- -proc mem.Free mptr ;////////////////////////////////////////////////////////// -;----------------------------------------------------------------------------- -; mov eax,[mptr] -; or eax,eax -; jz @f -; push ebx ecx -; lea ecx,[eax-4] -; stdcall kernel_free, ecx -; pop ecx ebx -; @@: ret - stdcall kernel_free, [mptr] - ret -endp - -proc load_file_parse_table - stdcall kernel_alloc, 0x1000 - mov [tmp_file_name_table], eax - mov edi, eax - mov esi, sysdir_name - mov ecx, 128/4 - rep movsd - invoke ini.enum_keys, conf_fname, conf_path_sect, get_every_key - mov eax, [tmp_file_name_table] - mov [full_file_name_table], eax - mov eax, [tmp_file_name_size] - mov [full_file_name_table.size], eax - ret -endp - -proc get_every_key stdcall, f_name, sec_name, key_name - mov esi, [key_name] - mov ecx, esi - cmp byte [esi], '/' - jnz @f - inc esi -@@: - mov edi, [tmp_file_name_size] - shl edi, 7 - cmp edi, 0x1000 - jae .stop_parse - add edi, [tmp_file_name_table] - lea ebx, [edi+64] -@@: - cmp edi, ebx - jae .skip_this_key - lodsb - test al, al - jz @f - or al, 20h - stosb - jmp @b - -.stop_parse: - xor eax, eax - ret - -@@: - stosb - invoke ini.get_str, [f_name], [sec_name], ecx, ebx, 64, def_val_1 - cmp byte [ebx], '/' - jnz @f - lea esi, [ebx+1] - mov edi, ebx - mov ecx, 63 - rep movsb -@@: - push ebp - mov ebp, [tmp_file_name_table] - mov ecx, [tmp_file_name_size] - jecxz .noreplace - mov eax, ecx - dec eax - shl eax, 7 - add ebp, eax -.replace_loop: - mov edi, ebx - mov esi, ebp -@@: - lodsb - test al, al - jz .doreplace - mov dl, [edi] - inc edi - test dl, dl - jz .replace_loop_cont - or dl, 20h - cmp al, dl - jz @b - jmp .replace_loop_cont - -.doreplace: - cmp byte [edi], 0 - jz @f - cmp byte [edi], '/' - jnz .replace_loop_cont -@@: - lea esi, [ebp+64] - call .replace - jc .skip_this_key2 -.replace_loop_cont: - sub ebp, 128 - loop .replace_loop -.noreplace: - pop ebp - inc [tmp_file_name_size] -.skip_this_key: - xor eax, eax - inc eax - ret - -.skip_this_key2: - pop ebp - jmp .skip_this_key -endp - -proc get_every_key.replace -; in: ebx->destination, esi->first part of name, edi->second part of name -; maximum length is 64 bytes -; out: CF=1 <=> overflow - sub esp, 64 ; allocate temporary buffer in stack - push esi - lea esi, [esp+4] ; esi->tmp buffer - xchg esi, edi ; edi->tmp buffer, esi->source -@@: ; save second part of name to temporary buffer - lodsb - stosb - test al, al - jnz @b - pop esi - mov edi, ebx -@@: ; copy first part of name to destination - lodsb - test al, al - jz @f - stosb - jmp @b - -@@: ; restore second part of name from temporary buffer to destination - lea edx, [ebx+64] ; limit of destination - mov esi, esp -@@: - cmp edi, edx - jae .overflow - lodsb - stosb - test al, al - jnz @b - add esp, 64 ; CF is cleared - ret - -.overflow: ; name is too long - add esp, 64 - stc - ret -endp -end if diff --git a/kernel/branches/Kolibri-F/core/fpu.inc b/kernel/branches/Kolibri-F/core/fpu.inc deleted file mode 100644 index 6c109999b..000000000 --- a/kernel/branches/Kolibri-F/core/fpu.inc +++ /dev/null @@ -1,419 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2017. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -init_fpu: - clts - fninit - - bt [cpu_caps+(CAPS_XSAVE/32)*4], CAPS_XSAVE mod 32 - jnc .no_xsave - - mov ecx, cr4 - or ecx, CR4_OSXSAVE - mov cr4, ecx - ; don't call cpuid again - bts [cpu_caps+(CAPS_OSXSAVE/32)*4], CAPS_OSXSAVE mod 32 - - ; zero xsave header - mov ecx, 64/4 - xor eax, eax - mov edi, fpu_data + 512 ; skip legacy region - rep stosd - - mov eax, 0x0d ; extended state enumeration main leaf - xor ecx, ecx - cpuid - and eax, XCR0_FPU_MMX + XCR0_SSE + XCR0_AVX + XCR0_AVX512 - xor edx, edx - mov [xsave_eax], eax - mov [xsave_edx], edx - xor ecx, ecx - xsetbv - - mov eax, 0x0d - xor ecx, ecx - cpuid - add ebx, 63 - and ebx, NOT 63 - mov [xsave_area_size], ebx - cmp ebx, fpu_data_size - ja $ - - test eax, XCR0_AVX512 - jz @f - call init_avx512 - mov eax, [xsave_eax] - mov edx, [xsave_edx] - xsave [fpu_data] - ret -@@: - test eax, XCR0_AVX - jz @f - call init_avx - mov eax, [xsave_eax] - mov edx, [xsave_edx] - xsave [fpu_data] - ret -@@: - test eax, XCR0_SSE - jz $ - call init_sse - mov eax, [xsave_eax] - mov edx, [xsave_edx] - xsave [fpu_data] - ret -.no_xsave: - mov [xsave_area_size], 512 ; enough for FPU/MMX and SSE - bt [cpu_caps], CAPS_SSE - jnc .fpu_mmx -.sse: - call init_sse - fxsave [fpu_data] - ret -.fpu_mmx: - call init_fpu_mmx - fnsave [fpu_data] - ret - -init_fpu_mmx: - mov ecx, cr0 - and ecx, not CR0_EM - or ecx, CR0_MP + CR0_NE - mov cr0, ecx - ret - -init_sse: - mov ebx, cr4 - mov ecx, cr0 - or ebx, CR4_OSFXSR + CR4_OSXMMEXPT - mov cr4, ebx - - and ecx, not (CR0_EM + CR0_MP) - or ecx, CR0_NE - mov cr0, ecx - - mov dword [esp-4], MXCSR_INIT - ldmxcsr [esp-4] - - xorps xmm0, xmm0 - xorps xmm1, xmm1 - xorps xmm2, xmm2 - xorps xmm3, xmm3 - xorps xmm4, xmm4 - xorps xmm5, xmm5 - xorps xmm6, xmm6 - xorps xmm7, xmm7 - ret - -init_avx: - mov ebx, cr4 - or ebx, CR4_OSFXSR + CR4_OSXMMEXPT - mov cr4, ebx - - mov ecx, cr0 - and ecx, not (CR0_EM + CR0_MP) - or ecx, CR0_NE - mov cr0, ecx - - mov dword [esp-4], MXCSR_INIT - vldmxcsr [esp-4] - - vzeroall - ret - -init_avx512: - mov ebx, cr4 - or ebx, CR4_OSFXSR + CR4_OSXMMEXPT - mov cr4, ebx - - mov ecx, cr0 - and ecx, not (CR0_EM + CR0_MP) - or ecx, CR0_NE - mov cr0, ecx - - mov dword [esp-4], MXCSR_INIT - vldmxcsr [esp-4] - - vpxorq zmm0, zmm0, zmm0 - vpxorq zmm1, zmm1, zmm1 - vpxorq zmm2, zmm2, zmm2 - vpxorq zmm3, zmm3, zmm3 - vpxorq zmm4, zmm4, zmm4 - vpxorq zmm5, zmm5, zmm5 - vpxorq zmm6, zmm6, zmm6 - vpxorq zmm7, zmm7, zmm7 - - ret - -; param -; eax= 512 bytes memory area aligned on a 16-byte boundary - -align 4 -fpu_save: - push ecx - push esi - push edi - - pushfd - cli - - clts - mov edi, eax - - mov ecx, [fpu_owner] - mov esi, [current_slot_idx] - cmp ecx, esi - jne .save - - call save_fpu_context - jmp .exit -.save: - mov [fpu_owner], esi - - shl ecx, 8 - mov eax, [ecx+SLOT_BASE+APPDATA.fpu_state] - - call save_context - -; first 512 bytes of XSAVE area have the same format as FXSAVE - shl esi, 8 - mov esi, [esi+SLOT_BASE+APPDATA.fpu_state] - mov ecx, 512/4 - cld - rep movsd - fninit -.exit: - popfd - pop edi - pop esi - pop ecx - ret - -avx_save_size: - mov eax, [xsave_area_size] - ret - -; param -; eax= avx_save_size() bytes memory area aligned on a 64-byte boundary - -align 4 -avx_save: - push ecx - push esi - push edi - - pushfd - cli - - clts - mov edi, eax - - mov ecx, [fpu_owner] - mov esi, [current_slot_idx] - cmp ecx, esi - jne .save - - call save_context - jmp .exit -.save: - mov [fpu_owner], esi - - shl ecx, 8 - mov eax, [ecx+SLOT_BASE+APPDATA.fpu_state] - - call save_context - - shl esi, 8 - mov esi, [esi+SLOT_BASE+APPDATA.fpu_state] - mov ecx, [xsave_area_size] - add ecx, 3 - shr ecx, 2 - rep movsd - fninit -.exit: - popfd - pop edi - pop esi - pop ecx - ret - -align 4 -save_context: - bt [cpu_caps+(CAPS_OSXSAVE/32)*4], CAPS_OSXSAVE mod 32 - jnc save_fpu_context - push eax edx - mov ecx, eax - mov eax, [xsave_eax] - mov edx, [xsave_edx] - xsave [ecx] - pop edx eax - ret -save_fpu_context: - bt [cpu_caps], CAPS_SSE - jnc .no_SSE - fxsave [eax] - ret -.no_SSE: - fnsave [eax] - ret - - -align 4 -fpu_restore: - push ecx - push esi - - mov esi, eax - - pushfd - cli - - mov ecx, [fpu_owner] - mov eax, [current_slot_idx] - cmp ecx, eax - jne .copy - - clts - bt [cpu_caps], CAPS_SSE - jnc .no_SSE - - fxrstor [esi] - popfd - pop esi - pop ecx - ret -.no_SSE: - fnclex ;fix possible problems - frstor [esi] - popfd - pop esi - pop ecx - ret -.copy: - shl eax, 8 - mov edi, [eax+SLOT_BASE+APPDATA.fpu_state] - mov ecx, 512/4 - cld - rep movsd - popfd - pop esi - pop ecx - ret - -align 4 -avx_restore: - push ecx - push esi - - mov esi, eax - - pushfd - cli - - mov ecx, [fpu_owner] - mov eax, [current_slot_idx] - cmp ecx, eax - jne .copy - - clts - bt [cpu_caps+(CAPS_OSXSAVE/32)*4], CAPS_OSXSAVE mod 32 - jnc .no_xsave - push edx - mov eax, [xsave_eax] - mov edx, [xsave_edx] - xrstor [esi] - pop edx - popfd - pop esi - pop ecx - ret -.no_xsave: - bt [cpu_caps], CAPS_SSE - jnc .no_SSE - - fxrstor [esi] - popfd - pop esi - pop ecx - ret -.no_SSE: - fnclex ;fix possible problems - frstor [esi] - popfd - pop esi - pop ecx - ret -.copy: - shl eax, 8 - mov edi, [eax+SLOT_BASE+APPDATA.fpu_state] - mov ecx, [xsave_area_size] - add ecx, 3 - shr ecx, 2 - cld - rep movsd - popfd - pop esi - pop ecx - ret - -align 4 -except_7: ;#NM exception handler - save_ring3_context - clts - mov ax, app_data; - mov ds, ax - mov es, ax - - mov ebx, [fpu_owner] - cmp ebx, [current_slot_idx] - je .exit - - shl ebx, 8 - mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] - bt [cpu_caps+(CAPS_OSXSAVE/32)*4], CAPS_OSXSAVE mod 32 - jnc .no_xsave - mov ecx, eax - mov eax, [xsave_eax] - mov edx, [xsave_edx] - xsave [ecx] - mov ebx, [current_slot_idx] - mov [fpu_owner], ebx - shl ebx, 8 - mov ecx, [ebx+SLOT_BASE+APPDATA.fpu_state] - xrstor [ecx] -.exit: - restore_ring3_context - iret -.no_xsave: - bt [cpu_caps], CAPS_SSE - jnc .no_SSE - - fxsave [eax] - mov ebx, [current_slot_idx] - mov [fpu_owner], ebx - shl ebx, 8 - mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] - fxrstor [eax] - restore_ring3_context - iret - -.no_SSE: - fnsave [eax] - mov ebx, [current_slot_idx] - mov [fpu_owner], ebx - shl ebx, 8 - mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] - frstor [eax] - restore_ring3_context - iret - -iglobal - fpu_owner dd 2 -endg diff --git a/kernel/branches/Kolibri-F/core/heap.inc b/kernel/branches/Kolibri-F/core/heap.inc deleted file mode 100644 index 444f0ffef..000000000 --- a/kernel/branches/Kolibri-F/core/heap.inc +++ /dev/null @@ -1,1589 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -struct MEM_BLOCK - list LHEAD - next_block dd ? ;+8 - prev_block dd ? ;+4 - base dd ? ;+16 - size dd ? ;+20 - flags dd ? ;+24 - handle dd ? ;+28 -ends - -MEM_BLOCK_RESERVED = 0x02 ; Will be allocated on first access (lazy allocation) -MEM_BLOCK_FREE = 0x04 -MEM_BLOCK_USED = 0x08 -MEM_BLOCK_DONT_FREE = 0x10 - -macro calc_index op -{ shr op, 12 - dec op - cmp op, 63 - jna @f - mov op, 63 -@@: -} - -align 4 -md: -.add_to_used: - mov eax, [esi + MEM_BLOCK.base] - mov ebx, [esi + MEM_BLOCK.base] - shr ebx, 6 - add eax, ebx - shr ebx, 6 - add eax, ebx - shr eax, 12 - and eax, 63 - inc [mem_hash_cnt + eax*4] - - lea ecx, [mem_used_list + eax*8] - list_add esi, ecx - mov [esi + MEM_BLOCK.flags], MEM_BLOCK_USED - mov eax, [esi + MEM_BLOCK.size] - sub [heap_free], eax - ret -align 4 -.find_used: - mov ecx, eax - mov ebx, eax - shr ebx, 6 - add ecx, ebx - shr ebx, 6 - add ecx, ebx - shr ecx, 12 - and ecx, 63 - - lea ebx, [mem_used_list + ecx*8] - mov esi, ebx -.next: - mov esi, [esi + MEM_BLOCK.list.next] - cmp esi, ebx - je .fail - - cmp eax, [esi + MEM_BLOCK.base] - jne .next - - ret -.fail: - xor esi, esi - ret - -align 4 -.del_from_used: - call .find_used - test esi, esi - jz .done - - cmp [esi + MEM_BLOCK.flags], MEM_BLOCK_USED - jne .fatal - - dec [mem_hash_cnt + ecx*4] - list_del esi -.done: - ret -.fatal: ;FIXME panic here - xor esi, esi - ret - -;Initial heap state -; -; + heap_size terminator MEM_BLOCK_USED -; + 4096*MEM_BLOCK.sizeof free space MEM_BLOCK_FREE -;HEAP_BASE heap_descriptors MEM_BLOCK_USED -; - -align 4 -proc init_kernel_heap - - mov ecx, 64 - mov edi, mem_block_list - @@: - mov eax, edi - stosd - stosd - loop @B - - mov ecx, 64 - mov edi, mem_used_list - @@: - mov eax, edi - stosd - stosd - loop @B - - stdcall alloc_pages, dword 32 - - or eax, PG_SWR - mov ebx, HEAP_BASE - mov ecx, 32 - call commit_pages - - mov edi, HEAP_BASE ;descriptors - mov ebx, HEAP_BASE + sizeof.MEM_BLOCK ;free space - mov ecx, HEAP_BASE + sizeof.MEM_BLOCK*2 ;terminator - - xor eax, eax - mov [edi + MEM_BLOCK.next_block], ebx - mov [edi + MEM_BLOCK.prev_block], eax - mov [edi + MEM_BLOCK.list.next], eax - mov [edi + MEM_BLOCK.list.prev], eax - mov [edi + MEM_BLOCK.base], HEAP_BASE - mov [edi + MEM_BLOCK.size], 4096*sizeof.MEM_BLOCK - mov [edi + MEM_BLOCK.flags], MEM_BLOCK_USED - - mov [ecx + MEM_BLOCK.next_block], eax - mov [ecx + MEM_BLOCK.prev_block], ebx - mov [ecx + MEM_BLOCK.list.next], eax - mov [ecx + MEM_BLOCK.list.prev], eax - mov [ecx + MEM_BLOCK.base], eax - mov [ecx + MEM_BLOCK.size], eax - mov [ecx + MEM_BLOCK.flags], MEM_BLOCK_USED - - mov [ebx + MEM_BLOCK.next_block], ecx - mov [ebx + MEM_BLOCK.prev_block], edi - mov [ebx + MEM_BLOCK.base], HEAP_BASE + 4096*sizeof.MEM_BLOCK - - mov ecx, [pg_data.kernel_pages] - shl ecx, 12 - sub ecx, HEAP_BASE-OS_BASE + 4096*sizeof.MEM_BLOCK - mov [heap_size], ecx - mov [heap_free], ecx - mov [ebx + MEM_BLOCK.size], ecx - mov [ebx + MEM_BLOCK.flags], MEM_BLOCK_FREE - - mov [mem_block_mask], eax - mov [mem_block_mask + 4], 0x80000000 - - mov ecx, mem_block_list + 63*8 - list_add ebx, ecx - - mov ecx, 4096-3-1 - mov eax, HEAP_BASE + sizeof.MEM_BLOCK*4 - - mov [next_memblock], HEAP_BASE + sizeof.MEM_BLOCK *3 - @@: - mov [eax-sizeof.MEM_BLOCK], eax - add eax, sizeof.MEM_BLOCK - loop @B - - mov dword[eax-sizeof.MEM_BLOCK], 0 - - mov ecx, heap_mutex - call mutex_init - mov [heap_blocks], 4094 - mov [free_blocks], 4093 - ret -endp - -; param -; eax= required size -; -; retval -; edi= memory block descriptor -; ebx= descriptor index - -align 4 -get_small_block: - mov ecx, eax - shr ecx, 12 - dec ecx - cmp ecx, 63 - jle .get_index - mov ecx, 63 - .get_index: - lea esi, [mem_block_mask] - xor ebx, ebx - or edx, -1 - - cmp ecx, 32 - jb .bit_test - - sub ecx, 32 - add ebx, 32 - add esi, 4 - .bit_test: - shl edx, cl - and edx, [esi] - .find: - bsf edi, edx - jz .high_mask - add ebx, edi - lea ecx, [mem_block_list + ebx*8] - mov edi, ecx - .next: - mov edi, [edi + MEM_BLOCK.list.next] - cmp edi, ecx - je .err - cmp eax, [edi + MEM_BLOCK.size] - ja .next - ret - .err: - xor edi, edi - ret - - .high_mask: - add esi, 4 - cmp esi, mem_block_mask + 8 - jae .err - add ebx, 32 - mov edx, [esi] - jmp .find - - -align 4 -free_mem_block: - - mov ebx, [next_memblock] - mov [eax], ebx - mov [next_memblock], eax - - xor ebx, ebx - mov dword[eax + 4], ebx - mov dword[eax + 8], ebx - mov dword[eax + 12], ebx - mov dword[eax + 16], ebx -; mov dword[eax + 20], 0 ;don't clear block size - mov dword[eax + 24], ebx - mov dword[eax + 28], ebx - - inc [free_blocks] - - ret - -align 4 -proc alloc_kernel_space stdcall, size:dword - local block_ind:DWORD - - push ebx - push esi - push edi - - mov eax, [size] - add eax, 4095 - and eax, not 4095 - mov [size], eax - - cmp eax, [heap_free] - ja .error - - spin_lock_irqsave heap_mutex - - mov eax, [size] - - call get_small_block ; eax - test edi, edi - jz .error_unlock - - cmp [edi + MEM_BLOCK.flags], MEM_BLOCK_FREE - jne .error_unlock - - mov [block_ind], ebx ;index of allocated block - - mov eax, [edi + MEM_BLOCK.size] - cmp eax, [size] - je .m_eq_size - - mov esi, [next_memblock] ;new memory block - test esi, esi - jz .error_unlock - - dec [free_blocks] - mov eax, [esi] - mov [next_memblock], eax - - mov [esi + MEM_BLOCK.next_block], edi - mov eax, [edi + MEM_BLOCK.prev_block] - mov [esi + MEM_BLOCK.prev_block], eax - mov [edi + MEM_BLOCK.prev_block], esi - mov [esi + MEM_BLOCK.list.next], 0 - mov [esi + MEM_BLOCK.list.prev], 0 - mov [eax + MEM_BLOCK.next_block], esi - - mov ebx, [edi + MEM_BLOCK.base] - mov [esi + MEM_BLOCK.base], ebx - mov edx, [size] - mov [esi + MEM_BLOCK.size], edx - add [edi + MEM_BLOCK.base], edx - sub [edi + MEM_BLOCK.size], edx - - mov eax, [edi + MEM_BLOCK.size] - calc_index eax - cmp eax, [block_ind] - je .add_used - - list_del edi - - mov ecx, [block_ind] - lea edx, [mem_block_list + ecx*8] - cmp edx, [edx] - jnz @f - btr [mem_block_mask], ecx -@@: - bts [mem_block_mask], eax - lea edx, [mem_block_list + eax*8] ;edx= list head - list_add edi, edx -.add_used: - - call md.add_to_used - - spin_unlock_irqrestore heap_mutex - mov eax, [esi + MEM_BLOCK.base] - pop edi - pop esi - pop ebx - ret - -.m_eq_size: - list_del edi - lea edx, [mem_block_list + ebx*8] - cmp edx, [edx] - jnz @f - btr [mem_block_mask], ebx -@@: - mov esi, edi - jmp .add_used - -.error_unlock: - spin_unlock_irqrestore heap_mutex -.error: - xor eax, eax - pop edi - pop esi - pop ebx - ret -endp - -align 4 -proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword - - spin_lock_irqsave heap_mutex - - mov eax, [base] - - call md.del_from_used - test esi, esi - jz .fail - - mov eax, [esi + MEM_BLOCK.size] - add [heap_free], eax - - mov edi, [esi + MEM_BLOCK.next_block] - cmp [edi + MEM_BLOCK.flags], MEM_BLOCK_FREE - jne .prev - - list_del edi - - mov edx, [edi + MEM_BLOCK.next_block] - mov [esi + MEM_BLOCK.next_block], edx - mov [edx + MEM_BLOCK.prev_block], esi - mov ecx, [edi + MEM_BLOCK.size] - add [esi + MEM_BLOCK.size], ecx - - calc_index ecx - - lea edx, [mem_block_list + ecx*8] - cmp edx, [edx] - jne @F - btr [mem_block_mask], ecx -@@: - mov eax, edi - call free_mem_block -.prev: - mov edi, [esi + MEM_BLOCK.prev_block] - cmp [edi + MEM_BLOCK.flags], MEM_BLOCK_FREE - jne .insert - - mov edx, [esi + MEM_BLOCK.next_block] - mov [edi + MEM_BLOCK.next_block], edx - mov [edx + MEM_BLOCK.prev_block], edi - - mov eax, esi - call free_mem_block - - mov ecx, [edi + MEM_BLOCK.size] - mov eax, [esi + MEM_BLOCK.size] - add eax, ecx - mov [edi + MEM_BLOCK.size], eax - - calc_index eax ;new index - calc_index ecx ;old index - cmp eax, ecx - je .m_eq - - push ecx - list_del edi - pop ecx - - lea edx, [mem_block_list + ecx*8] - cmp edx, [edx] - jne .add_block - btr [mem_block_mask], ecx - -.add_block: - bts [mem_block_mask], eax - lea edx, [mem_block_list + eax*8] - list_add edi, edx -.m_eq: - spin_unlock_irqrestore heap_mutex - xor eax, eax - not eax - ret -.insert: - mov [esi + MEM_BLOCK.flags], MEM_BLOCK_FREE - mov eax, [esi + MEM_BLOCK.size] - calc_index eax - mov edi, esi - jmp .add_block - -.fail: - spin_unlock_irqrestore heap_mutex - xor eax, eax - ret -endp - -align 4 -proc kernel_alloc stdcall, size:dword - locals - lin_addr dd ? - pages_count dd ? - endl - - push ebx - push edi - - mov eax, [size] - add eax, 4095 - and eax, not 4095; - mov [size], eax - and eax, eax - jz .err - mov ebx, eax - shr ebx, 12 - mov [pages_count], ebx - - stdcall alloc_kernel_space, eax - mov [lin_addr], eax - mov ebx, [pages_count] - test eax, eax - jz .err - - mov edx, eax - - shr ebx, 3 - jz .tail - - shl ebx, 3 - stdcall alloc_pages, ebx - test eax, eax - jz .err - - mov ecx, ebx - or eax, PG_GLOBAL + PG_SWR - mov ebx, [lin_addr] - call commit_pages - - mov edx, ebx ; this dirty hack -.tail: - mov ebx, [pages_count] - and ebx, 7 - jz .end -@@: - call alloc_page - test eax, eax - jz .err - - stdcall map_page, edx, eax, dword (PG_GLOBAL + PG_SWR) - add edx, 0x1000 - dec ebx - jnz @B -.end: - mov eax, [lin_addr] - pop edi - pop ebx - ret -.err: - xor eax, eax - pop edi - pop ebx - ret -endp - -align 4 -proc kernel_free stdcall, base:dword - - push ebx esi - - spin_lock_irqsave heap_mutex - - mov eax, [base] - call md.find_used - - cmp [esi + MEM_BLOCK.flags], MEM_BLOCK_USED - jne .fail - - spin_unlock_irqrestore heap_mutex - - mov eax, [esi + MEM_BLOCK.base] - mov ecx, [esi + MEM_BLOCK.size] - shr ecx, 12 - call release_pages ;eax, ecx - stdcall free_kernel_space, [base] - pop esi ebx - ret -.fail: - spin_unlock_irqrestore heap_mutex - xor eax, eax - pop esi ebx - ret -endp - -;;;;;;;;;;;;;; USER HEAP ;;;;;;;;;;;;;;;;; - -HEAP_TOP = 0x80000000 - -align 4 -proc init_heap - - mov ebx, [current_process] - mov eax, [ebx + PROC.heap_top] - test eax, eax - jz @F - sub eax, [ebx + PROC.heap_base] - sub eax, PAGE_SIZE - ret -@@: - lea ecx, [ebx + PROC.heap_lock] - call mutex_init - - mov esi, [ebx + PROC.mem_used] - add esi, 4095 - and esi, not 4095 - mov [ebx + PROC.mem_used], esi - mov eax, HEAP_TOP - mov [ebx + PROC.heap_base], esi - mov [ebx + PROC.heap_top], eax - - sub eax, esi - shr esi, 10 - mov ecx, eax - sub eax, PAGE_SIZE - or ecx, MEM_BLOCK_FREE - mov [page_tabs + esi], ecx - ret -endp - -align 4 -proc user_alloc stdcall, alloc_size:dword - - push ebx esi edi - - mov ebx, [current_process] - lea ecx, [ebx + PROC.heap_lock] - call mutex_lock - - mov ecx, [alloc_size] - add ecx, (4095 + PAGE_SIZE) - and ecx, not 4095 - mov esi, [ebx + PROC.heap_base] - mov edi, [ebx + PROC.heap_top] - .scan: - cmp esi, edi - jae .m_exit - - mov ebx, esi - shr ebx, 12 - mov eax, [page_tabs + ebx*4] - test al, MEM_BLOCK_FREE - jz .test_used - and eax, 0xFFFFF000 - cmp eax, ecx ;alloc_size - jb .m_next - jz @f - - lea edx, [esi + ecx] - sub eax, ecx - or al, MEM_BLOCK_FREE - shr edx, 12 - mov [page_tabs + edx*4], eax - @@: - or ecx, MEM_BLOCK_USED - mov [page_tabs + ebx*4], ecx - shr ecx, 12 - inc ebx - dec ecx - jz .no - @@: - mov dword [page_tabs + ebx*4], MEM_BLOCK_RESERVED - inc ebx - dec ecx - jnz @B - .no: - - mov edx, [current_process] - mov ebx, [alloc_size] - add ebx, 0xFFF - and ebx, not 0xFFF - add [edx + PROC.mem_used], ebx - - lea ecx, [edx + PROC.heap_lock] - call mutex_unlock - - lea eax, [esi + 4096] - - pop edi - pop esi - pop ebx - ret -.test_used: - test al, MEM_BLOCK_USED - jz .m_exit - - and eax, 0xFFFFF000 ; not PAGESIZE -.m_next: - add esi, eax - jmp .scan -.m_exit: - mov ecx, [current_process] - lea ecx, [ecx + PROC.heap_lock] - call mutex_unlock - - xor eax, eax - pop edi - pop esi - pop ebx - ret -endp - -align 4 -proc user_alloc_at stdcall, address:dword, alloc_size:dword - - push ebx - push esi - push edi - - mov ebx, [current_process] - lea ecx, [ebx + PROC.heap_lock] - call mutex_lock - - mov edx, [address] - and edx, not 0xFFF - mov [address], edx - sub edx, 0x1000 - jb .error - mov esi, [ebx + PROC.heap_base] - mov edi, [ebx + PROC.heap_top] - cmp edx, esi - jb .error -.scan: - cmp esi, edi - jae .error - mov ebx, esi - shr ebx, 12 - mov eax, [page_tabs + ebx*4] - mov ecx, eax - and ecx, 0xFFFFF000 - add ecx, esi - cmp edx, ecx - jb .found - mov esi, ecx - jmp .scan -.error: - mov ecx, [current_process] - lea ecx, [ecx + PROC.heap_lock] - call mutex_unlock - - xor eax, eax - pop edi - pop esi - pop ebx - ret -.found: - test al, MEM_BLOCK_FREE - jz .error - mov eax, ecx - sub eax, edx - sub eax, 0x1000 - cmp eax, [alloc_size] - jb .error - -; Here we have 1 big free block which includes requested area. -; In general, 3 other blocks must be created instead: -; free at [esi, edx); -; busy at [edx, edx + 0x1000 + ALIGN_UP(alloc_size,0x1000)); -; free at [edx + 0x1000 + ALIGN_UP(alloc_size,0x1000), ecx) -; First or third block (or both) may be absent. - mov eax, edx - sub eax, esi - jz .nofirst - or al, MEM_BLOCK_FREE - mov [page_tabs + ebx*4], eax - .nofirst: - mov eax, [alloc_size] - add eax, 0x1FFF - and eax, not 0xFFF - mov ebx, edx - add edx, eax - shr ebx, 12 - or al, MEM_BLOCK_USED - mov [page_tabs + ebx*4], eax - shr eax, 12 - dec eax - jz .second_nofill - inc ebx - .fill: - mov dword [page_tabs + ebx*4], MEM_BLOCK_RESERVED - inc ebx - dec eax - jnz .fill - - .second_nofill: - sub ecx, edx - jz .nothird - or cl, MEM_BLOCK_FREE - mov [page_tabs + ebx*4], ecx - - .nothird: - mov edx, [current_process] - mov ebx, [alloc_size] - add ebx, 0xFFF - and ebx, not 0xFFF - add [edx + PROC.mem_used], ebx - - lea ecx, [edx + PROC.heap_lock] - call mutex_unlock - - mov eax, [address] - - pop edi - pop esi - pop ebx - ret -endp - -align 4 -proc user_free stdcall, base:dword - - push esi - - mov esi, [base] - test esi, esi - jz .fail - - push ebx - - mov ebx, [current_process] - lea ecx, [ebx + PROC.heap_lock] - call mutex_lock - - xor ebx, ebx - shr esi, 12 - mov eax, [page_tabs + (esi-1)*4] - test al, MEM_BLOCK_USED - jz .cantfree - test al, MEM_BLOCK_DONT_FREE - jnz .cantfree - - and eax, not 4095 - mov ecx, eax - or al, MEM_BLOCK_FREE - mov [page_tabs + (esi-1)*4], eax - sub ecx, 4096 - mov ebx, ecx - shr ecx, 12 - jz .released - .release: - xor eax, eax - xchg eax, [page_tabs + esi*4] - test al, 1 - jz @F - test eax, PG_SHARED - jnz @F - call free_page - mov eax, esi - shl eax, 12 - invlpg [eax] - @@: - inc esi - dec ecx - jnz .release - - .released: - push edi - - mov edx, [current_process] - lea ecx, [edx + PROC.heap_lock] - mov esi, dword [edx + PROC.heap_base] - mov edi, dword [edx + PROC.heap_top] - sub ebx, [edx + PROC.mem_used] - neg ebx - mov [edx + PROC.mem_used], ebx - call user_normalize - pop edi - .exit: - call mutex_unlock - - xor eax, eax - inc eax - pop ebx - pop esi - ret - - .cantfree: - mov ecx, [current_process] - lea ecx, [ecx + PROC.heap_lock] - jmp .exit - .fail: - xor eax, eax - pop esi - ret -endp - - -align 4 -proc user_unmap stdcall, base:dword, offset:dword, size:dword - - push ebx - - mov ebx, [base] ; must be valid pointer - test ebx, ebx - jz .error - - mov edx, [offset] ; check offset - add edx, ebx ; must be below 2Gb app limit - js .error - - shr ebx, 12 ; chek block attributes - lea ebx, [page_tabs + ebx*4] - mov eax, [ebx-4] ; block attributes - test al, MEM_BLOCK_USED - jz .error - test al, MEM_BLOCK_DONT_FREE - jnz .error - - shr edx, 12 - lea edx, [page_tabs + edx*4] ; unmap offset - - mov ecx, [size] - add ecx, 4095 - shr ecx, 12 ; unmap size in pages - - shr eax, 12 ; block size + 1 page - lea ebx, [ebx + eax*4-4] ; block end ptr - lea eax, [edx + ecx*4] ; unmap end ptr - - cmp eax, ebx ; check for overflow - ja .error - - mov ebx, [offset] - and ebx, not 4095 ; is it required ? - add ebx, [base] - - .unmap: - mov eax, [edx] ; get page addres - test al, 1 ; page mapped ? - jz @F - test eax, PG_SHARED ; page shared ? - jnz @F - mov dword[edx], MEM_BLOCK_RESERVED - ; mark page as reserved - invlpg [ebx] ; when we start using - call free_page ; empty c-o-w page instead this ? - @@: - add ebx, 4096 ; PAGESIZE? - add edx, 4 - dec ecx - jnz .unmap - - pop ebx - or al, 1 ; return non zero on success - ret -.error: - pop ebx - xor eax, eax ; something wrong - ret -endp - -align 4 -user_normalize: -; in: esi=heap_base, edi=heap_top -; out: eax=0 <=> OK -; destroys: ebx,edx,esi,edi - shr esi, 12 - shr edi, 12 -@@: - mov eax, [page_tabs + esi*4] - test al, MEM_BLOCK_USED - jz .test_free - shr eax, 12 - add esi, eax - jmp @B -.test_free: - test al, MEM_BLOCK_FREE - jz .err - mov edx, eax - shr edx, 12 - add edx, esi - cmp edx, edi - jae .exit - - mov ebx, [page_tabs + edx*4] - test bl, MEM_BLOCK_USED - jz .next_free - - shr ebx, 12 - add edx, ebx - mov esi, edx - jmp @B -.next_free: - test bl, MEM_BLOCK_FREE - jz .err - and dword[page_tabs + edx*4], 0 - add eax, ebx - and eax, not 4095 ; not (PAGESIZE - 1) ? - or eax, MEM_BLOCK_FREE - mov [page_tabs + esi*4], eax - jmp @B -.exit: - xor eax, eax - inc eax - ret -.err: - xor eax, eax - ret - -user_realloc: -; in: eax = pointer, ebx = new size -; out: eax = new pointer or NULL - test eax, eax - jnz @f -; realloc(NULL,sz) - same as malloc(sz) - push ebx - call user_alloc - ret -@@: - push ecx edx - - push eax - mov ecx, [current_process] - lea ecx, [ecx + PROC.heap_lock] - call mutex_lock - pop eax - - lea ecx, [eax - 0x1000] - shr ecx, 12 - mov edx, [page_tabs + ecx*4] - test dl, MEM_BLOCK_USED - jnz @f -; attempt to realloc invalid pointer -.ret0: - mov ecx, [current_process] - lea ecx, [ecx + PROC.heap_lock] - call mutex_unlock - - pop edx ecx - xor eax, eax - ret -@@: - test dl, MEM_BLOCK_DONT_FREE - jnz .ret0 - add ebx, 0x1FFF - shr edx, 12 - shr ebx, 12 -; edx = allocated size, ebx = new size - add edx, ecx - add ebx, ecx - cmp edx, ebx - jb .realloc_add -; release part of allocated memory -.loop: - cmp edx, ebx - jz .release_done - dec edx - xor eax, eax - xchg eax, [page_tabs + edx*4] - test al, 1 - jz .loop - call free_page - mov eax, edx - shl eax, 12 - invlpg [eax] - jmp .loop -.release_done: - sub ebx, ecx - cmp ebx, 1 - jnz .nofreeall - mov eax, [page_tabs + ecx*4] - and eax, not 0xFFF - mov edx, [current_process] - mov ebx, [edx + PROC.mem_used] - sub ebx, eax - add ebx, 0x1000 - or al, MEM_BLOCK_FREE - mov [page_tabs + ecx*4], eax - push esi edi - mov esi, [edx + PROC.heap_base] - mov edi, [edx + PROC.heap_top] - mov [edx + PROC.mem_used], ebx - call user_normalize - pop edi esi - jmp .ret0 ; all freed -.nofreeall: - sub edx, ecx - shl ebx, 12 - or ebx, MEM_BLOCK_USED - xchg [page_tabs + ecx*4], ebx - shr ebx, 12 - sub ebx, edx - push ebx ecx edx - mov edx, [current_process] - shl ebx, 12 - sub ebx, [edx + PROC.mem_used] - neg ebx - mov [edx + PROC.mem_used], ebx - pop edx ecx ebx - lea eax, [ecx + 1] - shl eax, 12 - push eax - add ecx, edx - lea edx, [ecx + ebx] - shl ebx, 12 - jz .ret - push esi - mov esi, [current_process] - mov esi, [esi + PROC.heap_top] - shr esi, 12 -@@: - cmp edx, esi - jae .merge_done - mov eax, [page_tabs + edx*4] - test al, MEM_BLOCK_USED - jnz .merge_done - and dword [page_tabs + edx*4], 0 - shr eax, 12 - add edx, eax - shl eax, 12 - add ebx, eax - jmp @b -.merge_done: - pop esi - or ebx, MEM_BLOCK_FREE - mov [page_tabs + ecx*4], ebx -.ret: - mov ecx, [current_process] - lea ecx, [ecx + PROC.heap_lock] - call mutex_unlock - pop eax edx ecx - ret - -.realloc_add: -; get some additional memory - mov eax, [current_process] - mov eax, [eax + PROC.heap_top] - shr eax, 12 - cmp edx, eax - jae .cant_inplace - mov eax, [page_tabs + edx*4] - test al, MEM_BLOCK_FREE - jz .cant_inplace - shr eax, 12 - add eax, edx - sub eax, ebx - jb .cant_inplace - jz @f - shl eax, 12 - or al, MEM_BLOCK_FREE - mov [page_tabs + ebx*4], eax -@@: - mov eax, ebx - sub eax, ecx - shl eax, 12 - or al, MEM_BLOCK_USED - mov [page_tabs + ecx*4], eax - lea eax, [ecx + 1] - shl eax, 12 - push eax - push edi - lea edi, [page_tabs + edx*4] - mov eax, 2 - sub ebx, edx - mov ecx, ebx - cld - rep stosd - pop edi - mov edx, [current_process] - shl ebx, 12 - add [edx + PROC.mem_used], ebx - - mov ecx, [current_process] - lea ecx, [ecx + PROC.heap_lock] - call mutex_unlock - pop eax edx ecx - ret - -.cant_inplace: - push esi edi - mov eax, [current_process] - mov esi, [eax + PROC.heap_base] - mov edi, [eax + PROC.heap_top] - shr esi, 12 - shr edi, 12 - sub ebx, ecx -.find_place: - cmp esi, edi - jae .place_not_found - mov eax, [page_tabs + esi*4] - test al, MEM_BLOCK_FREE - jz .next_place - shr eax, 12 - cmp eax, ebx - jae .place_found - add esi, eax - jmp .find_place -.next_place: - shr eax, 12 - add esi, eax - jmp .find_place -.place_not_found: - pop edi esi - jmp .ret0 -.place_found: - sub eax, ebx - jz @f - push esi - add esi, ebx - shl eax, 12 - or al, MEM_BLOCK_FREE - mov [page_tabs + esi*4], eax - pop esi -@@: - mov eax, ebx - shl eax, 12 - or al, MEM_BLOCK_USED - mov [page_tabs + esi*4], eax - inc esi - mov eax, esi - shl eax, 12 - push eax - mov eax, [page_tabs + ecx*4] - and eax, not 0xFFF - or al, MEM_BLOCK_FREE - sub edx, ecx - mov [page_tabs + ecx*4], eax - inc ecx - dec ebx - dec edx - jz .no -@@: - xor eax, eax - xchg eax, [page_tabs + ecx*4] - mov [page_tabs + esi*4], eax - mov eax, ecx - shl eax, 12 - invlpg [eax] - inc esi - inc ecx - dec ebx - dec edx - jnz @b -.no: - push ebx - mov edx, [current_process] - shl ebx, 12 - add [edx + PROC.mem_used], ebx - pop ebx -@@: - mov dword [page_tabs + esi*4], MEM_BLOCK_RESERVED - inc esi - dec ebx - jnz @b - - mov ecx, [current_process] - lea ecx, [ecx + PROC.heap_lock] - call mutex_unlock - pop eax edi esi edx ecx - ret - - - -;;;;;;;;;;;;;; SHARED MEMORY ;;;;;;;;;;;;;;;;; - - -; param -; eax= shm_map object - -align 4 -destroy_smap: - - pushfd - cli - - push esi - push edi - - mov edi, eax - mov esi, [eax + SMAP.parent] - test esi, esi - jz .done - - lock dec [esi + SMEM.refcount] - jnz .done - - mov ecx, [esi + SMEM.bk] - mov edx, [esi + SMEM.fd] - - mov [ecx + SMEM.fd], edx - mov [edx + SMEM.bk], ecx - - stdcall kernel_free, [esi + SMEM.base] - mov eax, esi - call free -.done: - mov eax, edi - call destroy_kernel_object - - pop edi - pop esi - popfd - - ret - -E_NOTFOUND = 5 -E_ACCESS = 10 -E_NOMEM = 30 -E_PARAM = 33 - -SHM_READ = 0 -SHM_WRITE = 1 - -SHM_ACCESS_MASK = 3 - -SHM_OPEN = 0 shl 2 -SHM_OPEN_ALWAYS = 1 shl 2 -SHM_CREATE = 2 shl 2 - -SHM_OPEN_MASK = 3 shl 2 - -align 4 -proc shmem_open stdcall name:dword, size:dword, access:dword - locals - action dd ? - owner_access dd ? - mapped dd ? - endl - - push ebx - push esi - push edi - - mov [mapped], 0 - mov [owner_access], 0 - - pushfd ;mutex required - cli - - mov eax, [access] - and eax, SHM_OPEN_MASK - mov [action], eax - - mov ebx, [name] - test ebx, ebx - mov edx, E_PARAM - jz .fail - - mov esi, [shmem_list.fd] -align 4 -@@: - cmp esi, shmem_list - je .not_found - - lea edx, [esi + SMEM.name]; link , base, size - stdcall strncmp, edx, ebx, 32 - test eax, eax - je .found - - mov esi, [esi + SMEM.fd] - jmp @B - -.not_found: - mov eax, [action] - - cmp eax, SHM_OPEN - mov edx, E_NOTFOUND - je .fail - - cmp eax, SHM_CREATE - mov edx, E_PARAM - je .create_shm - - cmp eax, SHM_OPEN_ALWAYS - jne .fail - -.create_shm: - - mov ecx, [size] - test ecx, ecx - jz .fail - - add ecx, 4095 - and ecx, -4096 - mov [size], ecx - - mov eax, sizeof.SMEM - call malloc - test eax, eax - mov esi, eax - mov edx, E_NOMEM - jz .fail - - stdcall kernel_alloc, [size] - test eax, eax - mov [mapped], eax - mov edx, E_NOMEM - jz .cleanup - - mov ecx, [size] - mov edx, [access] - and edx, SHM_ACCESS_MASK - - mov [esi + SMEM.base], eax - mov [esi + SMEM.size], ecx - mov [esi + SMEM.access], edx - mov [esi + SMEM.refcount], 0 - mov [esi + SMEM.name + 28], 0 - - lea eax, [esi + SMEM.name] - stdcall strncpy, eax, [name], 31 - - mov eax, [shmem_list.fd] - mov [esi + SMEM.bk], shmem_list - mov [esi + SMEM.fd], eax - - mov [eax + SMEM.bk], esi - mov [shmem_list.fd], esi - - mov [action], SHM_OPEN - mov [owner_access], SHM_WRITE - -.found: - mov eax, [action] - - cmp eax, SHM_CREATE - mov edx, E_ACCESS - je .exit - - cmp eax, SHM_OPEN - mov edx, E_PARAM - je .create_map - - cmp eax, SHM_OPEN_ALWAYS - jne .fail - -.create_map: - - mov eax, [access] - and eax, SHM_ACCESS_MASK - cmp eax, [esi + SMEM.access] - mov [access], eax - mov edx, E_ACCESS - ja .fail - - mov ebx, [current_slot_idx] - shl ebx, BSF sizeof.TASKDATA - mov ebx, [TASK_TABLE + ebx + TASKDATA.pid] - mov eax, sizeof.SMAP - - call create_kernel_object - test eax, eax - mov edi, eax - mov edx, E_NOMEM - jz .fail - - inc [esi + SMEM.refcount] - - mov [edi + SMAP.magic], 'SMAP' - mov [edi + SMAP.destroy], destroy_smap - mov [edi + SMAP.parent], esi - mov [edi + SMAP.base], 0 - - stdcall user_alloc, [esi + SMEM.size] - test eax, eax - mov [mapped], eax - mov edx, E_NOMEM - jz .cleanup2 - - mov [edi + SMAP.base], eax - - mov ecx, [esi + SMEM.size] - mov [size], ecx - - shr ecx, 12 - shr eax, 10 - - mov esi, [esi + SMEM.base] - shr esi, 10 - lea edi, [page_tabs + eax] - add esi, page_tabs - - mov edx, [access] - or edx, [owner_access] - shl edx, 1 - or edx, PG_SHARED + PG_UR -@@: - lodsd - and eax, 0xFFFFF000 - or eax, edx - stosd - loop @B - - xor edx, edx - - cmp [owner_access], 0 - jne .fail -.exit: - mov edx, [size] -.fail: - mov eax, [mapped] - - popfd - pop edi - pop esi - pop ebx - ret -.cleanup: - mov [size], edx - mov eax, esi - call free - jmp .exit - -.cleanup2: - mov [size], edx - mov eax, edi - call destroy_smap - jmp .exit -endp - -align 4 -proc shmem_close stdcall, name:dword - - mov eax, [name] - test eax, eax - jz .fail - - push esi - push edi - pushfd - cli - - mov esi, [current_slot] - add esi, APP_OBJ_OFFSET -.next: - mov eax, [esi + APPOBJ.fd] - test eax, eax - jz @F - - cmp eax, esi - mov esi, eax - je @F - - cmp [eax + SMAP.magic], 'SMAP' - jne .next - - mov edi, [eax + SMAP.parent] - test edi, edi - jz .next - - lea edi, [edi + SMEM.name] - stdcall strncmp, [name], edi, 32 - test eax, eax - jne .next - - stdcall user_free, [esi + SMAP.base] - - mov eax, esi - call [esi + APPOBJ.destroy] -@@: - popfd - pop edi - pop esi -.fail: - ret -endp - - - -proc user_ring stdcall, size:dword - -locals - virt_ptr dd ? - phys_ptr dd ? - num_pages dd ? -endl - -; Size must be an exact multiple of pagesize - mov eax, [size] - test eax, PAGE_SIZE-1 - jnz .exit - -; We must have at least one complete page - shr eax, 12 - jz .exit - mov [num_pages], eax - -; Allocate double the virtual memory - mov eax, [size] - shl eax, 1 - jz .exit - stdcall user_alloc, eax - test eax, eax - jz .exit - mov [virt_ptr], eax - -; Now allocate physical memory - stdcall alloc_pages, [num_pages] - test eax, eax - jz .exit_free_virt - mov [phys_ptr], eax - -; Map first half of virtual memory to physical memory - push ecx esi edi - mov ecx, [num_pages] - mov esi, [virt_ptr] - mov edi, [phys_ptr] - .loop1: - stdcall map_page, esi, edi, PG_UWR - add esi, PAGE_SIZE - add edi, PAGE_SIZE - dec ecx - jnz .loop1 - -; Map second half of virtual memory to same physical memory - mov ecx, [num_pages] - mov edi, [phys_ptr] - .loop2: - stdcall map_page, esi, edi, PG_UWR - add esi, PAGE_SIZE - add edi, PAGE_SIZE - dec ecx - jnz .loop2 - pop edi esi ecx - - mov eax, [virt_ptr] - ret - - .exit_free_virt: - stdcall user_free, [virt_ptr] - - .exit: - xor eax, eax - ret - -endp \ No newline at end of file diff --git a/kernel/branches/Kolibri-F/core/hpet.inc b/kernel/branches/Kolibri-F/core/hpet.inc deleted file mode 100644 index 08b504a23..000000000 --- a/kernel/branches/Kolibri-F/core/hpet.inc +++ /dev/null @@ -1,74 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -HPET_ID = 0x0000 -HPET_PERIOD = 0x0004 -HPET_CFG_ENABLE = 0x0001 -HPET_CFG = 0x0010 -HPET_COUNTER = 0x00f0 -HPET_T0_CFG = 0x0100 - -HPET_TN_LEVEL = 0x0002 -HPET_TN_ENABLE = 0x0004 -HPET_TN_FSB = 0x4000 - -uglobal -hpet_base rd 1 -hpet_period rd 1 -hpet_timers rd 1 -hpet_tsc_start rd 2 -endg - -align 4 -init_hpet: - mov ebx, [hpet_base] - test ebx, ebx - jz .done - - mov eax, [ebx] - and ah, 0x1F - inc ah - movzx eax, ah - mov [hpet_timers], eax - mov ecx, eax - - mov eax, [ebx+HPET_PERIOD] - xor edx, edx - shld edx, eax, 10 - shl eax, 10 - mov esi, 1000000 - div esi - mov [hpet_period], eax - - mov esi, [ebx+HPET_CFG] - and esi, not HPET_CFG_ENABLE - mov [ebx+HPET_CFG], esi ;stop main counter - - lea edx, [ebx+HPET_T0_CFG] -@@: - jcxz @F - mov eax, [edx] - and eax, not (HPET_TN_ENABLE+HPET_TN_LEVEL+HPET_TN_FSB) - mov [edx], eax - add edx, 0x20 - dec ecx - jmp @B -@@: - mov [ebx+HPET_COUNTER], ecx ;reset main counter - mov [ebx+HPET_COUNTER+4], ecx - - or esi, HPET_CFG_ENABLE - mov [ebx+HPET_CFG], esi ;and start again - -.done: - rdtsc - mov [hpet_tsc_start], eax - mov [hpet_tsc_start+4], edx - - ret diff --git a/kernel/branches/Kolibri-F/core/irq.inc b/kernel/branches/Kolibri-F/core/irq.inc deleted file mode 100644 index deac174d5..000000000 --- a/kernel/branches/Kolibri-F/core/irq.inc +++ /dev/null @@ -1,294 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -IRQ_RESERVED = 56 - -IRQ_POOL_SIZE = 48 - -uglobal - -align 16 -irqh_tab rd sizeof.LHEAD * IRQ_RESERVED / 4 - -irqh_pool rd sizeof.IRQH * IRQ_POOL_SIZE /4 -next_irqh rd 1 - -irq_active_set rd (IRQ_RESERVED+31)/32 -irq_failed rd IRQ_RESERVED - -endg - -set_irq_active: - mov eax, ebp - mov ecx, ebp - shr ecx, 5 - and eax, 31 - bts [irq_active_set+ecx*4], eax - ret - -reset_irq_active: - mov eax, ebp - mov ecx, ebp - shr ecx, 5 - and eax, 31 - btr [irq_active_set+ecx*4], eax - ret - -align 4 -init_irqs: - - mov ecx, IRQ_RESERVED - mov edi, irqh_tab -@@: - mov eax, edi - stosd - stosd - loop @B - - mov ecx, IRQ_POOL_SIZE-1 - mov eax, irqh_pool+sizeof.IRQH - mov [next_irqh], irqh_pool -@@: - mov [eax-sizeof.IRQH], eax - add eax, sizeof.IRQH - loop @B - - mov [eax-sizeof.IRQH], dword 0 - ret - - -align 4 -proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword - locals - .irqh dd ? - endl - - DEBUGF 1, "K : Attach Interrupt %d Handler %x\n", [irq], [handler] - - and [.irqh], 0 - - push ebx - - mov ebx, [irq] ;irq num - test ebx, ebx - jz .err - - cmp ebx, IRQ_RESERVED - jae .err - - mov edx, [handler] - test edx, edx - jz .err - - spin_lock_irqsave IrqsList - -;allocate handler - - mov ecx, [next_irqh] - test ecx, ecx - jz .fail - - mov eax, [ecx] - mov [next_irqh], eax - mov [.irqh], ecx - - mov [irq_failed+ebx*4], 0;clear counter - - mov eax, [user_data] - mov [ecx+IRQH.handler], edx - mov [ecx+IRQH.data], eax - and [ecx+IRQH.num_ints], 0 - - lea edx, [irqh_tab+ebx*8] - list_add_tail ecx, edx ;clobber eax - stdcall enable_irq, ebx - -.fail: - spin_unlock_irqrestore IrqsList -.err: - pop ebx - mov eax, [.irqh] - ret - -endp - -if 0 -align 4 -proc get_int_handler stdcall, irq:dword - - mov eax, [irq] - cmp eax, 15 - ja .fail - mov eax, [irq_tab + 4 * eax] - ret -.fail: - xor eax, eax - ret -endp -end if - - -align 4 -proc detach_int_handler - - ret -endp - - -macro irq_serv_h [num] { - forward -align 4 - .irq_#num : - push num - jmp .main -} - -align 16 -irq_serv: - -rept 12 irqn:1 {irq_serv_h irqn} ; 1--12 -rept 18 irqn:14 {irq_serv_h irqn} ; 14--31 (irq32 is vector 0x40) -rept 23 irqn:33 {irq_serv_h irqn} ; 33--55 - -purge irq_serv_h - -align 16 -.main: - save_ring3_context - mov ebp, [esp + 32] - mov bx, app_data;os_data - mov ds, bx - mov es, bx - - cmp [v86_irqhooks+ebp*8], 0 - jnz v86_irq - - call set_irq_active - - lea esi, [irqh_tab+ebp*8] ; esi= list head - mov ebx, esi -.next: - mov ebx, [ebx+IRQH.list.next]; ebx= irqh pointer - cmp ebx, esi - je .done - - push ebx ; FIX THIS - push edi - push esi - - push [ebx+IRQH.data] - call [ebx+IRQH.handler] - pop ecx - - pop esi - pop edi - pop ebx - - test eax, eax - jz .next - - inc [ebx+IRQH.num_ints] - call reset_irq_active - jmp .next - -.done: - call reset_irq_active - jnc .exit - -; There is at least one configuration with one device which generates IRQ -; that is not the same as it should be according to PCI config space. -; For that device, the handler is registered at wrong IRQ. -; As a workaround, when nobody acknowledges the generated IRQ, -; try to ask all other registered handlers; if some handler acknowledges -; the IRQ this time, relink it to the current IRQ list. -; To make this more reliable, for every handler keep number of times -; that it has acknowledged an IRQ, and assume that handlers with at least one -; acknowledged IRQ are registered properly. -; Note: this still isn't 100% correct, because two IRQs can fire simultaneously, -; the better way would be to find the correct IRQ, but I don't know how to do -; this in that case. - cmp ebp, 1 - jz .fail - push ebp - xor ebp, ebp -.try_other_irqs: - cmp ebp, [esp] - jz .try_next_irq - cmp ebp, 1 - jz .try_next_irq - cmp ebp, 6 - jz .try_next_irq - cmp ebp, 12 - jz .try_next_irq - cmp ebp, 14 - jz .try_next_irq - cmp ebp, 15 - jz .try_next_irq - lea esi, [irqh_tab+ebp*8] - mov ebx, esi -.try_next_handler: - mov ebx, [ebx+IRQH.list.next] - cmp ebx, esi - je .try_next_irq - cmp [ebx+IRQH.num_ints], 0 - jne .try_next_handler -; keyboard handler acknowledges everything - push [ebx+IRQH.data] - call [ebx+IRQH.handler] - pop ecx - test eax, eax - jz .try_next_handler - -.found_in_wrong_list: - DEBUGF 1,'K : warning: relinking handler from IRQ%d to IRQ%d\n',\ - ebp, [esp] - pop ebp - spin_lock_irqsave IrqsList - list_del ebx - lea edx, [irqh_tab+ebp*8] - list_add_tail ebx, edx - spin_unlock_irqrestore IrqsList - jmp .exit - -.try_next_irq: - inc ebp - cmp ebp, 16 - jb .try_other_irqs - pop ebp - -.fail: - inc [irq_failed+ebp*4] -.exit: - - mov ecx, ebp - call irq_eoi - -; IRQ handler could make some kernel thread ready; reschedule - mov bl, SCHEDULE_HIGHER_PRIORITY - call find_next_task - jz .return ; if there is only one running process - call do_change_task - .return: - restore_ring3_context - add esp, 4 - iret - -align 4 -irqD: - push eax - push ecx - xor eax, eax - out 0xf0, al - mov cl, 13 - call irq_eoi - pop ecx - pop eax - iret - diff --git a/kernel/branches/Kolibri-F/core/malloc.inc b/kernel/branches/Kolibri-F/core/malloc.inc deleted file mode 100644 index b20eead7b..000000000 --- a/kernel/branches/Kolibri-F/core/malloc.inc +++ /dev/null @@ -1,1035 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; Small heap based on malloc/free/realloc written by Doug Lea -; Version 2.8.3 Thu Sep 22 11:16:15 2005 Doug Lea (dl at gee) -; Source ftp://gee.cs.oswego.edu/pub/misc/malloc.c -; License http://creativecommons.org/licenses/publicdomain. - - -; eax= size - -; temp -; esi= nb -; ebx= idx -; -align 4 -malloc: - push ebx esi - -; nb = ((size+7)&~7)+8; - - mov esi, eax ;size - add esi, 7 - and esi, -8 - add esi, 8 - - mov ecx, mst.mutex - call mutex_lock - - cmp esi, 256 - jae .large - - mov ecx, esi - shr ecx, 3 - or eax, -1 - shl eax, cl - and eax, [mst.smallmap] - jz .small - - push ebp - push edi - - bsf eax, eax - mov ebx, eax - -; psize= idx<<3; -; B = &ms.smallbins[idx]; -; p = B->fd; -; F = p->fd; -; rsize= psize-nb; - - lea ebp, [eax*8] ;ebp= psize - shl eax, 4 - lea edi, [mst.smallbins+eax] ;edi= B - mov edx, [edi+8] ;edx= p - mov eax, [edx+8] ;eax= F - mov ecx, ebp - sub ecx, esi ;ecx= rsize - -; if (B == F) - cmp edi, eax - jne @F - - btr [mst.smallmap], ebx -@@: - -; B->fd = F; -; F->bk = B; -; if(rsize<16) - - cmp ecx, 16 - mov [edi+8], eax - mov [eax+12], edi - jae .split - -; p->head = psize|PINUSE_BIT|CINUSE_BIT; -; (p + psize)->head |= PINUSE_BIT; - - lea eax, [edx+8] - or dword [edx+ebp+4], 1 - - or ebp, 3 - mov [edx+4], ebp - - pop edi - pop ebp -.done: - mov esi, eax - mov ecx, mst.mutex - call mutex_unlock - mov eax, esi - pop esi ebx - ret - -.split: - lea ebx, [edx+8] ;ebx=mem - -; r = chunk_plus_offset(p, nb); -; p->head = nb|PINUSE_BIT|CINUSE_BIT; -; r->head = rsize|PINUSE_BIT; - - lea eax, [edx+esi] ;eax= r - or esi, 3 - mov [edx+4], esi - - mov edx, ecx - or edx, 1 - mov [eax+4], edx - -; (r + rsize)->prev_foot = rsize; - - mov [eax+ecx], ecx - -; I = rsize>>3; - - shr ecx, 3 - -; ms.smallmap |= 1<< I; - bts [mst.smallmap], ecx - -; B = &ms.smallbins[I]; - - shl ecx, 4 - pop edi - pop ebp - add ecx, mst.smallbins ;ecx= B - - mov edx, [ecx+8] ; F = B->fd; - mov [ecx+8], eax ; B->fd = r; - mov [edx+12], eax ; F->bk = r; - mov [eax+8], edx ; r->fd = F; - mov [eax+12], ecx ; r->bk = B; - - mov eax, ebx - jmp .done - -.small: - -; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0) -;;;;;;;;;;; start a change - mov eax, [mst.treemap] - test eax, eax -;;;;;;;;;;; end the change -; cmp [mst.treemap], 0 - jz .from_top - mov eax, esi - call malloc_small - test eax, eax - jz .from_top - jmp .done - -.large: - -; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0) - - cmp [mst.treemap], 0 - je .from_top - - call malloc_large ;esi= nb - test eax, eax - jne .done -.from_top: - -; if (nb < ms.topsize) - - mov eax, [mst.topsize] - cmp esi, eax - jae .fail - -; rsize = ms.topsize -= nb; -; p = ms.top; - - mov ecx, [mst.top] - sub eax, esi - mov [mst.topsize], eax - -; r = ms.top = chunk_plus_offset(p, nb); -; r->head = rsize | PINUSE_BIT; -; p->head = nb |PINUSE_BIT|CINUSE_BIT; - - lea edx, [ecx+esi] - or eax, 1 - mov [mst.top], edx - or esi, 3 - mov [edx+4], eax - mov [ecx+4], esi - lea eax, [ecx+8] - jmp .done - -.fail: - xor eax, eax - jmp .done - -; param -; eax= mem -align 4 -free: - test eax, eax - jz .exit - - push ebx edi - mov edi, eax - add edi, -8 - -; if(p->head & CINUSE_BIT) - - test byte [edi+4], 2 - je .fail - - mov ecx, mst.mutex - call mutex_lock - -; psize = p->head & (~3); - - mov eax, [edi+4] - push esi - mov esi, eax - and esi, -4 - -; next = chunk_plus_offset(p, psize); -; if(!(p->head & PINUSE_BIT)) - - test al, 1 - lea ebx, [esi+edi] - jne .next - -; prevsize = p->prev_foot; -; prev=p - prevsize; -; psize += prevsize; -; p = prev; - - mov ecx, [edi] ;ecx= prevsize - add esi, ecx ;esi= psize - sub edi, ecx ;edi= p - -; if (prevsize < 256) - - cmp ecx, 256 - jae .unlink_large - - mov eax, [edi+8] ;F = p->fd; - mov edx, [edi+12] ;B = p->bk; - -; if (F == B) -; ms.smallmap &= ~(1<< I); - shr ecx, 3 - cmp eax, edx - jne @F - btr [mst.smallmap], ecx -@@: - mov [eax+12], edx ;F->bk = B; - mov [edx+8], eax ;B->fd = F - jmp .next -.unlink_large: - mov edx, edi - call unlink_large_chunk -.next: - -; if(next->head & PINUSE_BIT) - - mov eax, [ebx+4] - test al, 1 - jz .fail2 - -; if (! (next->head & CINUSE_BIT)) - - test al, 2 - jnz .fix_next - -; if (next == ms.top) - - cmp ebx, [mst.top] - jne @F - -; tsize = ms.topsize += psize; - - mov eax, [mst.topsize] - add eax, esi - mov [mst.topsize], eax - -; ms.top = p; -; p->head = tsize | PINUSE_BIT; - - or eax, 1 - mov [mst.top], edi - mov [edi+4], eax -.fail2: - mov esi, eax - mov ecx, mst.mutex - call mutex_unlock - mov eax, esi - pop esi -.fail: - pop edi ebx -.exit: - ret - -@@: - -; nsize = next->head & ~INUSE_BITS; - - and eax, -4 - add esi, eax ;psize += nsize; - -; if (nsize < 256) - - cmp eax, 256 - jae .unl_large - - mov edx, [ebx+8] ;F = next->fd - mov ebx, [ebx+12] ;B = next->bk - -; if (F == B) - - cmp edx, ebx - jne @F - mov ecx, eax - shr ecx, 3 - btr [mst.smallmap], ecx -@@: - mov [edx+12], ebx ;F->bk = B - -; p->head = psize|PINUSE_BIT; - - mov ecx, esi - mov [ebx+8], edx - or ecx, 1 - mov [edi+4], ecx - -; (p+psize)->prev_foot = psize; - - mov [esi+edi], esi - -; insert_chunk(p,psize); - - mov eax, esi - mov ecx, edi - call insert_chunk - jmp .fail2 -.unl_large: - -; unlink_large_chunk((tchunkptr)next); - - mov edx, ebx - call unlink_large_chunk -; p->head = psize|PINUSE_BIT; - - mov ecx, esi - or ecx, 1 - mov [edi+4], ecx - -; (p+psize)->prev_foot = psize; - - mov [esi+edi], esi - -; insert_chunk(p,psize); - - mov eax, esi - mov ecx, edi - call insert_chunk - jmp .fail2 -.fix_next: - -; (p+psize)->prev_foot = psize; -; next->head &= ~PINUSE_BIT; -; p->head = psize|PINUSE_BIT; - - and eax, -2 - mov edx, esi - mov [ebx+4], eax - or edx, 1 - mov [edi+4], edx - -; (p+psize)->prev_foot = psize; - - mov [esi+edi], esi -; insert_chunk(p,psize); - - mov eax, esi - mov ecx, edi - call insert_chunk - jmp .fail2 - -; param -; ecx = chunk -; eax = size - -insert_chunk: - - cmp eax, 256 - push esi - mov esi, ecx - jae .large - -; I = S>>3; -; ms.smallmap |= 1<< I; - - shr eax, 3 - bts [mst.smallmap], eax - -; B = &ms.smallbins[I]; - - shl eax, 4 - add eax, mst.smallbins - mov edx, [eax+8] ;F = B->fd - mov [eax+8], esi ;B->fd = P - mov [edx+12], esi ;F->bk = P - mov [esi+8], edx ;P->fd = F - mov [esi+12], eax ;P->bk = B - pop esi - ret -.large: - mov ebx, eax - call insert_large_chunk - pop esi - ret - - -; param -; esi= chunk -; ebx= size - -insert_large_chunk: - -; I = compute_tree_index(S); - - mov edx, ebx - shr edx, 8 - bsr eax, edx - lea ecx, [eax+7] - mov edx, ebx - shr edx, cl - and edx, 1 - lea ecx, [edx+eax*2] - -; X->index = I; - mov dword [esi+28], ecx - -; X->child[0] = X->child[1] = 0; - and dword [esi+20], 0 - and dword [esi+16], 0 - -; H = &ms.treebins[I]; - - mov eax, ecx - lea edx, [mst.treebins+eax*4] - -; if (!(ms.treemap & 1<child[(K >> 31) & 1]); - mov ecx, eax - shr ecx, 31 - lea ecx, [edx+ecx*4+16] - -; K <<= 1; -; if (*C != 0) - mov edi, [ecx] - add eax, eax - test edi, edi - jz .insert_child - -; T = *C; - mov edx, edi -.loop: - -; for (;;) -; if ((T->head & ~INUSE_BITS) != S) - - mov ecx, [edx+4] - and ecx, not 3 - cmp ecx, ebx - jne .not_eq_size - -; F = T->fd; - mov eax, [edx+8] - -; T->fd = F->bk = X; - mov [eax+12], esi - mov [edx+8], esi - -; X->fd = F; -; X->bk = T; -; X->parent = 0; - - and dword [esi+24], 0 - mov [esi+8], eax - mov [esi+12], edx - ret -.insert_child: - -; *C = X; - mov [ecx], esi -.done: - -; X->parent = T; - mov [esi+24], edx - -; X->fd = X->bk = X; - mov [esi+12], esi - mov [esi+8], esi - ret - - -; param -; edx= chunk - -unlink_large_chunk: - - mov eax, [edx+12] - cmp eax, edx - push edi - mov edi, [edx+24] - je @F - - mov ecx, [edx+8] ;F = X->fd - mov [ecx+12], eax ;F->bk = R; - mov [eax+8], ecx ;R->fd = F - jmp .parent -@@: - mov eax, [edx+20] - test eax, eax - push esi - lea esi, [edx+20] - jne .loop - - mov eax, [edx+16] - test eax, eax - lea esi, [edx+16] - je .l2 -.loop: - cmp dword [eax+20], 0 - lea ecx, [eax+20] - jne @F - - cmp dword [eax+16], 0 - lea ecx, [eax+16] - je .l1 -@@: - mov eax, [ecx] - mov esi, ecx - jmp .loop -.l1: - mov dword [esi], 0 -.l2: - pop esi -.parent: - test edi, edi - je .done - - mov ecx, [edx+28] - cmp edx, [mst.treebins+ecx*4] - lea ecx, [mst.treebins+ecx*4] - jne .l3 - - test eax, eax - mov [ecx], eax - jne .l5 - - mov ecx, [edx+28] - btr [mst.treemap], ecx - pop edi - ret - -.l3: - cmp [edi+16], edx - jne @F - - mov [edi+16], eax - jmp .l4 - -@@: - mov [edi+20], eax - -.l4: - test eax, eax - je .done - -.l5: - mov [eax+24], edi - mov ecx, [edx+16] - test ecx, ecx - je .l6 - - mov [eax+16], ecx - mov [ecx+24], eax - -.l6: - mov edx, [edx+20] - test edx, edx - je .done - - mov [eax+20], edx - mov [edx+24], eax - -.done: - pop edi - ret - -; param -; esi= nb - -malloc_small: - push ebp - mov ebp, esi - - push edi - - bsf eax, [mst.treemap] - mov ecx, [mst.treebins+eax*4] - -; rsize = (t->head & ~INUSE_BITS) - nb; - - mov edi, [ecx+4] - and edi, -4 - sub edi, esi - -.loop: - mov ebx, ecx - -.loop_1: - -; while ((t = leftmost_child(t)) != 0) - - mov eax, [ecx+16] - test eax, eax - jz @F - mov ecx, eax - jmp .l1 - -@@: - mov ecx, [ecx+20] - -.l1: - test ecx, ecx - jz .unlink - -; trem = (t->head & ~INUSE_BITS) - nb; - - mov eax, [ecx+4] - and eax, -4 - sub eax, ebp - -; if (trem < rsize) - - cmp eax, edi - jae .loop_1 - -; rsize = trem; - - mov edi, eax - jmp .loop -.unlink: - - -; r = chunk_plus_offset((mchunkptr)v, nb); -; unlink_large_chunk(v); - - mov edx, ebx - lea esi, [ebx+ebp] - call unlink_large_chunk - -; if (rsize < 16) - - cmp edi, 16 - jae .split - -; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT; - - lea ecx, [edi+ebp] - -; (v+rsize + nb)->head |= PINUSE_BIT; - - add edi, ebx - lea eax, [edi+ebp+4] - pop edi - or ecx, 3 - mov [ebx+4], ecx - or dword [eax], 1 - pop ebp - - lea eax, [ebx+8] - ret - -.split: - -; v->head = nb|PINUSE_BIT|CINUSE_BIT; -; r->head = rsize|PINUSE_BIT; -; (r+rsize)->prev_foot = rsize; - - or ebp, 3 - mov edx, edi - or edx, 1 - - cmp edi, 256 - mov [ebx+4], ebp - mov [esi+4], edx - mov [esi+edi], edi - jae .large - - shr edi, 3 - bts [mst.smallmap], edi - - mov eax, edi - shl eax, 4 - add eax, mst.smallbins - - mov edx, [eax+8] - mov [eax+8], esi - mov [edx+12], esi - pop edi - mov [esi+12], eax - mov [esi+8], edx - pop ebp - lea eax, [ebx+8] - ret - -.large: - lea eax, [ebx+8] - push eax - mov ebx, edi - call insert_large_chunk - pop eax - pop edi - pop ebp - ret - - -; param -; esi= nb - -malloc_large: -.idx equ esp+4 -.rst equ esp - - push ebp - push esi - push edi - sub esp, 8 -; v = 0; -; rsize = -nb; - - mov edi, esi - mov ebx, esi - xor ebp, ebp - neg edi - -; idx = compute_tree_index(nb); - - mov edx, esi - shr edx, 8 - bsr eax, edx - lea ecx, [eax+7] - shr esi, cl - and esi, 1 - lea ecx, [esi+eax*2] - mov [.idx], ecx - -; if ((t = ms.treebins[idx]) != 0) - - mov eax, [mst.treebins+ecx*4] - test eax, eax - jz .l3 - -; sizebits = nb << leftshift_for_tree_index(idx); - - cmp ecx, 31 - jne @F - xor ecx, ecx - jmp .l1 - -@@: - mov edx, ecx - shr edx, 1 - mov ecx, 37 - sub ecx, edx - -.l1: - mov edx, ebx - shl edx, cl - -; rst = 0; - mov [.rst], ebp - -.loop: - -; trem = (t->head & ~INUSE_BITS) - nb; - - mov ecx, [eax+4] - and ecx, -4 - sub ecx, ebx - -; if (trem < rsize) - - cmp ecx, edi - jae @F -; v = t; -; if ((rsize = trem) == 0) - - test ecx, ecx - mov ebp, eax - mov edi, ecx - je .l2 - -@@: - -; rt = t->child[1]; - - mov ecx, [eax+20] - -; t = t->child[(sizebits >> 31) & 1]; - - mov esi, edx - shr esi, 31 - -; if (rt != 0 && rt != t) - - test ecx, ecx - mov eax, [eax+esi*4+16] - jz @F - cmp ecx, eax - jz @F - -; rst = rt; - mov [.rst], ecx - -@@: -; if (t == 0) - - test eax, eax - jz @F - -; sizebits <<= 1; - - add edx, edx - jmp .loop - -@@: -; t = rst; - mov eax, [.rst] - -.l2: -; if (t == 0 && v == 0) - - test eax, eax - jne .l4 - test ebp, ebp - jne .l7 - mov ecx, [.idx] - -.l3: - -; leftbits = (-1<head & ~INUSE_BITS) - nb; - - mov ecx, [eax+4] - and ecx, -4 - sub ecx, ebx - -; if (trem < rsize) - - cmp ecx, edi - jae @F -; rsize = trem; - - mov edi, ecx -; v = t; - mov ebp, eax - -@@: - -; t = leftmost_child(t); - - mov ecx, [eax+16] - test ecx, ecx - je @F - mov eax, ecx - jmp .l6 - -@@: - mov eax, [eax+20] - -.l6: - -; while (t != 0) - - test eax, eax - jne .l4 - -.l5: - -; if (v != 0) - - test ebp, ebp - jz .done - -.l7: - -; r = chunk_plus_offset((mchunkptr)v, nb); -; unlink_large_chunk(v); - - mov edx, ebp - lea esi, [ebx+ebp] - call unlink_large_chunk - -; if (rsize < 16) - - cmp edi, 16 - jae .large - -; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT; - - lea ecx, [edi+ebx] - -; (v+rsize + nb)->head |= PINUSE_BIT; - - add edi, ebp - lea eax, [edi+ebx+4] - or ecx, 3 - mov [ebp+4], ecx - or dword [eax], 1 - lea eax, [ebp+8] - add esp, 8 - pop edi - pop esi - pop ebp - ret - -.large: - -; v->head = nb|PINUSE_BIT|CINUSE_BIT; -; r->head = rsize|PINUSE_BIT; - - mov edx, edi - or ebx, 3 - mov [ebp+4], ebx - or edx, 1 - mov [esi+4], edx - -; (r+rsize)->prev_foot = rsize; -; insert_large_chunk((tchunkptr)r, rsize); - - mov [esi+edi], edi - mov eax, edi - mov ecx, esi - call insert_chunk - - lea eax, [ebp+8] - add esp, 8 - pop edi - pop esi - pop ebp - ret - -.done: - add esp, 8 - pop edi - pop esi - pop ebp - xor eax, eax - ret - -init_malloc: - - stdcall kernel_alloc, 0x40000 - - mov [mst.top], eax - mov [mst.topsize], 128*1024 - mov dword [eax+4], (128*1024) or 1 - mov eax, mst.smallbins - -@@: - mov [eax+8], eax - mov [eax+12], eax - add eax, 16 - cmp eax, mst.smallbins+512 - jb @B - - mov ecx, mst.mutex - call mutex_init - - ret - diff --git a/kernel/branches/Kolibri-F/core/memory.inc b/kernel/branches/Kolibri-F/core/memory.inc deleted file mode 100644 index 86a6a9501..000000000 --- a/kernel/branches/Kolibri-F/core/memory.inc +++ /dev/null @@ -1,1364 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -align 4 -proc alloc_page - - pushfd - cli - push ebx - - cmp [pg_data.pages_free], 1 - jle .out_of_memory - - - mov ebx, [page_start] - mov ecx, [page_end] -.l1: - bsf eax, [ebx]; - jnz .found - add ebx, 4 - cmp ebx, ecx - jb .l1 - pop ebx - popfd - xor eax, eax - ret -.found: - - dec [pg_data.pages_free] - jz .out_of_memory - - btr [ebx], eax - mov [page_start], ebx - sub ebx, sys_pgmap - lea eax, [eax+ebx*8] - shl eax, 12 -; dec [pg_data.pages_free] - pop ebx - popfd - ret - -.out_of_memory: - mov [pg_data.pages_free], 1 - xor eax, eax - pop ebx - popfd - ret - -endp - -align 4 -proc alloc_pages stdcall, count:dword - pushfd - push ebx - push edi - cli - mov eax, [count] - add eax, 7 - shr eax, 3 - mov [count], eax - - mov ebx, [pg_data.pages_free] - sub ebx, 9 - js .out_of_memory - shr ebx, 3 - cmp eax, ebx - jg .out_of_memory - - mov ecx, [page_start] - mov ebx, [page_end] -.find: - mov edx, [count] - mov edi, ecx - .match: - cmp byte [ecx], 0xFF - jne .next - dec edx - jz .ok - inc ecx - cmp ecx, ebx - jb .match - .out_of_memory: - .fail: - xor eax, eax - pop edi - pop ebx - popfd - ret - .next: - inc ecx - cmp ecx, ebx - jb .find - pop edi - pop ebx - popfd - xor eax, eax - ret - .ok: - sub ecx, edi - inc ecx - push esi - mov esi, edi - xor eax, eax - rep stosb - sub esi, sys_pgmap - shl esi, 3+12 - mov eax, esi - mov ebx, [count] - shl ebx, 3 - sub [pg_data.pages_free], ebx - pop esi - pop edi - pop ebx - popfd - ret -endp - -align 4 -;proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword -map_page: - push ebx - mov eax, [esp+12] ; phis_addr - or eax, [esp+16] ; flags - and eax, [pte_valid_mask] - mov ebx, [esp+8] ; lin_addr - shr ebx, 12 - mov [page_tabs+ebx*4], eax - mov eax, [esp+8] ; lin_addr - pop ebx - invlpg [eax] - ret 12 - -align 4 -map_space: ;not implemented - - - ret - - -align 4 -proc free_page -;arg: eax page address - pushfd - cli - shr eax, 12 ;page index - bts dword [sys_pgmap], eax ;that's all! - cmc - adc [pg_data.pages_free], 0 - shr eax, 3 - and eax, not 3 ;dword offset from page_map - add eax, sys_pgmap - cmp [page_start], eax - ja @f - popfd - ret -@@: - mov [page_start], eax - popfd - ret -endp - -align 4 -proc map_io_mem stdcall, base:dword, size:dword, flags:dword - - push ebx - push edi - mov eax, [size] - add eax, [base] - add eax, 4095 - and eax, -4096 - mov ecx, [base] - and ecx, -4096 - sub eax, ecx - mov [size], eax - - stdcall alloc_kernel_space, eax - test eax, eax - jz .fail - push eax - - mov edi, 0x1000 - mov ebx, eax - mov ecx, [size] - mov edx, [base] - shr eax, 12 - shr ecx, 12 - or edx, [flags] - and edx, [pte_valid_mask] -@@: - mov [page_tabs+eax*4], edx - invlpg [ebx] - inc eax - add ebx, edi - add edx, edi - loop @B - - pop eax - mov edx, [base] - and edx, 4095 - add eax, edx -.fail: - pop edi - pop ebx - ret -endp - -; param -; eax= page base + page flags -; ebx= linear address -; ecx= count - -align 4 -commit_pages: - test ecx, ecx - jz .fail - - push edi - push eax - push ecx - mov ecx, pg_data.mutex - call mutex_lock - pop ecx - pop eax - - and eax, [pte_valid_mask ] - mov edi, ebx - shr edi, 12 - lea edi, [page_tabs+edi*4] -@@: - stosd - invlpg [ebx] - add eax, 0x1000 - add ebx, 0x1000 - loop @B - - pop edi - - mov ecx, pg_data.mutex - call mutex_unlock -.fail: - ret - - -; param -; eax= base -; ecx= count - -align 4 -release_pages: - - push ebp - push esi - push edi - push ebx - - mov esi, eax - mov edi, eax - - shr esi, 12 - lea esi, [page_tabs+esi*4] - - push ecx - mov ecx, pg_data.mutex - call mutex_lock - pop ecx - - mov ebp, [pg_data.pages_free] - mov ebx, [page_start] - mov edx, sys_pgmap -@@: - xor eax, eax - xchg eax, [esi] - invlpg [edi] - - test eax, 1 - jz .next - - shr eax, 12 - bts [edx], eax - cmc - adc ebp, 0 - shr eax, 3 - and eax, -4 - add eax, edx - cmp eax, ebx - jae .next - - mov ebx, eax -.next: - add edi, 0x1000 - add esi, 4 - loop @B - - mov [pg_data.pages_free], ebp - mov ecx, pg_data.mutex - call mutex_unlock - - pop ebx - pop edi - pop esi - pop ebp - ret - -; param -; eax= base -; ecx= count - -align 4 -unmap_pages: - - push edi - - mov edi, eax - mov edx, eax - - shr edi, 10 - add edi, page_tabs - - xor eax, eax -@@: - stosd - invlpg [edx] - add edx, 0x1000 - loop @b - - pop edi - ret - - -align 4 -proc map_page_table stdcall, lin_addr:dword, phis_addr:dword - push ebx - mov ebx, [lin_addr] - shr ebx, 22 - mov eax, [phis_addr] - and eax, not 0xFFF - or eax, PG_UWR - mov dword [master_tab+ebx*4], eax - mov eax, [lin_addr] - shr eax, 10 - add eax, page_tabs - invlpg [eax] - pop ebx - ret -endp - -uglobal -sb16_buffer_allocated db 0 -endg - -; Allocates [.size] bytes so that the target memory block -; is inside one 64K page for 24-bit DMA controller, -; that is, somewhere between 00xx0000h and 00xxFFFFh. -proc alloc_dma24 -; Implementation note. -; The only user of that function is SB16 driver, -; so just return a statically allocated buffer. -virtual at esp - dd ? ; return address -.size dd ? -end virtual - cmp [sb16_buffer_allocated], 0 - jnz .fail - inc [sb16_buffer_allocated] - mov eax, SB16Buffer - ret 4 -.fail: - xor eax, eax - ret 4 -endp - -; Allocates a physical page for master page table -; that duplicates first Mb of OS_BASE at address 0; -; used for starting APs and for shutting down, -; where it is important to execute code in trivial-mapped pages. -; Returns eax = allocated physical page. -proc create_trampoline_pgmap -; The only non-trivial moment: -; we need a linear address to fill information, -; but we don't need it outside of this function, -; so we're returning physical address. -; Therefore, allocate memory with kernel_alloc, -; this will allocate physical page and a linear address somewhere, -; and deallocate only linear address with free_kernel_space. - stdcall kernel_alloc, 0x1000 - mov edi, eax - mov esi, master_tab - mov ecx, 1024 - rep movsd - mov ecx, [master_tab+(OS_BASE shr 20)] - mov [eax], ecx - mov edi, eax - call get_pg_addr - push eax - stdcall free_kernel_space, edi - pop eax - ret -endp - -align 4 -proc new_mem_resize stdcall, new_size:dword - - push ebx - push esi - push edi - - mov edx, [current_slot] - mov ebx, [edx+APPDATA.process] - - cmp [ebx+PROC.heap_base], 0 - jne .exit - - mov edi, [new_size] - add edi, 4095 - and edi, not 4095 - mov [new_size], edi - - mov esi, [ebx+PROC.mem_used] - add esi, 4095 - and esi, not 4095 - - cmp edi, esi - ja .expand - je .exit - - mov ebx, edi - shr edi, 12 - shr esi, 12 - - mov ecx, pg_data.mutex - call mutex_lock -@@: - mov eax, [app_page_tabs+edi*4] - test eax, 1 - jz .next - - mov dword [app_page_tabs+edi*4], 0 - invlpg [ebx] - call free_page - -.next: - inc edi - add ebx, 0x1000 - cmp edi, esi - jb @B - - mov ecx, pg_data.mutex - call mutex_unlock - -.update_size: - mov edx, [current_slot] - mov ebx, [new_size] - mov edx, [edx+APPDATA.process] - mov [edx+PROC.mem_used], ebx -.exit: - pop edi - pop esi - pop ebx - xor eax, eax - ret - -.expand: - - mov ecx, pg_data.mutex - call mutex_lock - - xchg esi, edi - - push esi ;new size - push edi ;old size - - add edi, 0x3FFFFF - and edi, not(0x3FFFFF) - add esi, 0x3FFFFF - and esi, not(0x3FFFFF) - - cmp edi, esi - jae .grow - @@: - call alloc_page - test eax, eax - jz .exit_fail - - stdcall map_page_table, edi, eax - - push edi - shr edi, 10 - add edi, page_tabs - mov ecx, 1024 - xor eax, eax - cld - rep stosd - pop edi - - add edi, 0x00400000 - cmp edi, esi - jb @B -.grow: - pop edi ;old size - pop ecx ;new size - - shr edi, 10 - shr ecx, 10 - sub ecx, edi - shr ecx, 2 ;pages count - mov eax, 2 - - add edi, app_page_tabs - rep stosd - - mov ecx, pg_data.mutex - call mutex_unlock - - jmp .update_size - -.exit_fail: - mov ecx, pg_data.mutex - call mutex_unlock - - add esp, 8 - pop edi - pop esi - pop ebx - xor eax, eax - inc eax - ret -endp - - -; param -; eax= linear address -; -; retval -; eax= physical page address - -align 4 -get_pg_addr: - sub eax, OS_BASE - cmp eax, 0x400000 - jb @f - shr eax, 12 - mov eax, [page_tabs+(eax+(OS_BASE shr 12))*4] -@@: - and eax, 0xFFFFF000 - ret - - -align 4 -; Now it is called from core/sys32::exc_c (see stack frame there) -proc page_fault_handler - - .err_addr equ ebp-4 - - push ebx ;save exception number (#PF) - mov ebp, esp - mov ebx, cr2 - push ebx ;that is locals: .err_addr = cr2 - inc [pg_data.pages_faults] - - mov eax, [pf_err_code] - - cmp ebx, OS_BASE ;ebx == .err_addr - jb .user_space ;page in application memory - - cmp ebx, page_tabs - jb .kernel_space ;page in kernel memory - - cmp ebx, kernel_tabs - jb .alloc;.app_tabs ;page tables of application ; - ;simply create one -.core_tabs: -.fail: ;simply return to caller - mov esp, ebp - pop ebx ;restore exception number (#PF) - ret - -.user_space: - test eax, PG_READ - jnz .err_access ;Page presents - ;Access error ? - - shr ebx, 12 - mov ecx, ebx - shr ecx, 10 - mov edx, [master_tab+ecx*4] - test edx, PG_READ - jz .fail ;page table is not created - ;incorrect address in program - - mov eax, [page_tabs+ebx*4] - test eax, 2 - jz .fail ;address is not reserved for usage. Error - -.alloc: - call alloc_page - test eax, eax - jz .fail - - stdcall map_page, [.err_addr], eax, PG_UWR - - mov edi, [.err_addr] - and edi, 0xFFFFF000 - mov ecx, 1024 - xor eax, eax - ;cld ;caller is duty for this - rep stosd -.exit: ;iret with repeat fault instruction - add esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller - restore_ring3_context - iretd - -.err_access: -; access denied? this may be a result of copy-on-write protection for DLL -; check list of HDLLs - and ebx, not 0xFFF - mov eax, [current_process] - mov eax, [eax+PROC.dlls_list_ptr] - test eax, eax - jz .fail - mov esi, [eax+HDLL.fd] -.scan_hdll: - cmp esi, eax - jz .fail - mov edx, ebx - sub edx, [esi+HDLL.base] - cmp edx, [esi+HDLL.size] - jb .fault_in_hdll -.scan_hdll.next: - mov esi, [esi+HDLL.fd] - jmp .scan_hdll -.fault_in_hdll: -; allocate new page, map it as rw and copy data - call alloc_page - test eax, eax - jz .fail - stdcall map_page, ebx, eax, PG_UWR - mov edi, ebx - mov ecx, 1024 - sub ebx, [esi+HDLL.base] - mov esi, [esi+HDLL.parent] - mov esi, [esi+DLLDESCR.data] - add esi, ebx - rep movsd - jmp .exit - -.kernel_space: - test eax, PG_READ - jz .fail ;page does not present - - test eax, 12 ;U/S (+below) - jnz .fail ;application requested kernel memory - - ;test eax, 8 - ;jnz .fail ;the reserved bit is set in page tables. Added in P4/Xeon - - -;an attempt to write to a protected kernel page - - cmp ebx, tss._io_map_0 - jb .fail - - cmp ebx, tss._io_map_0+8192 - jae .fail - -; io permission map -; copy-on-write protection - - call alloc_page - test eax, eax - jz .fail - - push eax - stdcall map_page, [.err_addr], eax, dword PG_SWR - pop eax - mov edi, [.err_addr] - and edi, -4096 - lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0 - - mov ebx, esi - shr ebx, 12 - mov edx, [current_slot] - or eax, PG_SWR - mov [edx+APPDATA.io_map+ebx*4], eax - - add esi, [default_io_map] - mov ecx, 4096/4 - ;cld ;caller is duty for this - rep movsd - jmp .exit -endp - -; returns number of mapped bytes -proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\ - ofs:dword,buf_size:dword,req_access:dword - locals - count dd ? - process dd ? - endl - - mov [count], 0 - cmp [buf_size], 0 - jz .exit - - mov eax, [slot] - shl eax, 8 - mov eax, [SLOT_BASE+eax+APPDATA.process] - test eax, eax - jz .exit - - mov [process], eax - mov ebx, [ofs] - shr ebx, 22 - mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table - mov esi, [ipc_ptab] - and eax, 0xFFFFF000 - jz .exit - stdcall map_page, esi, eax, PG_SWR -@@: - mov edi, [lin_addr] - and edi, 0xFFFFF000 - mov ecx, [buf_size] - add ecx, 4095 - shr ecx, 12 - inc ecx ; ??????????? - - mov edx, [ofs] - shr edx, 12 - and edx, 0x3FF -.map: - stdcall safe_map_page, [slot], [req_access], [ofs] - jnc .exit - add [count], PAGE_SIZE - add [ofs], PAGE_SIZE - dec ecx - jz .exit - - add edi, PAGE_SIZE - inc edx - cmp edx, 1024 - jnz .map - - inc ebx - mov eax, [process] - mov eax, [eax+PROC.pdt_0+ebx*4] - and eax, 0xFFFFF000 - jz .exit - - stdcall map_page, esi, eax, PG_SWR - xor edx, edx - jmp .map -.exit: - mov eax, [count] - ret -endp - -proc map_memEx stdcall, lin_addr:dword,slot:dword,\ - ofs:dword,buf_size:dword,req_access:dword - locals - count dd ? - process dd ? - endl - - mov [count], 0 - cmp [buf_size], 0 - jz .exit - - mov eax, [slot] - shl eax, 8 - mov eax, [SLOT_BASE+eax+APPDATA.process] - test eax, eax - jz .exit - - mov [process], eax - mov ebx, [ofs] - shr ebx, 22 - mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table - mov esi, [proc_mem_tab] - and eax, 0xFFFFF000 - jz .exit - stdcall map_page, esi, eax, PG_SWR -@@: - mov edi, [lin_addr] - and edi, 0xFFFFF000 - mov ecx, [buf_size] - add ecx, 4095 - shr ecx, 12 - inc ecx ; ??????????? - - mov edx, [ofs] - shr edx, 12 - and edx, 0x3FF -.map: - stdcall safe_map_page, [slot], [req_access], [ofs] - jnc .exit - add [count], PAGE_SIZE - add [ofs], PAGE_SIZE - dec ecx - jz .exit - - add edi, PAGE_SIZE - inc edx - cmp edx, 1024 - jnz .map - - inc ebx - mov eax, [process] - mov eax, [eax+PROC.pdt_0+ebx*4] - and eax, 0xFFFFF000 - jz .exit - - stdcall map_page, esi, eax, PG_SWR - xor edx, edx - jmp .map -.exit: - mov eax, [count] - ret -endp - -; in: esi+edx*4 = pointer to page table entry -; in: [slot], [req_access], [ofs] on the stack -; in: edi = linear address to map -; out: CF cleared <=> failed -; destroys: only eax -proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword - mov eax, [esi+edx*4] - test al, PG_READ - jz .not_present - test al, PG_WRITE - jz .resolve_readonly -; normal case: writable page, just map with requested access -.map: - stdcall map_page, edi, eax, [req_access] - stc -.fail: - ret -.not_present: -; check for alloc-on-demand page - test al, 2 - jz .fail -; allocate new page, save it to source page table - push ecx - call alloc_page - pop ecx - test eax, eax - jz .fail - or al, PG_UWR - mov [esi+edx*4], eax - jmp .map -.resolve_readonly: -; readonly page, probably copy-on-write -; check: readonly request of readonly page is ok - test [req_access], PG_WRITE - jz .map -; find control structure for this page - pushf - cli - cld - push ebx ecx - mov eax, [slot] - shl eax, 8 - mov eax, [SLOT_BASE+eax+APPDATA.process] - mov eax, [eax+PROC.dlls_list_ptr] - test eax, eax - jz .no_hdll - mov ecx, [eax+HDLL.fd] -.scan_hdll: - cmp ecx, eax - jz .no_hdll - mov ebx, [ofs] - and ebx, not 0xFFF - sub ebx, [ecx+HDLL.base] - cmp ebx, [ecx+HDLL.size] - jb .hdll_found - mov ecx, [ecx+HDLL.fd] - jmp .scan_hdll -.no_hdll: - pop ecx ebx - popf - clc - ret -.hdll_found: -; allocate page, save it in page table, map it, copy contents from base - mov eax, [ecx+HDLL.parent] - add ebx, [eax+DLLDESCR.data] - call alloc_page - test eax, eax - jz .no_hdll - or al, PG_UWR - mov [esi+edx*4], eax - stdcall map_page, edi, eax, [req_access] - push esi edi - mov esi, ebx - mov ecx, 4096/4 - rep movsd - pop edi esi - pop ecx ebx - popf - stc - ret -endp - -syscall_IPC: -;input: -; ebx=1 - set ipc buffer area -; ecx=address of buffer -; edx=size of buffer -; eax=2 - send message -; ebx=PID -; ecx=address of message -; edx=size of message - - dec ebx - jnz @f - - mov eax, [current_slot] - pushf - cli - mov [eax+APPDATA.ipc_start], ecx ;set fields in extended information area - mov [eax+APPDATA.ipc_size], edx - - add edx, ecx - add edx, 4095 - and edx, not 4095 - -.touch: - mov eax, [ecx] - add ecx, 0x1000 - cmp ecx, edx - jb .touch - - popf - mov [esp+32], ebx ;ebx=0 - ret - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;2 -@@: - dec ebx - jnz @f - - stdcall sys_ipc_send, ecx, edx, esi - mov [esp+32], eax - ret -@@: - or eax, -1 - mov [esp+32], eax - ret - -proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword - locals - dst_slot dd ? - dst_offset dd ? - buf_size dd ? - used_buf dd ? - endl - - pushf - cli - - mov eax, [PID] - call pid_to_slot - test eax, eax - jz .no_pid - - mov [dst_slot], eax - shl eax, 8 - mov edi, [eax+SLOT_BASE+APPDATA.ipc_start] ;is ipc area defined? - test edi, edi - jz .no_ipc_area - - mov ebx, edi - and ebx, 0xFFF - mov [dst_offset], ebx - - mov esi, [eax+SLOT_BASE+APPDATA.ipc_size] - mov [buf_size], esi - - mov ecx, [ipc_tmp] - cmp esi, 0x40000-0x1000; size of [ipc_tmp] minus one page - jbe @f - push esi edi - add esi, 0x1000 - stdcall alloc_kernel_space, esi - mov ecx, eax - pop edi esi -@@: - mov [used_buf], ecx - stdcall map_mem_ipc, ecx, [dst_slot], \ - edi, esi, PG_SWR - - mov edi, [dst_offset] - add edi, [used_buf] - cmp dword [edi], 0 - jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now - - mov edx, dword [edi+4] - lea ebx, [edx+8] - add ebx, [msg_size] - cmp ebx, [buf_size] - ja .buffer_overflow ;esi<0 - not enough memory in buffer - - mov dword [edi+4], ebx - mov eax, [TASK_BASE] - mov eax, [eax+TASKDATA.pid] ;eax - our PID - add edi, edx - mov [edi], eax - mov ecx, [msg_size] - - mov [edi+4], ecx - add edi, 8 - mov esi, [msg_addr] - ; add esi, new_app_base - cld - rep movsb - - mov ebx, [ipc_tmp] - mov edx, ebx - shr ebx, 12 - xor eax, eax - mov [page_tabs+ebx*4], eax - invlpg [edx] - - mov ebx, [ipc_pdir] - mov edx, ebx - shr ebx, 12 - xor eax, eax - mov [page_tabs+ebx*4], eax - invlpg [edx] - - mov ebx, [ipc_ptab] - mov edx, ebx - shr ebx, 12 - xor eax, eax - mov [page_tabs+ebx*4], eax - invlpg [edx] - - mov eax, [dst_slot] - shl eax, BSF sizeof.APPDATA - or [eax+SLOT_BASE+APPDATA.occurred_events], EVENT_IPC - push 0 - jmp .ret -.no_pid: - popf - mov eax, 4 - ret -.no_ipc_area: - popf - xor eax, eax - inc eax - ret -.ipc_blocked: - push 2 - jmp .ret -.buffer_overflow: - push 3 -.ret: - mov eax, [used_buf] - cmp eax, [ipc_tmp] - je @f - stdcall free_kernel_space, eax -@@: - pop eax - popf - ret -endp - -align 4 -sysfn_meminfo: - cmp ecx, OS_BASE - jae .fail - - mov eax, [pg_data.pages_count] - mov [ecx], eax - shl eax, 12 - mov [esp+32], eax - mov eax, [pg_data.pages_free] - mov [ecx+4], eax - mov eax, [pg_data.pages_faults] - mov [ecx+8], eax - mov eax, [heap_size] - mov [ecx+12], eax - mov eax, [heap_free] - mov [ecx+16], eax - mov eax, [heap_blocks] - mov [ecx+20], eax - mov eax, [free_blocks] - mov [ecx+24], eax - ret -.fail: - or dword [esp+32], -1 - ret - -align 4 -syscall_some_intrenal_services: - cmp ebx, 4 - jbe sys_sheduler - cmp ebx, 11 - jb syscall_undefined - cmp ebx, 29 - ja syscall_undefined - xor eax, eax - jmp dword [syscall_some_intrenal_servicescall+ebx*4-11*4] -.11: - call init_heap - mov [esp+SYSCALL_STACK._eax], eax - ret -.12: - stdcall user_alloc, ecx - mov [esp+SYSCALL_STACK._eax], eax - ret -.13: - stdcall user_free, ecx - mov [esp+SYSCALL_STACK._eax], eax - ret -.14: - cmp ecx, OS_BASE - jae .fail - mov edi, ecx - call get_event_ex - mov [esp+SYSCALL_STACK._eax], eax - ret -.16: - test ecx, ecx - jz .fail - cmp ecx, OS_BASE - jae .fail - stdcall get_service, ecx - mov [esp+SYSCALL_STACK._eax], eax - ret -.17: - call srv_handlerEx ;ecx - mov [esp+SYSCALL_STACK._eax], eax - ret -.18: - mov eax, edx -.19: - cmp ecx, OS_BASE - jae .fail - stdcall load_library, ecx, eax - mov [esp+SYSCALL_STACK._eax], eax - ret -.20: - mov eax, edx - mov ebx, ecx - call user_realloc ;in: eax = pointer, ebx = new size - mov [esp+SYSCALL_STACK._eax], eax - ret -.21: - cmp ecx, OS_BASE - jae .fail - cmp edx, OS_BASE - jae .fail - stdcall load_pe_driver, ecx, edx - mov [esp+SYSCALL_STACK._eax], eax - ret -.22: - cmp ecx, OS_BASE - jae .fail - stdcall shmem_open, ecx, edx, esi - mov [esp+SYSCALL_STACK._edx], edx - mov [esp+SYSCALL_STACK._eax], eax - ret -.23: - cmp ecx, OS_BASE - jae .fail - stdcall shmem_close, ecx - mov [esp+SYSCALL_STACK._eax], eax - ret -.24: - mov eax, [current_slot] - xchg ecx, [eax+APPDATA.exc_handler] - xchg edx, [eax+APPDATA.except_mask] - mov [esp+SYSCALL_STACK._ebx], edx - mov [esp+SYSCALL_STACK._eax], ecx - ret -.25: - cmp ecx, 32 - jae .fail - mov eax, [current_slot] - btr [eax+APPDATA.except_mask], ecx - setc byte[esp+SYSCALL_STACK._eax] - jecxz @f - bts [eax+APPDATA.except_mask], ecx -@@: - ret -.26: - stdcall user_unmap, ecx, edx, esi - mov [esp+SYSCALL_STACK._eax], eax - ret -.27: - cmp ecx, OS_BASE - jae .fail - stdcall load_file_umode, ecx - mov [esp+SYSCALL_STACK._edx], edx - mov [esp+SYSCALL_STACK._eax], eax - ret -.28: - cmp ecx, OS_BASE - jae .fail - push ecx edx - stdcall kernel_alloc, maxPathLength - mov edi, eax - pop eax esi - push edi - call getFullPath - pop ebp - test eax, eax - jz @f - stdcall load_file_umode, ebp - mov [esp+SYSCALL_STACK._edx], edx -@@: - mov [esp+SYSCALL_STACK._eax], eax - stdcall kernel_free, ebp - ret - -.29: - stdcall user_ring, ecx - mov [esp+SYSCALL_STACK._eax], eax - ret - -.fail: - mov [esp+SYSCALL_STACK._eax], eax - ret - -align 4 -syscall_some_intrenal_servicescall: ; keep this table closer to main code - - dd syscall_some_intrenal_services.11 ; init_heap - dd syscall_some_intrenal_services.12 ; user_alloc - dd syscall_some_intrenal_services.13 ; user_free - dd syscall_some_intrenal_services.14 ; get_event_ex - dd syscall_some_intrenal_services.fail ; moved to syscall_some_intrenal_services.24 - dd syscall_some_intrenal_services.16 ; get_service - dd syscall_some_intrenal_services.17 ; call_service - dd syscall_some_intrenal_services.18 ; loadLibUnicode - dd syscall_some_intrenal_services.19 ; load_dll - dd syscall_some_intrenal_services.20 ; user_realloc - dd syscall_some_intrenal_services.21 ; load_driver - dd syscall_some_intrenal_services.22 ; shmem_open - dd syscall_some_intrenal_services.23 ; shmem_close - dd syscall_some_intrenal_services.24 ; set exception handler - dd syscall_some_intrenal_services.25 ; unmask exception - dd syscall_some_intrenal_services.26 ; user_unmap - dd syscall_some_intrenal_services.27 ; load_file_umode - dd syscall_some_intrenal_services.28 ; loadFileUnicode - dd syscall_some_intrenal_services.29 ; user_ring - -align 4 -proc load_pe_driver stdcall, file:dword, cmdline:dword - push esi - - stdcall load_PE, [file] - test eax, eax - jz .fail - - mov esi, eax - push [cmdline] - push DRV_ENTRY - call eax - pop ecx - pop ecx - test eax, eax - jz .fail - - mov [eax+SRV.entry], esi - pop esi - ret - -.fail: - xor eax, eax - pop esi - ret -endp - -align 4 -proc create_ring_buffer stdcall, size:dword, flags:dword - locals - buf_ptr dd ? - endl - - mov eax, [size] - test eax, eax - jz .fail - - add eax, eax - stdcall alloc_kernel_space, eax - test eax, eax - jz .fail - - push ebx - - mov [buf_ptr], eax - - mov ebx, [size] - shr ebx, 12 - push ebx - - stdcall alloc_pages, ebx - pop ecx - - test eax, eax - jz .mm_fail - - push edi - - or eax, [flags] - mov edi, [buf_ptr] - mov ebx, [buf_ptr] - mov edx, ecx - shl edx, 2 - shr edi, 10 -@@: - mov [page_tabs+edi], eax - mov [page_tabs+edi+edx], eax - invlpg [ebx] - invlpg [ebx+0x10000] - add eax, 0x1000 - add ebx, 0x1000 - add edi, 4 - dec ecx - jnz @B - - mov eax, [buf_ptr] - pop edi - pop ebx - ret -.mm_fail: - stdcall free_kernel_space, [buf_ptr] - xor eax, eax - pop ebx -.fail: - ret -endp - - -align 4 -proc print_mem - mov edi, BOOT.memmap_blocks - mov ecx, [edi-4] - test ecx, ecx - jz .done - -@@: - mov eax, [edi] - mov edx, [edi+4] - add eax, [edi+8] - adc edx, [edi+12] - - DEBUGF 1, "K : E820 %x%x - %x%x type %d\n", \ - [edi+4], [edi],\ - edx, eax, [edi+16] - add edi, 20 - dec ecx - jnz @b -.done: - ret -endp diff --git a/kernel/branches/Kolibri-F/core/mtrr.inc b/kernel/branches/Kolibri-F/core/mtrr.inc deleted file mode 100644 index 705550fe2..000000000 --- a/kernel/branches/Kolibri-F/core/mtrr.inc +++ /dev/null @@ -1,931 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; Initializes MTRRs. -proc init_mtrr - - cmp [BOOT.mtrr], byte 2 - je .exit - - bt [cpu_caps], CAPS_MTRR - jnc .exit - - call mtrr_reconfigure - stdcall set_mtrr, [LFBAddress], 0x1000000, MEM_WC - -.exit: - ret -endp - -; Helper procedure for mtrr_reconfigure and set_mtrr, -; called before changes in MTRRs. -; 1. disable and flush caches -; 2. clear PGE bit in cr4 -; 3. flush TLB -; 4. disable mtrr - -proc mtrr_begin_change - mov eax, cr0 - or eax, 0x60000000 ;disable caching - mov cr0, eax - wbinvd ;invalidate cache - - bt [cpu_caps], CAPS_PGE - jnc .cr3_flush - - mov eax, cr4 - btr eax, 7 ;clear cr4.PGE - mov cr4, eax ;flush TLB - jmp @F ;skip extra serialization - -.cr3_flush: - mov eax, cr3 - mov cr3, eax ;flush TLB -@@: - mov ecx, MSR_MTRR_DEF_TYPE - rdmsr - btr eax, 11 ;clear enable flag - wrmsr ;disable mtrr - ret -endp - -; Helper procedure for mtrr_reconfigure and set_mtrr, -; called after changes in MTRRs. -; 1. enable mtrr -; 2. flush all caches -; 3. flush TLB -; 4. restore cr4.PGE flag, if required - -proc mtrr_end_change - mov ecx, MSR_MTRR_DEF_TYPE - rdmsr - or ah, 8 ; enable variable-ranges MTRR - and al, 0xF0 ; default memtype = UC - wrmsr - - wbinvd ;again invalidate - mov eax, cr0 - and eax, not 0x60000000 - mov cr0, eax ; enable caching - - mov eax, cr3 - mov cr3, eax ;flush tlb - - bt [cpu_caps], CAPS_PGE - jnc @F - - mov eax, cr4 - bts eax, 7 ;set cr4.PGE flag - mov cr4, eax -@@: - ret -endp - -; Some limits to number of structures located in the stack. -MAX_USEFUL_MTRRS = 16 -MAX_RANGES = 16 - -; mtrr_reconfigure keeps a list of MEM_WB ranges. -; This structure describes one item in the list. -struct mtrr_range -next dd ? ; next item -start dq ? ; first byte -length dq ? ; length in bytes -ends - -uglobal -align 4 -num_variable_mtrrs dd 0 ; number of variable-range MTRRs -endg - -; Helper procedure for MTRR initialization. -; Takes MTRR configured by BIOS and tries to recongifure them -; in order to allow non-UC data at top of 4G memory. -; Example: if low part of physical memory is 3.5G = 0xE0000000 bytes wide, -; BIOS can configure two MTRRs so that the first MTRR describes [0, 4G) as WB -; and the second MTRR describes [3.5G, 4G) as UC; -; WB+UC=UC, so the resulting memory map would be as needed, -; but in this configuration our attempts to map LFB at (say) 0xE8000000 as WC -; would be ignored, WB+UC+WC is still UC. -; So we must keep top of 4G memory not covered by MTRRs, -; using three WB MTRRs [0,2G) + [2G,3G) + [3G,3.5G), -; this gives the same memory map, but allows to add further entries. -; See mtrrtest.asm for detailed input/output from real hardware+BIOS. -proc mtrr_reconfigure - push ebp ; we're called from init_LFB, and it feels hurt when ebp is destroyed -; 1. Prepare local variables. -; 1a. Create list of MAX_RANGES free (aka not yet allocated) ranges. - xor eax, eax - lea ecx, [eax+MAX_RANGES] -.init_ranges: - sub esp, sizeof.mtrr_range - 4 - push eax - mov eax, esp - dec ecx - jnz .init_ranges - mov eax, esp -; 1b. Fill individual local variables. - xor edx, edx - sub esp, MAX_USEFUL_MTRRS * 16 ; .mtrrs - push edx ; .mtrrs_end - push edx ; .num_used_mtrrs - push eax ; .first_free_range - push edx ; .first_range: no ranges yet - mov cl, [cpu_phys_addr_width] - or eax, -1 - shl eax, cl ; note: this uses cl&31 = cl-32, not the entire cl - push eax ; .phys_reserved_mask -virtual at esp -.phys_reserved_mask dd ? -.first_range dd ? -.first_free_range dd ? -.num_used_mtrrs dd ? -.mtrrs_end dd ? -.mtrrs rq MAX_USEFUL_MTRRS * 2 -.local_vars_size = $ - esp -end virtual - -; 2. Get the number of variable-range MTRRs from MTRRCAP register. -; Abort if zero. - mov ecx, 0xFE - rdmsr - test al, al - jz .abort - mov byte [num_variable_mtrrs], al -; 3. Validate MTRR_DEF_TYPE register. - mov ecx, 0x2FF - rdmsr -; If BIOS has not initialized variable-range MTRRs, fallback to step 7. - test ah, 8 - jz .fill_ranges_from_memory_map -; If the default memory type (not covered by MTRRs) is not UC, -; then probably BIOS did something strange, so it is better to exit immediately -; hoping for the best. - cmp al, MEM_UC - jnz .abort -; 4. Validate all variable-range MTRRs -; and copy configured MTRRs to the local array [.mtrrs]. -; 4a. Prepare for the loop over existing variable-range MTRRs. - mov ecx, 0x200 - lea edi, [.mtrrs] -.get_used_mtrrs_loop: -; 4b. For every MTRR, read PHYSBASEn and PHYSMASKn. -; In PHYSBASEn, clear upper bits and copy to ebp:ebx. - rdmsr - or edx, [.phys_reserved_mask] - xor edx, [.phys_reserved_mask] - mov ebp, edx - mov ebx, eax - inc ecx -; If PHYSMASKn is not active, ignore this MTRR. - rdmsr - inc ecx - test ah, 8 - jz .get_used_mtrrs_next -; 4c. For every active MTRR, check that number of local entries is not too large. - inc [.num_used_mtrrs] - cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS - ja .abort -; 4d. For every active MTRR, store PHYSBASEn with upper bits cleared. -; This contains the MTRR base and the memory type in low byte. - mov [edi], ebx - mov [edi+4], ebp -; 4e. For every active MTRR, check that the range is continuous: -; PHYSMASKn with upper bits set must be negated power of two, and -; low bits of PHYSBASEn must be zeroes: -; PHYSMASKn = 1...10...0, -; PHYSBASEn = x...x0...0, -; this defines a continuous range from x...x0...0 to x...x1...1, -; length = 10...0 = negated PHYSMASKn. -; Store length in the local array. - and eax, not 0xFFF - or edx, [.phys_reserved_mask] - mov dword [edi+8], 0 - mov dword [edi+12], 0 - sub [edi+8], eax - sbb [edi+12], edx -; (x and -x) is the maximum power of two that divides x. -; Condition for powers of two: (x and -x) equals x. - and eax, [edi+8] - and edx, [edi+12] - cmp eax, [edi+8] - jnz .abort - cmp edx, [edi+12] - jnz .abort - sub eax, 1 - sbb edx, 0 - and eax, not 0xFFF - and eax, ebx - jnz .abort - and edx, ebp - jnz .abort -; 4f. For every active MTRR, validate memory type: it must be either WB or UC. - add edi, 16 - cmp bl, MEM_UC - jz .get_used_mtrrs_next - cmp bl, MEM_WB - jnz .abort -.get_used_mtrrs_next: -; 4g. Repeat the loop at 4b-4f for all [num_variable_mtrrs] entries. - mov eax, [num_variable_mtrrs] - lea eax, [0x200+eax*2] - cmp ecx, eax - jb .get_used_mtrrs_loop -; 4h. If no active MTRRs were detected, fallback to step 7. - cmp [.num_used_mtrrs], 0 - jz .fill_ranges_from_memory_map - mov [.mtrrs_end], edi -; 5. Generate sorted list of ranges marked as WB. -; 5a. Prepare for the loop over configured MTRRs filled at step 4. - lea ecx, [.mtrrs] -.fill_wb_ranges: -; 5b. Ignore non-WB MTRRs. - mov ebx, [ecx] - cmp bl, MEM_WB - jnz .next_wb_range - mov ebp, [ecx+4] - and ebx, not 0xFFF ; clear memory type and reserved bits -; ebp:ebx = start of the range described by the current MTRR. -; 5c. Find the first existing range containing a point greater than ebp:ebx. - lea esi, [.first_range] -.find_range_wb: -; If there is no next range or start of the next range is greater than ebp:ebx, -; exit the loop to 5d. - mov edi, [esi] - test edi, edi - jz .found_place_wb - mov eax, ebx - mov edx, ebp - sub eax, dword [edi+mtrr_range.start] - sbb edx, dword [edi+mtrr_range.start+4] - jb .found_place_wb -; Otherwise, if end of the next range is greater than or equal to ebp:ebx, -; exit the loop to 5e. - mov esi, edi - sub eax, dword [edi+mtrr_range.length] - sbb edx, dword [edi+mtrr_range.length+4] - jb .expand_wb - or eax, edx - jnz .find_range_wb - jmp .expand_wb -.found_place_wb: -; 5d. ebp:ebx is not within any existing range. -; Insert a new range between esi and edi. -; (Later, during 5e, it can be merged with the following ranges.) - mov eax, [.first_free_range] - test eax, eax - jz .abort - mov [esi], eax - mov edx, [eax+mtrr_range.next] - mov [.first_free_range], edx - mov dword [eax+mtrr_range.start], ebx - mov dword [eax+mtrr_range.start+4], ebp -; Don't fill [eax+mtrr_range.next] and [eax+mtrr_range.length] yet, -; they will be calculated including merges at step 5e. - mov esi, edi - mov edi, eax -.expand_wb: -; 5e. The range at edi contains ebp:ebx, and esi points to the first range -; to be checked for merge: esi=edi if ebp:ebx was found in an existing range, -; esi is next after edi if a new range with ebp:ebx was created. -; Merge it with following ranges while start of the next range is not greater -; than the end of the new range. - add ebx, [ecx+8] - adc ebp, [ecx+12] -; ebp:ebx = end of the range described by the current MTRR. -.expand_wb_loop: -; If there is no next range or start of the next range is greater than ebp:ebx, -; exit the loop to 5g. - test esi, esi - jz .expand_wb_done - mov eax, ebx - mov edx, ebp - sub eax, dword [esi+mtrr_range.start] - sbb edx, dword [esi+mtrr_range.start+4] - jb .expand_wb_done -; Otherwise, if end of the next range is greater than or equal to ebp:ebx, -; exit the loop to 5f. - sub eax, dword [esi+mtrr_range.length] - sbb edx, dword [esi+mtrr_range.length+4] - jb .expand_wb_last -; Otherwise, the current range is completely within the new range. -; Free it and continue the loop. - mov edx, [esi+mtrr_range.next] - cmp esi, edi - jz @f - mov eax, [.first_free_range] - mov [esi+mtrr_range.next], eax - mov [.first_free_range], esi -@@: - mov esi, edx - jmp .expand_wb_loop -.expand_wb_last: -; 5f. Start of the new range is inside range described by esi, -; end of the new range is inside range described by edi. -; If esi is equal to edi, the new range is completely within -; an existing range, so proceed to the next range. - cmp esi, edi - jz .next_wb_range -; Otherwise, set end of interval at esi to end of interval at edi -; and free range described by edi. - mov ebx, dword [esi+mtrr_range.start] - mov ebp, dword [esi+mtrr_range.start+4] - add ebx, dword [esi+mtrr_range.length] - adc ebp, dword [esi+mtrr_range.length+4] - mov edx, [esi+mtrr_range.next] - mov eax, [.first_free_range] - mov [esi+mtrr_range.next], eax - mov [.first_free_range], esi - mov esi, edx -.expand_wb_done: -; 5g. We have found the next range (maybe 0) after merging and -; the new end of range (maybe ebp:ebx from the new range -; or end of another existing interval calculated at step 5f). -; Write them to range at edi. - mov [edi+mtrr_range.next], esi - sub ebx, dword [edi+mtrr_range.start] - sbb ebp, dword [edi+mtrr_range.start+4] - mov dword [edi+mtrr_range.length], ebx - mov dword [edi+mtrr_range.length+4], ebp -.next_wb_range: -; 5h. Continue the loop 5b-5g over all configured MTRRs. - add ecx, 16 - cmp ecx, [.mtrrs_end] - jb .fill_wb_ranges -; 6. Exclude all ranges marked as UC. -; 6a. Prepare for the loop over configured MTRRs filled at step 4. - lea ecx, [.mtrrs] -.fill_uc_ranges: -; 6b. Ignore non-UC MTRRs. - mov ebx, [ecx] - cmp bl, MEM_UC - jnz .next_uc_range - mov ebp, [ecx+4] - and ebx, not 0xFFF ; clear memory type and reserved bits -; ebp:ebx = start of the range described by the current MTRR. - lea esi, [.first_range] -; 6c. Find the first existing range containing a point greater than ebp:ebx. -.find_range_uc: -; If there is no next range, ignore this MTRR, -; exit the loop and continue to next MTRR. - mov edi, [esi] - test edi, edi - jz .next_uc_range -; If start of the next range is greater than or equal to ebp:ebx, -; exit the loop to 6e. - mov eax, dword [edi+mtrr_range.start] - mov edx, dword [edi+mtrr_range.start+4] - sub eax, ebx - sbb edx, ebp - jnb .truncate_uc -; Otherwise, continue the loop if end of the next range is less than ebp:ebx, -; exit the loop to 6d otherwise. - mov esi, edi - add eax, dword [edi+mtrr_range.length] - adc edx, dword [edi+mtrr_range.length+4] - jnb .find_range_uc -; 6d. ebp:ebx is inside (or at end of) an existing range. -; Split the range. (The second range, maybe containing completely within UC-range, -; maybe of zero length, can be removed at step 6e, if needed.) - mov edi, [.first_free_range] - test edi, edi - jz .abort - mov dword [edi+mtrr_range.start], ebx - mov dword [edi+mtrr_range.start+4], ebp - mov dword [edi+mtrr_range.length], eax - mov dword [edi+mtrr_range.length+4], edx - mov eax, [edi+mtrr_range.next] - mov [.first_free_range], eax - mov eax, [esi+mtrr_range.next] - mov [edi+mtrr_range.next], eax -; don't change [esi+mtrr_range.next] yet, it will be filled at step 6e - mov eax, ebx - mov edx, ebp - sub eax, dword [esi+mtrr_range.start] - sbb edx, dword [esi+mtrr_range.start+4] - mov dword [esi+mtrr_range.length], eax - mov dword [esi+mtrr_range.length+4], edx -.truncate_uc: -; 6e. edi is the first range after ebp:ebx, check it and next ranges -; for intersection with the new range, truncate heads. - add ebx, [ecx+8] - adc ebp, [ecx+12] -; ebp:ebx = end of the range described by the current MTRR. -.truncate_uc_loop: -; If start of the next range is greater than ebp:ebx, -; exit the loop to 6g. - mov eax, ebx - mov edx, ebp - sub eax, dword [edi+mtrr_range.start] - sbb edx, dword [edi+mtrr_range.start+4] - jb .truncate_uc_done -; Otherwise, if end of the next range is greater than ebp:ebx, -; exit the loop to 6f. - sub eax, dword [edi+mtrr_range.length] - sbb edx, dword [edi+mtrr_range.length+4] - jb .truncate_uc_last -; Otherwise, the current range is completely within the new range. -; Free it and continue the loop if there is a next range. -; If that was a last range, exit the loop to 6g. - mov edx, [edi+mtrr_range.next] - mov eax, [.first_free_range] - mov [.first_free_range], edi - mov [edi+mtrr_range.next], eax - mov edi, edx - test edi, edi - jnz .truncate_uc_loop - jmp .truncate_uc_done -.truncate_uc_last: -; 6f. The range at edi partially intersects with the UC-range described by MTRR. -; Truncate it from the head. - mov dword [edi+mtrr_range.start], ebx - mov dword [edi+mtrr_range.start+4], ebp - neg eax - adc edx, 0 - neg edx - mov dword [edi+mtrr_range.length], eax - mov dword [edi+mtrr_range.length+4], edx -.truncate_uc_done: -; 6g. We have found the next range (maybe 0) after intersection. -; Write it to [esi+mtrr_range.next]. - mov [esi+mtrr_range.next], edi -.next_uc_range: -; 6h. Continue the loop 6b-6g over all configured MTRRs. - add ecx, 16 - cmp ecx, [.mtrrs_end] - jb .fill_uc_ranges -; Sanity check: if there are no ranges after steps 5-6, -; fallback to step 7. Otherwise, go to 8. - cmp [.first_range], 0 - jnz .ranges_ok -.fill_ranges_from_memory_map: -; 7. BIOS has not configured variable-range MTRRs. -; Create one range from 0 to [MEM_AMOUNT]. - mov eax, [.first_free_range] - mov edx, [eax+mtrr_range.next] - mov [.first_free_range], edx - mov [.first_range], eax - xor edx, edx - mov [eax+mtrr_range.next], edx - mov dword [eax+mtrr_range.start], edx - mov dword [eax+mtrr_range.start+4], edx - mov ecx, [MEM_AMOUNT] - mov dword [eax+mtrr_range.length], ecx - mov dword [eax+mtrr_range.length+4], edx -.ranges_ok: -; 8. We have calculated list of WB-ranges. -; Now we should calculate a list of MTRRs so that -; * every MTRR describes a range with length = power of 2 and start that is aligned, -; * every MTRR can be WB or UC -; * (sum of all WB ranges) minus (sum of all UC ranges) equals the calculated list -; * top of 4G memory must not be covered by any ranges -; Example: range [0,0xBC000000) can be converted to -; [0,0x80000000)+[0x80000000,0xC0000000)-[0xBC000000,0xC0000000) -; WB +WB -UC -; but not to [0,0x100000000)-[0xC0000000,0x100000000)-[0xBC000000,0xC0000000). -; 8a. Check that list of ranges is [0,something) plus, optionally, [4G,something). -; This holds in practice (see mtrrtest.asm for real-life examples) -; and significantly simplifies the code: ranges are independent, start of range -; is almost always aligned (the only exception >4G upper memory can be easily covered), -; there is no need to consider adding holes before start of range, only -; append them to end of range. - xor eax, eax - mov edi, [.first_range] - cmp dword [edi+mtrr_range.start], eax - jnz .abort - cmp dword [edi+mtrr_range.start+4], eax - jnz .abort - cmp dword [edi+mtrr_range.length+4], eax - jnz .abort - mov edx, [edi+mtrr_range.next] - test edx, edx - jz @f - cmp dword [edx+mtrr_range.start], eax - jnz .abort - cmp dword [edx+mtrr_range.start+4], 1 - jnz .abort - cmp [edx+mtrr_range.next], eax - jnz .abort -@@: -; 8b. Initialize: no MTRRs filled. - mov [.num_used_mtrrs], eax - lea esi, [.mtrrs] -.range2mtrr_loop: -; 8c. If we are dealing with upper-memory range (after 4G) -; with length > start, create one WB MTRR with [start,2*start), -; reset start to 2*start and return to this step. -; Example: [4G,24G) -> [4G,8G) {returning} + [8G,16G) {returning} -; + [16G,24G) {advancing to ?}. - mov eax, dword [edi+mtrr_range.length+4] - test eax, eax - jz .less4G - mov edx, dword [edi+mtrr_range.start+4] - cmp eax, edx - jb .start_aligned - inc [.num_used_mtrrs] - cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS - ja .abort - mov dword [esi], MEM_WB - mov dword [esi+4], edx - mov dword [esi+8], 0 - mov dword [esi+12], edx - add esi, 16 - add dword [edi+mtrr_range.start+4], edx - sub dword [edi+mtrr_range.length+4], edx - jnz .range2mtrr_loop - cmp dword [edi+mtrr_range.length], 0 - jz .range2mtrr_next -.less4G: -; 8d. If we are dealing with low-memory range (before 4G) -; and appending a maximal-size hole would create a range covering top of 4G, -; create a maximal-size WB range and return to this step. -; Example: for [0,0xBC000000) the following steps would consider -; variants [0,0x80000000)+(another range to be splitted) and -; [0,0x100000000)-(another range to be splitted); we forbid the last variant, -; so the first variant must be used. - bsr ecx, dword [edi+mtrr_range.length] - xor edx, edx - inc edx - shl edx, cl - lea eax, [edx*2] - add eax, dword [edi+mtrr_range.start] - jnz .start_aligned - inc [.num_used_mtrrs] - cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS - ja .abort - mov eax, dword [edi+mtrr_range.start] - mov dword [esi], eax - or dword [esi], MEM_WB - mov dword [esi+4], 0 - mov dword [esi+8], edx - mov dword [esi+12], 0 - add esi, 16 - add dword [edi+mtrr_range.start], edx - sub dword [edi+mtrr_range.length], edx - jnz .less4G - jmp .range2mtrr_next -.start_aligned: -; Start is aligned for any allowed length, maximum-size hole is allowed. -; Select the best MTRR configuration for one range. -; length=...101101 -; Without hole at the end, we need one WB MTRR for every 1-bit in length: -; length=...100000 + ...001000 + ...000100 + ...000001 -; We can also append one hole at the end so that one 0-bit (selected by us) -; becomes 1 and all lower bits become 0 for WB-range: -; length=...110000 - (...00010 + ...00001) -; In this way, we need one WB MTRR for every 1-bit higher than the selected bit, -; one WB MTRR for the selected bit, one UC MTRR for every 0-bit between -; the selected bit and lowest 1-bit (they become 1-bits after negation) -; and one UC MTRR for lowest 1-bit. -; So we need to select 0-bit with the maximal difference -; (number of 0-bits) - (number of 1-bits) between selected and lowest 1-bit, -; this equals the gain from using a hole. If the difference is negative for -; all 0-bits, don't append hole. -; Note that lowest 1-bit is not included when counting, but selected 0-bit is. -; 8e. Find the optimal bit position for hole. -; eax = current difference, ebx = best difference, -; ecx = hole bit position, edx = current bit position. - xor eax, eax - xor ebx, ebx - xor ecx, ecx - bsf edx, dword [edi+mtrr_range.length] - jnz @f - bsf edx, dword [edi+mtrr_range.length+4] - add edx, 32 -@@: - push edx ; save position of lowest 1-bit for step 8f -.calc_stat: - inc edx - cmp edx, 64 - jae .stat_done - inc eax ; increment difference in hope for 1-bit -; Note: bt conveniently works with both .length and .length+4, -; depending on whether edx>=32. - bt dword [edi+mtrr_range.length], edx - jc .calc_stat - dec eax ; hope was wrong, decrement difference to correct 'inc' - dec eax ; and again, now getting the real difference - cmp eax, ebx - jle .calc_stat - mov ebx, eax - mov ecx, edx - jmp .calc_stat -.stat_done: -; 8f. If we decided to create a hole, flip all bits between lowest and selected. - pop edx ; restore position of lowest 1-bit saved at step 8e - test ecx, ecx - jz .fill_hi_init -@@: - inc edx - cmp edx, ecx - ja .fill_hi_init - btc dword [edi+mtrr_range.length], edx - jmp @b -.fill_hi_init: -; 8g. Create MTRR ranges corresponding to upper 32 bits. - sub ecx, 32 -.fill_hi_loop: - bsr edx, dword [edi+mtrr_range.length+4] - jz .fill_hi_done - inc [.num_used_mtrrs] - cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS - ja .abort - mov eax, dword [edi+mtrr_range.start] - mov [esi], eax - mov eax, dword [edi+mtrr_range.start+4] - mov [esi+4], eax - xor eax, eax - mov [esi+8], eax - bts eax, edx - mov [esi+12], eax - cmp edx, ecx - jl .fill_hi_uc - or dword [esi], MEM_WB - add dword [edi+mtrr_range.start+4], eax - jmp @f -.fill_hi_uc: - sub dword [esi+4], eax - sub dword [edi+mtrr_range.start+4], eax -@@: - add esi, 16 - sub dword [edi+mtrr_range.length], eax - jmp .fill_hi_loop -.fill_hi_done: -; 8h. Create MTRR ranges corresponding to lower 32 bits. - add ecx, 32 -.fill_lo_loop: - bsr edx, dword [edi+mtrr_range.length] - jz .range2mtrr_next - inc [.num_used_mtrrs] - cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS - ja .abort - mov eax, dword [edi+mtrr_range.start] - mov [esi], eax - mov eax, dword [edi+mtrr_range.start+4] - mov [esi+4], eax - xor eax, eax - mov [esi+12], eax - bts eax, edx - mov [esi+8], eax - cmp edx, ecx - jl .fill_lo_uc - or dword [esi], MEM_WB - add dword [edi+mtrr_range.start], eax - jmp @f -.fill_lo_uc: - sub dword [esi], eax - sub dword [edi+mtrr_range.start], eax -@@: - add esi, 16 - sub dword [edi+mtrr_range.length], eax - jmp .fill_lo_loop -.range2mtrr_next: -; 8i. Repeat the loop at 8c-8h for all ranges. - mov edi, [edi+mtrr_range.next] - test edi, edi - jnz .range2mtrr_loop -; 9. We have calculated needed MTRRs, now setup them in the CPU. -; 9a. Abort if number of MTRRs is too large. - mov eax, [num_variable_mtrrs] - cmp [.num_used_mtrrs], eax - ja .abort - -; 9b. Prepare for changes. - call mtrr_begin_change - -; 9c. Prepare for loop over MTRRs. - lea esi, [.mtrrs] - mov ecx, 0x200 -@@: -; 9d. For every MTRR, copy PHYSBASEn as is: step 8 has configured -; start value and type bits as needed. - mov eax, [esi] - mov edx, [esi+4] - wrmsr - inc ecx -; 9e. For every MTRR, calculate PHYSMASKn = -(length) or 0x800 -; with upper bits cleared, 0x800 = MTRR is valid. - xor eax, eax - xor edx, edx - sub eax, [esi+8] - sbb edx, [esi+12] - or eax, 0x800 - or edx, [.phys_reserved_mask] - xor edx, [.phys_reserved_mask] - wrmsr - inc ecx -; 9f. Continue steps 9d and 9e for all MTRRs calculated at step 8. - add esi, 16 - dec [.num_used_mtrrs] - jnz @b -; 9g. Zero other MTRRs. - xor eax, eax - xor edx, edx - mov ebx, [num_variable_mtrrs] - lea ebx, [0x200+ebx*2] -@@: - cmp ecx, ebx - jae @f - wrmsr - inc ecx - wrmsr - inc ecx - jmp @b -@@: - -; 9i. Check PAT support and reprogram PAT_MASR for write combining memory - bt [cpu_caps], CAPS_PAT - jnc @F - - mov ecx, MSR_CR_PAT - mov eax, PAT_VALUE ;UC UCM WC WB - mov edx, eax - wrmsr -@@: - -; 9j. Changes are done. - call mtrr_end_change - -.abort: - add esp, .local_vars_size + MAX_RANGES * sizeof.mtrr_range - pop ebp - ret -endp - -; Allocate&set one MTRR for given range. -; size must be power of 2 that divides base. -proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword -; find unused register - mov ecx, 0x201 -.scan: - mov eax, [num_variable_mtrrs] - lea eax, [0x200+eax*2] - cmp ecx, eax - jae .ret - rdmsr - dec ecx - test ah, 8 - jz .found - rdmsr - test edx, edx - jnz @f - and eax, not 0xFFF ; clear reserved bits - cmp eax, [base] - jz .ret -@@: - add ecx, 3 - jmp .scan -; no free registers, ignore the call -.ret: - ret -.found: -; found, write values - push ecx - call mtrr_begin_change - pop ecx - xor edx, edx - mov eax, [base] - or eax, [mem_type] - wrmsr - - mov al, [cpu_phys_addr_width] - xor edx, edx - bts edx, eax - xor eax, eax - sub eax, [size] - sbb edx, 0 - or eax, 0x800 - inc ecx - wrmsr - call mtrr_end_change - ret -endp - -; Helper procedure for mtrr_validate. -; Calculates memory type for given address according to variable-range MTRRs. -; Assumes that MTRRs are enabled. -; in: ebx = 32-bit physical address -; out: eax = memory type for ebx -proc mtrr_get_real_type -; 1. Initialize: we have not yet found any MTRRs covering ebx. - push 0 - mov ecx, 0x201 -.mtrr_loop: -; 2. For every MTRR, check whether it is valid; if not, continue to the next MTRR. - rdmsr - dec ecx - test ah, 8 - jz .next -; 3. For every valid MTRR, check whether (ebx and PHYSMASKn) == PHYSBASEn, -; excluding low 12 bits. - and eax, ebx - push eax - rdmsr - test edx, edx - pop edx - jnz .next - xor edx, eax - and edx, not 0xFFF - jnz .next -; 4. If so, set the bit corresponding to memory type defined by this MTRR. - and eax, 7 - bts [esp], eax -.next: -; 5. Continue loop at 2-4 for all variable-range MTRRs. - add ecx, 3 - mov eax, [num_variable_mtrrs] - lea eax, [0x200+eax*2] - cmp ecx, eax - jb .mtrr_loop -; 6. If no MTRRs cover address in ebx, use default MTRR type from MTRR_DEF_CAP. - pop edx - test edx, edx - jz .default -; 7. Find&clear 1-bit in edx. - bsf eax, edx - btr edx, eax -; 8. If there was only one 1-bit, then all MTRRs are consistent, return that bit. - test edx, edx - jz .nothing -; Otherwise, return MEM_UC (e.g. WB+UC is UC). - xor eax, eax -.nothing: - ret -.default: - mov ecx, 0x2FF - rdmsr - movzx eax, al - ret -endp - -; If MTRRs are configured improperly, this is not obvious to the user; -; everything works, but the performance can be horrible. -; Try to detect this and let the user know that the low performance -; is caused by some problem and is not a global property of the system. -; Let's hope he would report it to developers... -proc mtrr_validate -; 1. If MTRRs are not supported, they cannot be configured improperly. -; Note: VirtualBox claims MTRR support in cpuid, but emulates MTRRCAP=0, -; which is efficiently equivalent to absent MTRRs. -; So check [num_variable_mtrrs] instead of CAPS_MTRR in [cpu_caps]. - cmp [num_variable_mtrrs], 0 - jz .exit -; 2. If variable-range MTRRs are not configured, this is a problem. - mov ecx, 0x2FF - rdmsr - test ah, 8 - jz .fail -; 3. Get the memory type for address somewhere inside working memory. -; It must be write-back. - mov ebx, 0x27FFFF - call mtrr_get_real_type - cmp al, MEM_WB - jnz .fail -; 4. If we're using a mode with LFB, -; get the memory type for last pixel of the framebuffer. -; It must be write-combined. - test word [SCR_MODE], 0x4000 - jz .exit - mov eax, [_display.lfb_pitch] - mul [_display.height] - dec eax -; LFB is mapped to virtual address LFB_BASE, -; it uses global pages if supported by CPU. - mov ebx, [sys_proc+PROC.pdt_0+(LFB_BASE shr 20)] - test ebx, PDE_LARGE - jnz @f - mov ebx, [page_tabs+(LFB_BASE shr 10)] -@@: - and ebx, not 0xFFF - add ebx, eax - call mtrr_get_real_type - cmp al, MEM_WC - jz .exit -; 5. The check at step 4 fails on Bochs: -; Bochs BIOS configures MTRRs in a strange way not respecting [cpu_phys_addr_width], -; so mtrr_reconfigure avoids to touch anything. -; However, Bochs core ignores MTRRs (keeping them only for rdmsr/wrmsr), -; so we don't care about proper setting for Bochs. -; Use northbridge PCI id to detect Bochs: it emulates either i440fx or i430fx -; depending on configuration file. - mov eax, [pcidev_list.fd] - cmp eax, pcidev_list ; sanity check: fail if no PCI devices - jz .fail - cmp [eax+PCIDEV.vendor_device_id], 0x12378086 - jz .exit - cmp [eax+PCIDEV.vendor_device_id], 0x01228086 - jnz .fail -.exit: - ret -.fail: - mov ebx, mtrr_user_message - mov ebp, notifyapp - call fs_execute_from_sysdir_param - ret -endp diff --git a/kernel/branches/Kolibri-F/core/mtrrtest.asm b/kernel/branches/Kolibri-F/core/mtrrtest.asm deleted file mode 100644 index dede91186..000000000 --- a/kernel/branches/Kolibri-F/core/mtrrtest.asm +++ /dev/null @@ -1,213 +0,0 @@ -; Simple test for ring-3 debugging of mtrr.inc. -; Contains some inputs taken from real-life MTRRs and expected outputs. -format PE console -;include 'win32a.inc' -macro $Revision [args] -{ -} -macro ignore_empty_revision_keyword { - macro $Revi#sion$ \{\} -} -ignore_empty_revision_keyword -include '../proc32.inc' -include '../struct.inc' -entry start - -; one test has 8, another test has 10 -; this is the maximal value for storing/copying, real value is in MTRRCAP -MAX_VARIABLE_MTRR = 10 - -start: -; Copy test inputs, run init_mtrr, compare with test outputs. Repeat. - mov esi, test1_in_data - mov edi, mtrrdata - mov ecx, mtrrdata_size / 4 - rep movsd - call init_mtrr - mov esi, test1_out_data - mov edi, mtrrdata - mov ecx, mtrrdata_size / 4 - repz cmpsd - jnz .fail - mov esi, test2_in_data - mov edi, mtrrdata - mov ecx, mtrrdata_size / 4 - rep movsd - call init_mtrr - mov esi, test2_out_data - mov edi, mtrrdata - mov ecx, mtrrdata_size / 4 - repz cmpsd - jnz .fail - ret - -.fail: - int3 - jmp $ - -; Helper procedure for _rdmsr/_wrmsr, replacements of rdmsr/wrmsr. -; Returns pointer to memory containing the given MSR. -; in: ecx = MSR -; out: esi -> MSR data -proc get_msr_ptr - mov esi, mtrrcap - cmp ecx, 0xFE - jz .ok - mov esi, mtrr_def_type - cmp ecx, 0x2FF - jz .ok - lea esi, [ecx-0x200] - cmp esi, MAX_VARIABLE_MTRR*2 - jae .fail - lea esi, [mtrr+esi*8] -.ok: - ret -.fail: - int3 - ret -endp - -; Emulates rdmsr. -proc _rdmsr - push esi - call get_msr_ptr - mov eax, [esi] - mov edx, [esi+4] - pop esi - ret -endp - -; Emulates wrmsr. -proc _wrmsr - push esi - call get_msr_ptr - mov [esi], eax - mov [esi+4], edx - pop esi - ret -endp - -; Macro to substitute rdmsr/wrmsr with emulating code. -macro rdmsr -{ - call _rdmsr -} -macro wrmsr -{ - call _wrmsr -} -; Our emulation of rdmsr/wrmsr has nothing to do with real cache -; and system-wide settings, -; remove all attempts to wbinvd and disable/enable cache in cr0. -macro wbinvd -{ -} -macro mov a,b -{ -if ~(a eq cr0) & ~(b eq cr0) - mov a, b -end if -} -macro movi r,i -{ - push i - pop r -} - -include '../kglobals.inc' -CAPS_MTRR = 12 -MSR_MTRR_DEF_TYPE = 0x2FF -CAPS_PGE = 13 -CAPS_PAT = 16 -MSR_CR_PAT = 0x277 -PAT_VALUE = 0x00070106 ; (UC<<24)|(UCM<<16)|(WC<<8)|WB -MEM_WB = 6 ;write-back memory -MEM_WC = 1 ;write combined memory -MEM_UC = 0 ;uncached memory -include 'mtrr.inc' - -BOOT_VARS = 0 -BOOT.mtrr db 1 -align 4 -cpu_caps dd 1 shl CAPS_MTRR -LFBAddress dd 0xE0000000 -LFBSize dd 0x10000000 -MEM_AMOUNT dd 0 ; not used, needed for compilation - -align 4 -; Test 1: input -test1_in_data: -test1_phys_addr_width db 36 - rb 3 -test1_in_mtrrcap dq 0xD08 -test1_in_mtrr_def_type dq 0xC00 -test1_in_mtrrs: - dq 0x000000006, 0xF00000800 - dq 0x100000006, 0xFC0000800 - dq 0x0BC000000, 0xFFC000800 - dq 0x0C0000000, 0xFC0000800 - dq 0x138000000, 0xFF8000800 - dq 0, 0 - dq 0, 0 - dq 0, 0 - dq -1, -1 ; not used - dq -1, -1 ; not used -; Test 1: output -test1_out_data: - dd 36 ; phys_addr_width, readonly - dq 0xD08 ; MTRRCAP, readonly - dq 0xC00 ; MTRR_DEF_TYPE, should be the same - dq 0x000000006, 0xF80000800 - dq 0x080000006, 0xFC0000800 - dq 0x0BC000000, 0xFFC000800 - dq 0x100000006, 0xFC0000800 - dq 0x138000000, 0xFF8000800 - dq 0x0E0000001, 0xFFF000800 ; added for [LFBAddress] - dq 0, 0 - dq 0, 0 - dq -1, -1 ; not used - dq -1, -1 ; not used - -; Test 2: input -test2_in_data: -test2_phys_addr_width db 39 - rb 3 -test2_in_mtrrcap dq 0xD0A -test2_in_mtrr_def_type dq 0xC00 -test2_in_mtrrs: - dq 0x0000000006, 0x7F00000800 - dq 0x0100000006, 0x7FE0000800 - dq 0x00E0000000, 0x7FE0000800 - dq 0x00DC000000, 0x7FFC000800 - dq 0x00DBC00000, 0x7FFFC00800 - dq 0x011F800000, 0x7FFF800800 - dq 0x011F400000, 0x7FFFC00800 - dq 0x011F200000, 0x7FFFE00800 - dq 0, 0 - dq 0, 0 - -; Test 2: output -test2_out_data: - dd 39 ; phys_addr_width, readonly - dq 0xD0A ; MTRRCAP, readonly - dq 0xC00 ; MTRR_DEF_TYPE, should be the same - dq 0x0000000006, 0x7F80000800 - dq 0x0080000006, 0x7FC0000800 - dq 0x00C0000006, 0x7FE0000800 - dq 0x00DC000000, 0x7FFC000800 - dq 0x00DBC00000, 0x7FFFC00800 - dq 0x0100000006, 0x7FE0000800 - dq 0x011F800000, 0x7FFF800800 - dq 0x011F400000, 0x7FFFC00800 - dq 0x011F200000, 0x7FFFE00800 - dq 0x00E0000001, 0x7FFF000800 ; added for [LFBAddress] -IncludeIGlobals -align 4 -mtrrdata: -cpu_phys_addr_width db ? - rb 3 -mtrrcap dq ? -mtrr_def_type dq ? -mtrr rq MAX_VARIABLE_MTRR*2 -mtrrdata_size = $ - mtrrdata -IncludeUGlobals diff --git a/kernel/branches/Kolibri-F/core/peload.inc b/kernel/branches/Kolibri-F/core/peload.inc deleted file mode 100644 index 2991a8b83..000000000 --- a/kernel/branches/Kolibri-F/core/peload.inc +++ /dev/null @@ -1,295 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -include 'export.inc' - -align 4 - -proc load_PE stdcall, file_name:dword - locals - image dd ? - entry dd ? - base dd ? - endl - - stdcall load_file, [file_name] - test eax, eax - jz .fail - - mov [image], eax - - mov edx, [eax+STRIPPED_PE_HEADER.SizeOfImage] -; mov cl, [eax+STRIPPED_PE_HEADER.Subsystem] - cmp word [eax], STRIPPED_PE_SIGNATURE - jz @f - - mov edx, [eax+60] -; mov cl, [eax+5Ch+edx] - mov edx, [eax+80+edx] - -@@: - mov [entry], 0 -; cmp cl, 1 -; jnz .cleanup - stdcall kernel_alloc, edx - test eax, eax - jz .cleanup - - mov [base], eax - DEBUGF 1,'K : driver %s mapped to %x\n',[file_name],[base] - - push ebx ebp - mov ebx, [image] - mov ebp, eax - call map_PE - pop ebp ebx - - mov [entry], eax - test eax, eax - jnz .cleanup - - stdcall kernel_free, [base] -.cleanup: - stdcall kernel_free, [image] - mov eax, [entry] - ret -.fail: - xor eax, eax - ret -endp - -map_PE: ;ebp=base:dword, ebx=image:dword - push edi - push esi - sub esp, .locals_size -virtual at esp -.numsections dd ? -.import_names dd ? -.import_targets dd ? -.peheader dd ? -.bad_import dd ? -.import_idx dd ? -.import_descr dd ? -.relocs_rva dd ? -.relocs_size dd ? -.section_header_size dd ? -.AddressOfEntryPoint dd ? -.ImageBase dd ? -.locals_size = $ - esp -end virtual - cmp word [ebx], STRIPPED_PE_SIGNATURE - jz .stripped - - mov edx, ebx - add edx, [ebx+60] - movzx eax, word [edx+6] - mov [.numsections], eax - mov eax, [edx+40] - mov [.AddressOfEntryPoint], eax - mov eax, [edx+52] - mov [.ImageBase], eax - mov ecx, [edx+84] - mov [.section_header_size], 40 - mov eax, [edx+128] - mov [.import_descr], eax - mov eax, [edx+160] - mov [.relocs_rva], eax - mov eax, [edx+164] - mov [.relocs_size], eax - add edx, 256 - - jmp .common -.stripped: - mov eax, [ebx+STRIPPED_PE_HEADER.AddressOfEntryPoint] - mov [.AddressOfEntryPoint], eax - mov eax, [ebx+STRIPPED_PE_HEADER.ImageBase] - mov [.ImageBase], eax - movzx eax, [ebx+STRIPPED_PE_HEADER.NumberOfSections] - mov [.numsections], eax - movzx ecx, [ebx+STRIPPED_PE_HEADER.NumberOfRvaAndSizes] - xor eax, eax - mov [.relocs_rva], eax - mov [.relocs_size], eax - test ecx, ecx - jz @f - mov eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_IMPORT*8] -@@: - mov [.import_descr], eax - cmp ecx, SPE_DIRECTORY_BASERELOC - jbe @f - mov eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_BASERELOC*8] - mov [.relocs_rva], eax - mov eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_BASERELOC*8+4] - mov [.relocs_size], eax -@@: - mov [.section_header_size], 28 - lea edx, [ebx+ecx*8+sizeof.STRIPPED_PE_HEADER+8] - mov ecx, [ebx+STRIPPED_PE_HEADER.SizeOfHeaders] - -.common: - mov esi, ebx - mov edi, ebp - shr ecx, 2 - rep movsd - - cmp [.numsections], 0 - jz .nosections -.copy_sections: - mov eax, [edx+8] - test eax, eax - je .no_section_data - mov esi, ebx - mov edi, ebp - add esi, [edx+12] - mov ecx, eax - add edi, [edx+4] - - add ecx, 3 - shr ecx, 2 - rep movsd - -.no_section_data: - mov ecx, [edx] - cmp ecx, eax - jbe .no_section_fill - sub ecx, eax - add eax, [edx+4] - lea edi, [eax+ebp] - - xor eax, eax - rep stosb - -.no_section_fill: - add edx, [.section_header_size] - dec [.numsections] - jnz .copy_sections -.nosections: - cmp [.relocs_size], 0 - je .no_relocations - mov esi, ebp - mov ecx, ebp - sub esi, [.ImageBase] - add ecx, [.relocs_rva] -.relocs_block: - mov edi, [ecx] - add edi, ebp - mov ebx, [ecx+4] - add ecx, 8 - sub [.relocs_size], ebx - sub ebx, 8 - shr ebx, 1 - jz .relocs_next_block -.one_reloc: - movzx eax, word [ecx] - add ecx, 2 - mov edx, eax - shr eax, 12 - and edx, 4095 - cmp eax, 3 - jne @f - add [edx+edi], esi -@@: - dec ebx - jnz .one_reloc -.relocs_next_block: - cmp [.relocs_size], 0 - jg .relocs_block -.no_relocations: - cmp [.import_descr], 0 - je .no_imports - add [.import_descr], ebp - mov [.bad_import], 0 -.import_block: - mov ecx, [.import_descr] - cmp dword [ecx+4], 0 - jne @f - cmp dword [ecx+12], 0 - je .done_imports -@@: - mov edx, dword [ecx] - mov ecx, dword [ecx+16] - test edx, edx - jnz @f - mov edx, ecx -@@: - mov [.import_idx], 0 - add ecx, ebp - add edx, ebp - mov [.import_names], edx - mov [.import_targets], ecx -.import_func: - mov esi, [.import_idx] - mov edi, [.import_names] - mov eax, [edi+esi*4] - test eax, eax - je .next_import_block - js .next_import_block - lea edi, [ebp+eax] - mov eax, [.import_targets] - mov dword [eax+esi*4], 0 - lea esi, [edi+2] - movzx ebx, word [edi] - push 32 - mov ecx, [__exports+32] - mov eax, [ecx+OS_BASE+ebx*4] - add eax, OS_BASE - push eax - push esi - call strncmp - test eax, eax - jz .import_func_found - xor ebx, ebx -.import_func_candidate: - push 32 - mov ecx, [__exports+32] - mov eax, [ecx+OS_BASE+ebx*4] - add eax, OS_BASE - push eax - push esi - call strncmp - test eax, eax - je .import_func_found - inc ebx - cmp ebx, [__exports+24] - jb .import_func_candidate - - mov esi, msg_unresolved - call sys_msg_board_str - lea esi, [edi+2] - call sys_msg_board_str - mov esi, msg_CR - call sys_msg_board_str - - mov [.bad_import], 1 - jmp .next_import_func -.import_func_found: - mov esi, [__exports+28] - mov edx, [.import_idx] - mov ecx, [.import_targets] - mov eax, [esi+OS_BASE+ebx*4] - add eax, OS_BASE - mov [ecx+edx*4], eax -.next_import_func: - inc [.import_idx] - jmp .import_func -.next_import_block: - add [.import_descr], 20 - jmp .import_block -.done_imports: - xor eax, eax - cmp [.bad_import], 0 - jne @f -.no_imports: - mov eax, ebp - add eax, [.AddressOfEntryPoint] -@@: - add esp, .locals_size - pop esi - pop edi - ret diff --git a/kernel/branches/Kolibri-F/core/sched.inc b/kernel/branches/Kolibri-F/core/sched.inc deleted file mode 100644 index 2b1d94b05..000000000 --- a/kernel/branches/Kolibri-F/core/sched.inc +++ /dev/null @@ -1,434 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2021. All rights reserved. ;; -;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; -;; Distributed under terms of the GNU General Public License ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; IRQ0 HANDLER (TIMER INTERRUPT) ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - -align 32 -irq0: - pushad - mov ax, app_data - mov ds, ax - mov es, ax - inc [timer_ticks] - mov eax, [timer_ticks] - call playNote ; <<<--- Speaker driver - sub eax, [next_usage_update] - cmp eax, 100 - jb .nocounter - add [next_usage_update], 100 - call updatecputimes - .nocounter: - xor ecx, ecx ; send End Of Interrupt signal - call irq_eoi - - mov bl, SCHEDULE_ANY_PRIORITY - call find_next_task - jz .return ; if there is only one running process - call do_change_task - .return: - popad - iretd - -align 4 -change_task: - pushfd - cli - pushad - mov bl, SCHEDULE_ANY_PRIORITY - call find_next_task - jz .return ; the same task -> skip switch - - call do_change_task - .return: - popad - popfd - ret - -uglobal -align 4 -; far_jump: -; .offs dd ? -; .sel dw ? - context_counter dd 0 ;noname & halyavin - next_usage_update dd 0 - timer_ticks dd 0 -; prev_slot dd ? -; event_sched dd ? -endg - -align 4 -update_counters: - mov edi, [TASK_BASE] - rdtsc - sub eax, [edi+TASKDATA.counter_add] ; time stamp counter add - add [edi+TASKDATA.counter_sum], eax ; counter sum - ret -align 4 -updatecputimes: - mov ecx, [thread_count] - mov edi, TASK_DATA - .newupdate: - xor eax, eax - xchg eax, [edi+TASKDATA.counter_sum] - mov [edi+TASKDATA.cpu_usage], eax - add edi, 0x20 - loop .newupdate - ret - -;TODO: Надо бы убрать использование do_change_task из V86... -; и после этого перенести обработку TASKDATA.counter_add/sum в do_change_task - -align 4 -do_change_task: -;param: -; ebx = address of the APPDATA for incoming task (new) -;warning: -; [current_slot_idx] and [TASK_BASE] must be changed before (e.g. in find_next_task) -; [current_slot] is the outcoming (old), and set here to a new value (ebx) -;scratched: eax,ecx,esi - mov esi, ebx - xchg esi, [current_slot] -; set new stack after saving old - mov [esi+APPDATA.saved_esp], esp - mov esp, [ebx+APPDATA.saved_esp] -; set new thread io-map - mov eax, [ebx+APPDATA.io_map] - mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)], eax - mov eax, [ebx+APPDATA.io_map+4] - mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)], eax -; set new thread memory-map - mov eax, [ebx+APPDATA.process] - cmp eax, [current_process] - je @f - mov [current_process], eax - mov eax, [eax+PROC.pdt_0_phys] - mov cr3, eax -@@: -; set tss.esp0 - - mov eax, [ebx+APPDATA.saved_esp0] - mov [tss._esp0], eax - - mov edx, [ebx+APPDATA.tls_base] - - mov [tls_data_l+2], dx - shr edx, 16 - mov [tls_data_l+4], dl - mov [tls_data_l+7], dh - - mov dx, app_tls - mov fs, dx - -; set gs selector unconditionally - Mov ax, graph_data - Mov gs, ax - ; TS flag is not triggered by AVX* instructions, therefore - ; we have to xsave/xrstor SIMD registers each task change - bt [cpu_caps+(CAPS_OSXSAVE/32)*4], CAPS_OSXSAVE mod 32 - jnc .no_xsave - mov ecx, [esi+APPDATA.fpu_state] - mov eax, [xsave_eax] - mov edx, [xsave_edx] - xsave [ecx] - mov ecx, [current_slot_idx] - mov [fpu_owner], ecx - mov ecx, [current_slot] - mov ecx, [ecx+APPDATA.fpu_state] - xrstor [ecx] - .no_xsave: - ; set CR0.TS - cmp bh, byte[fpu_owner] ;bh == incoming task (new) - clts ;clear a task switch flag - je @f - mov eax, cr0 ;and set it again if the owner - or eax, CR0_TS ;of a fpu has changed - mov cr0, eax - @@: ; set context_counter (only for user pleasure ???) - inc [context_counter] ;noname & halyavin - ; set debug-registers, if it's necessary - test byte[ebx+APPDATA.dbg_state], 1 - jz @f - xor eax, eax - mov dr6, eax - lea esi, [ebx+APPDATA.dbg_regs] - cld - macro lodsReg [reg] { - lodsd - mov reg, eax - } lodsReg dr0, dr1, dr2, dr3, dr7 - purge lodsReg - @@: - ret -;end. - - - - -MAX_PRIORITY = 0 ; highest, used for kernel tasks -USER_PRIORITY = 1 ; default -IDLE_PRIORITY = 2 ; lowest, only IDLE thread goes here -NR_SCHED_QUEUES = 3 ; MUST equal IDLE_PRIORYTY + 1 - -uglobal -; [scheduler_current + i*4] = zero if there are no threads with priority i, -; pointer to APPDATA of the current thread with priority i otherwise. -align 4 -scheduler_current rd NR_SCHED_QUEUES -endg - -; Add the given thread to the given priority list for the scheduler. -; in: edx -> APPDATA, ecx = priority -proc scheduler_add_thread -; 1. Acquire the lock. - spin_lock_irqsave SchedulerLock -; 2. Store the priority in APPDATA structure. - mov [edx+APPDATA.priority], ecx -; 3. There are two different cases: the given list is empty or not empty. -; In first case, go to 6. Otherwise, advance to 4. - mov eax, [scheduler_current+ecx*4] - test eax, eax - jz .new_list -; 4. Insert the new item immediately before the current item. - mov ecx, [eax+APPDATA.in_schedule.prev] - mov [edx+APPDATA.in_schedule.next], eax - mov [edx+APPDATA.in_schedule.prev], ecx - mov [eax+APPDATA.in_schedule.prev], edx - mov [ecx+APPDATA.in_schedule.next], edx -; 5. Release the lock and return. - spin_unlock_irqrestore SchedulerLock - ret -.new_list: -; 6. Initialize the list with one item and make it the current item. - mov [edx+APPDATA.in_schedule.next], edx - mov [edx+APPDATA.in_schedule.prev], edx - mov [scheduler_current+ecx*4], edx -; 7. Release the lock and return. - spin_unlock_irqrestore SchedulerLock - ret -endp - -; Remove the given thread from the corresponding priority list for the scheduler. -; in: edx -> APPDATA -proc scheduler_remove_thread -; 1. Acquire the lock. - spin_lock_irqsave SchedulerLock -; 2. Remove the item from the corresponding list. - mov eax, [edx+APPDATA.in_schedule.next] - mov ecx, [edx+APPDATA.in_schedule.prev] - mov [eax+APPDATA.in_schedule.prev], ecx - mov [ecx+APPDATA.in_schedule.next], eax -; 3. If the given thread is the current item in the list, -; advance the current item. -; 3a. Check whether the given thread is the current item; -; if no, skip the rest of this step. - mov ecx, [edx+APPDATA.priority] - cmp [scheduler_current+ecx*4], edx - jnz .return -; 3b. Set the current item to eax; step 2 has set eax = next item. - mov [scheduler_current+ecx*4], eax -; 3c. If there were only one item in the list, zero the current item. - cmp eax, edx - jnz .return - mov [scheduler_current+ecx*4], 0 -.return: -; 4. Release the lock and return. - spin_unlock_irqrestore SchedulerLock - ret -endp - -SCHEDULE_ANY_PRIORITY = 0 -SCHEDULE_HIGHER_PRIORITY = 1 -;info: -; Find next task to execute -;in: -; bl = SCHEDULE_ANY_PRIORITY: -; consider threads with any priority -; bl = SCHEDULE_HIGHER_PRIORITY: -; consider only threads with strictly higher priority than the current one, -; keep running the current thread if other ready threads have the same or lower priority -;retval: -; ebx = address of the APPDATA for the selected task (slot-base) -; edi = address of the TASKDATA for the selected task -; ZF = 1 if the task is the same -;warning: -; [current_slot_idx] = bh , [TASK_BASE] = edi -- as result -; [current_slot] is not set to new value (ebx)!!! -;scratched: eax,ecx -proc find_next_task - call update_counters - spin_lock_irqsave SchedulerLock - push NR_SCHED_QUEUES -; If bl == SCHEDULE_ANY_PRIORITY = 0, loop over all NR_SCHED lists. -; Otherwise, loop over first [APPDATA.priority] lists. - test bl, bl - jz .start - mov ebx, [current_slot] - mov edi, [TASK_BASE] - mov eax, [ebx+APPDATA.priority] - test eax, eax - jz .unlock_found - mov [esp], eax -.start: - xor ecx, ecx -.priority_loop: - mov ebx, [scheduler_current+ecx*4] - test ebx, ebx - jz .priority_next -.task_loop: - mov ebx, [ebx+APPDATA.in_schedule.next] - mov edi, ebx - shr edi, 3 - add edi, TASK_TABLE - (SLOT_BASE shr 3) - mov al, [edi+TASKDATA.state] - test al, al - jz .task_found ; state == 0 - cmp al, 5 - jne .task_next ; state == 1,2,3,4,9 - ; state == 5 - pushad ; more freedom for [APPDATA.wait_test] - call [ebx+APPDATA.wait_test] - mov [esp+28], eax - popad - or eax, eax - jnz @f - ; testing for timeout - mov eax, [timer_ticks] - sub eax, [ebx+APPDATA.wait_begin] - cmp eax, [ebx+APPDATA.wait_timeout] - jb .task_next - xor eax, eax -@@: - mov [ebx+APPDATA.wait_param], eax ; retval for wait - mov [edi+TASKDATA.state], TSTATE_RUNNING -.task_found: - mov [scheduler_current+ecx*4], ebx -; If we have selected a thread with higher priority -; AND rescheduling is due to IRQ, -; turn the current scheduler list one entry back, -; so the current thread will be next after high-priority thread is done. - mov ecx, [esp] - cmp ecx, NR_SCHED_QUEUES - jz .unlock_found - mov eax, [current_slot] - mov eax, [eax+APPDATA.in_schedule.prev] - mov [scheduler_current+ecx*4], eax -.unlock_found: - pop ecx - spin_unlock_irqrestore SchedulerLock -.found: - ; the line below assumes APPDATA is 256 bytes long and SLOT_BASE is - ; aligned on 0x10000 - mov byte [current_slot_idx], bh - mov [TASK_BASE], edi - rdtsc ;call _rdtsc - mov [edi+TASKDATA.counter_add], eax; for next using update_counters - cmp ebx, [current_slot] - ret -.task_next: - cmp ebx, [scheduler_current+ecx*4] - jnz .task_loop -.priority_next: - inc ecx - cmp ecx, [esp] - jb .priority_loop - mov ebx, [current_slot] - mov edi, [TASK_BASE] - jmp .unlock_found -endp - -if 0 - -struc TIMER -{ - .next dd ? - .exp_time dd ? - .func dd ? - .arg dd ? -} - - -uglobal -rdy_head rd 16 -endg - -align 4 -pick_task: - - xor eax, eax - .pick: - mov ebx, [rdy_head+eax*4] - test ebx, ebx - jz .next - - mov [next_task], ebx - test [ebx+flags.billable] - jz @F - mov [bill_task], ebx - @@: - ret - .next: - inc eax - jmp .pick - -; param -; eax= task -; -; retval -; eax= task -; ebx= queue -; ecx= front if 1 or back if 0 -align 4 -shed: - cmp [eax+.tics_left], 0;signed compare - mov ebx, [eax+.priority] - setg ecx - jg @F - - mov edx, [eax+.tics_quantum] - mov [eax+.ticks_left], edx - cmp ebx, (IDLE_PRIORITY-1) - je @F - inc ebx - @@: - ret - -; param -; eax= task -align 4 -enqueue: - call shed;eax - cmp [rdy_head+ebx*4], 0 - jnz @F - - mov [rdy_head+ebx*4], eax - mov [rdy_tail+ebx*4], eax - mov [eax+.next_ready], 0 - jmp .pick - @@: - test ecx, ecx - jz .back - - mov ecx, [rdy_head+ebx*4] - mov [eax+.next_ready], ecx - mov [rdy_head+ebx*4], eax - jmp .pick - .back: - mov ecx, [rdy_tail+ebx*4] - mov [ecx+.next_ready], eax - mov [rdy_tail+ebx*4], eax - mov [eax+.next_ready], 0 - .pick: - call pick_proc;select next task - ret - -end if diff --git a/kernel/branches/Kolibri-F/core/slab.inc b/kernel/branches/Kolibri-F/core/slab.inc deleted file mode 100644 index 2b70509af..000000000 --- a/kernel/branches/Kolibri-F/core/slab.inc +++ /dev/null @@ -1,125 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; Memory management for slab structures. -; The allocator meets special requirements: -; * memory blocks are properly aligned -; * memory blocks do not cross page boundary -; The allocator manages fixed-size blocks. -; Thus, the specific allocator works as follows: -; allocate one page, split into blocks, maintain the single-linked -; list of all free blocks in each page. - -; Note: size must be a multiple of required alignment. - -; Data for one pool: dd pointer to the first page, MUTEX lock. - -; Allocator for fixed-size blocks: allocate a block. -; [ebx-4] = pointer to the first page, ebx = pointer to MUTEX structure. -proc slab_alloc - push edi ; save used register to be stdcall -virtual at esp - dd ? ; saved edi - dd ? ; return address -.size dd ? -end virtual -; 1. Take the lock. - mov ecx, ebx - call mutex_lock -; 2. Find the first allocated page with a free block, if any. -; 2a. Initialize for the loop. - mov edx, ebx -.pageloop: -; 2b. Get the next page, keeping the current in eax. - mov eax, edx - mov edx, [edx-4] -; 2c. If there is no next page, we're out of luck; go to 4. - test edx, edx - jz .newpage - add edx, 0x1000 -@@: -; 2d. Get the pointer to the first free block on this page. -; If there is no free block, continue to 2b. - mov eax, [edx-8] - test eax, eax - jz .pageloop -; 2e. Get the pointer to the next free block. - mov ecx, [eax] -; 2f. Update the pointer to the first free block from eax to ecx. -; Normally [edx-8] still contains eax, if so, atomically set it to ecx -; and proceed to 3. -; However, the price of simplicity of slab_free (in particular, it doesn't take -; the lock) is that [edx-8] could (rarely) be changed while we processed steps -; 2d+2e. If so, return to 2d and retry. - lock cmpxchg [edx-8], ecx - jnz @b -.return: -; 3. Release the lock taken in step 1 and return. - push eax - mov ecx, ebx - call mutex_unlock - pop eax - pop edi ; restore used register to be stdcall - ret 4 -.newpage: -; 4. Allocate a new page. - push eax - stdcall kernel_alloc, 0x1000 - pop edx -; If failed, say something to the debug board and return zero. - test eax, eax - jz .nomemory -; 5. Add the new page to the tail of list of allocated pages. - mov [edx-4], eax -; 6. Initialize two service dwords in the end of page: -; first free block is (start of page) + (block size) -; (we will return first block at (start of page), so consider it allocated), -; no next page. - mov edx, eax - lea edi, [eax+0x1000-8] - add edx, [.size] - mov [edi], edx - and dword [edi+4], 0 -; 7. All blocks starting from edx are free; join them in a single-linked list. -@@: - mov ecx, edx - add edx, [.size] - mov [ecx], edx - cmp edx, edi - jbe @b - sub ecx, [.size] - and dword [ecx], 0 -; 8. Return (start of page). - jmp .return -.nomemory: - dbgstr 'no memory for slab allocation' - xor eax, eax - jmp .return -endp - -; Allocator for fixed-size blocks: free a block. -proc slab_free - push ecx edx -virtual at esp - rd 2 ; saved registers - dd ? ; return address -.block dd ? -end virtual -; Insert the given block to the head of free blocks in this page. - mov ecx, [.block] - mov edx, ecx - or edx, 0xFFF -@@: - mov eax, [edx+1-8] - mov [ecx], eax - lock cmpxchg [edx+1-8], ecx - jnz @b - pop edx ecx - ret 4 -endp diff --git a/kernel/branches/Kolibri-F/core/string.inc b/kernel/branches/Kolibri-F/core/string.inc deleted file mode 100644 index 3c6694445..000000000 --- a/kernel/branches/Kolibri-F/core/string.inc +++ /dev/null @@ -1,189 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; Author: Kees J. Bot 1 Jan 1994 ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; size_t strncat(char *s1, const char *s2, size_t n) -; Append string s2 to s1. - -; char *strchr(const char *s, int c) - - -; int strncmp(const char *s1, const char *s2, size_t n) -; Compare two strings. - -; char *strncpy(char *s1, const char *s2, size_t n) -; Copy string s2 to s1. - -; size_t strnlen(const char *s, size_t n) -; Return the length of a string. - -; proc strrchr stdcall, s:dword, c:dword -; Look for the last occurrence a character in a string. - -proc strncat stdcall, s1:dword, s2:dword, n:dword - push esi - push edi - mov edi, [s1] ; String s1 - mov edx, [n] ; Maximum length - - mov ecx, -1 - xor al, al ; Null byte - cld - repne scasb ; Look for the zero byte in s1 - dec edi ; Back one up (and clear 'Z' flag) - push edi ; Save end of s1 - mov edi, [s2] ; edi = string s2 - mov ecx, edx ; Maximum count - repne scasb ; Look for the end of s2 - jne @F - inc ecx ; Exclude null byte -@@: - sub edx, ecx ; Number of bytes in s2 - mov ecx, edx - mov esi, [s2] ; esi = string s2 - pop edi ; edi = end of string s1 - rep movsb ; Copy bytes - stosb ; Add a terminating null - mov eax, [s1] ; Return s1 - pop edi - pop esi - ret -endp - -align 4 -proc strncmp stdcall, s1:dword, s2:dword, n:dword - - push esi - push edi - mov ecx, [n] - test ecx, ecx ; Max length is zero? - je .done - - mov esi, [s1] ; esi = string s1 - mov edi, [s2] ; edi = string s2 - cld -.compare: - cmpsb ; Compare two bytes - jne .done - cmp byte [esi-1], 0 ; End of string? - je .done - dec ecx ; Length limit reached? - jne .compare -.done: - seta al ; al = (s1 > s2) - setb ah ; ah = (s1 < s2) - sub al, ah - movsx eax, al ; eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1 - pop edi - pop esi - ret -endp - -align 4 -proc strncpy stdcall, s1:dword, s2:dword, n:dword - - push esi - push edi - - mov ecx, [n] ; Maximum length - mov edi, [s2] ; edi = string s2 - xor al, al ; Look for a zero byte - mov edx, ecx ; Save maximum count - cld - repne scasb ; Look for end of s2 - sub edx, ecx ; Number of bytes in s2 including null - xchg ecx, edx - mov esi, [s2] ; esi = string s2 - mov edi, [s1] ; edi = string s1 - rep movsb ; Copy bytes - - mov ecx, edx ; Number of bytes not copied - rep stosb ; strncpy always copies n bytes by null padding - mov eax, [s1] ; Return s1 - pop edi - pop esi - ret -endp - -align 4 -proc strnlen stdcall, s:dword, n:dword - - push edi - mov ecx, [n] - mov edi, [s] ; edi = string - xor al, al ; Look for a zero byte - mov edx, ecx ; Save maximum count - cmp cl, 1 ; 'Z' bit must be clear if ecx = 0 - cld - repne scasb ; Look for zero - jne @F - inc ecx ; Don't count zero byte -@@: - mov eax, edx - sub eax, ecx ; Compute bytes scanned - pop edi - ret -endp - -align 4 -proc strchr stdcall, s:dword, c:dword - push edi - cld - mov edi, [s] ; edi = string - mov edx, 16 ; Look at small chunks of the string -.next: - shl edx, 1 ; Chunks become bigger each time - mov ecx, edx - xor al, al ; Look for the zero at the end - repne scasb - pushf ; Remember the flags - sub ecx, edx - neg ecx ; Some or all of the chunk - sub edi, ecx ; Step back - mov eax, [c] ; The character to look for - repne scasb - je .found - popf ; Did we find the end of string earlier? - jne .next ; No, try again - xor eax, eax ; Return NULL - pop edi - ret -.found: - pop eax ; Get rid of those flags - lea eax, [edi-1] ; Address of byte found - pop edi - ret - -endp - - -proc strrchr stdcall, s:dword, c:dword - push edi - mov edi, [s] ; edi = string - mov ecx, -1 - xor al, al - cld - repne scasb ; Look for the end of the string - not ecx ; -1 - ecx = Length of the string + null - dec edi ; Put edi back on the zero byte - mov eax, [c] ; The character to look for - std ; Downwards search - repne scasb - cld ; Direction bit back to default - jne .fail - lea eax, [edi+1] ; Found it - pop edi - ret -.fail: - xor eax, eax ; Not there - pop edi - ret -endp - - diff --git a/kernel/branches/Kolibri-F/core/sync.inc b/kernel/branches/Kolibri-F/core/sync.inc deleted file mode 100644 index a6c41f039..000000000 --- a/kernel/branches/Kolibri-F/core/sync.inc +++ /dev/null @@ -1,355 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;; Synhronization for MenuetOS. ;; -;; Author: Halyavin Andrey, halyavin@land.ru ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - - -RWSEM_WAITING_FOR_WRITE = 0 -RWSEM_WAITING_FOR_READ = 1 - -;void __fastcall mutex_init(struct mutex *lock) - -align 4 -mutex_init: - mov [ecx+MUTEX.wait_list.next], ecx - mov [ecx+MUTEX.wait_list.prev], ecx - mov [ecx+MUTEX.count], 1 - ret - -;void __fastcall mutex_lock(struct mutex *lock) - -align 4 -mutex_lock: - - dec [ecx+MUTEX.count] - jns .done - - pushfd - cli - - sub esp, sizeof.MUTEX_WAITER - - list_add_tail esp, ecx ;esp= new waiter, ecx= list head - - mov edx, [TASK_BASE] - mov [esp+MUTEX_WAITER.task], edx - -.forever: - - mov eax, -1 - xchg eax, [ecx+MUTEX.count] - dec eax - jz @F - - mov [edx+TASKDATA.state], TSTATE_RUN_SUSPENDED - call change_task - jmp .forever -@@: - mov eax, ecx - list_del esp - - cmp [eax+MUTEX.wait_list.next], eax - jne @F - - mov [eax+MUTEX.count], 0 -@@: - add esp, sizeof.MUTEX_WAITER - - popfd -.done: - ret - -;void __fastcall mutex_unlock(struct mutex *lock) - -align 4 -mutex_unlock: - - pushfd - cli - - mov eax, [ecx+MUTEX.wait_list.next] - cmp eax, ecx - mov [ecx+MUTEX.count], 1 - je @F - - mov eax, [eax+MUTEX_WAITER.task] - mov [eax+TASKDATA.state], TSTATE_RUNNING -@@: - popfd - ret - - -;void __fastcall init_rwsem(struct rw_semaphore *sem) - -align 4 -init_rwsem: - mov [ecx+RWSEM.wait_list.next], ecx - mov [ecx+RWSEM.wait_list.prev], ecx - mov [ecx+RWSEM.count], 0 - ret - -;void __fastcall down_read(struct rw_semaphore *sem) - -align 4 -down_read: - pushfd - cli - - mov eax, [ecx+RWSEM.count] - test eax, eax - js @F - - cmp ecx, [ecx+RWSEM.wait_list.next] - je .ok -@@: - sub esp, sizeof.MUTEX_WAITER - - mov eax, [TASK_BASE] - mov [esp+MUTEX_WAITER.task], eax - mov [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_READ - mov [eax+TASKDATA.state], TSTATE_RUN_SUSPENDED - - list_add_tail esp, ecx ;esp= new waiter, ecx= list head - - call change_task - - add esp, sizeof.MUTEX_WAITER - popfd - ret -.ok: - inc eax - mov [ecx+RWSEM.count], eax - - popfd - ret - -;void __fastcall down_write(struct rw_semaphore *sem) - -align 4 -down_write: - pushfd - cli - sub esp, sizeof.MUTEX_WAITER - - mov edx, [TASK_BASE] - mov [esp+MUTEX_WAITER.task], edx - mov [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_WRITE - mov [edx+TASKDATA.state], TSTATE_RUN_SUSPENDED - - list_add_tail esp, ecx ;esp= new waiter, ecx= list head - - xor eax, eax - not eax - -.forever: - test eax, [ecx+RWSEM.count] - jz @F - - mov [edx+TASKDATA.state], TSTATE_RUN_SUSPENDED - call change_task - jmp .forever -@@: - mov [ecx+RWSEM.count], eax - list_del esp - - add esp, sizeof.MUTEX_WAITER - popfd - ret - -;void __fastcall up_read(struct rw_semaphore *sem) - -align 4 -up_read: - pushfd - cli - - dec [ecx+RWSEM.count] - jnz @F - - mov eax, [ecx+RWSEM.wait_list.next] - cmp eax, ecx - je @F - - mov eax, [eax+MUTEX_WAITER.task] - mov [eax+TASKDATA.state], TSTATE_RUNNING -@@: - popfd - ret - -;void __fastcall up_write(struct rw_semaphore *sem) - -align 4 -up_write: - - pushfd - cli - - mov eax, [ecx+RWSEM.wait_list.next] - mov [ecx+RWSEM.count], 0 - - cmp ecx, eax - je .done - - mov edx, [eax+MUTEX_WAITER.type] - test edx, edx - jnz .wake - - mov eax, [eax+MUTEX_WAITER.task] - mov [eax+TASKDATA.state], TSTATE_RUNNING -.done: - popfd - ret - -.wake: - push ebx - push esi - push edi - - xor esi, esi - mov edi, ecx - -.wake_list: - - mov ebx, [eax+MUTEX_WAITER.list.next] - list_del eax - mov edx, [eax+MUTEX_WAITER.task] - mov [edx+TASKDATA.state], TSTATE_RUNNING - inc esi - cmp edi, ebx - je .wake_done - - mov ecx, [ebx+MUTEX_WAITER.type] - test ecx, ecx - jz .wake_done - - mov eax, ebx - jmp .wake_list - -.wake_done: - add [edi+RWSEM.count], esi - - pop edi - pop esi - pop ebx - popfd - ret - - -purge RWSEM_WAITING_FOR_WRITE -purge RWSEM_WAITING_FOR_READ - - -if ~defined sync_inc -sync_inc_fix: -sync_inc fix sync_inc_fix - -;simplest mutex. -macro SimpleMutex name -{ -; iglobal - name dd 0 - name#.type = 1 -; endg -} -macro WaitSimpleMutex name -{ - local start_wait,ok -start_wait=$ - cli - cmp [name], dword 0 - jz ok - sti - call change_task - jmp start_wait -ok=$ - push eax - mov eax, dword [TASK_BASE+second_base_address] - mov eax, [eax+TASKDATA.pid] - mov [name], eax - pop eax - sti -} -macro ReleaseSimpleMutex name -{ - mov [name], dword 0 -} -macro TryWaitSimpleMutex name ;result in eax and in flags -{ - local ok,try_end - cmp [name], dword 0 - jz ok - xor eax, eax - jmp try_end -ok=$ - xor eax, eax - inc eax -try_end=$ -} -macro SimpleCriticalSection name -{ -; iglobal - name dd 0 - dd 0 - name#.type=2 -; endg -} -macro WaitSimpleCriticalSection name -{ - local start_wait,first_wait,inc_counter,end_wait - push eax - mov eax, [TASK_BASE+second_base_address] - mov eax, [eax+TASKDATA.pid] -start_wait=$ - cli - cmp [name], dword 0 - jz first_wait - cmp [name], eax - jz inc_counter - sti - call change_task - jmp start_wait -first_wait=$ - mov [name], eax - mov [name+4], dword 1 - jmp end_wait -inc_counter=$ - inc dword [name+4] -end_wait=$ - sti - pop eax -} -macro ReleaseSimpleCriticalSection name -{ - local release_end - dec dword [name+4] - jnz release_end - mov [name], dword 0 -release_end=$ -} -macro TryWaitSimpleCriticalSection name ;result in eax and in flags -{ - local ok,try_end - mov eax, [CURRENT_TASK+second_base_address] - mov eax, [eax+TASKDATA.pid] - cmp [name], eax - jz ok - cmp [name], 0 - jz ok - xor eax, eax - jmp try_end -ok=$ - xor eax, eax - inc eax -try_end=$ -} -_cli equ call MEM_HeapLock -_sti equ call MEM_HeapUnLock -end if - diff --git a/kernel/branches/Kolibri-F/core/sys32-sp.inc b/kernel/branches/Kolibri-F/core/sys32-sp.inc deleted file mode 100644 index a7957cd96..000000000 --- a/kernel/branches/Kolibri-F/core/sys32-sp.inc +++ /dev/null @@ -1,14 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; Éste archivo debe ser editado con codificación CP866 - - msg_sel_ker cp850 "núcleo", 0 - msg_sel_app cp850 "aplicación", 0 diff --git a/kernel/branches/Kolibri-F/core/sys32.inc b/kernel/branches/Kolibri-F/core/sys32.inc deleted file mode 100644 index c6edd9e0d..000000000 --- a/kernel/branches/Kolibri-F/core/sys32.inc +++ /dev/null @@ -1,840 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2021. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License. ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -align 4 ;3A08 -build_interrupt_table: - mov edi, idts - mov esi, sys_int - mov ecx, 0x40 - mov eax, (10001110b shl 24) + os_code - @@: - movsw ; low word of code-entry - stosd ; interrupt gate type : os_code selector - movsw ; high word of code-entry - loop @b - movsd ; copy low dword of trap gate for int 0x40 - movsd ; copy high dword of trap gate for int 0x40 - mov ecx, 23 - mov eax, (10001110b shl 24) + os_code - @@: - movsw ; low word of code-entry - stosd ; interrupt gate type : os_code selector - movsw ; high word of code-entry - loop @b - lidt [esi] - ret - -iglobal - align 4 - sys_int: - ; exception handlers addresses (for interrupt gate construction) - dd e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc - dd e8,e9,e10,e11,e12,e13,page_fault_exc,e15 - dd e16, e17,e18, e19 - times 12 dd unknown_interrupt ;int_20..int_31 - - ; interrupt handlers addresses (for interrupt gate construction) - ; 0x20+ are IRQ handlers - dd irq0 - rept 12 irqn:1 \{dd irq_serv.irq_\#irqn\} - dd irqD - rept 18 irqn:14 \{dd irq_serv.irq_\#irqn\} - - ; int_0x40 gate trap (for directly copied) - dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16 - - rept 23 irqn:33 \{dd irq_serv.irq_\#irqn\} - - idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data) - dw 2*($-sys_int-4)-1 - dd idts ; 0x8000B100 - dw 0 ; alignment - - msg_fault_sel dd msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b - dd msg_exc_c,msg_exc_d,msg_exc_e,msg_exc_u - dd msg_exc_u,msg_exc_11 - - msg_exc_8 db "Double fault", 0 - msg_exc_u db "Undefined Exception", 0 - msg_exc_a db "Invalid TSS", 0 - msg_exc_b db "Segment not present", 0 - msg_exc_c db "Stack fault", 0 - msg_exc_d db "General protection fault", 0 - msg_exc_e db "Page fault", 0 - msg_exc_11 db "Alignment Check", 0 - - if lang eq sp - include 'core/sys32-sp.inc' - else - msg_sel_ker db "kernel", 0 - msg_sel_app db "application", 0 - end if - -endg - -macro save_ring3_context { - pushad -} -macro restore_ring3_context { - popad -} -macro exc_wo_code [num] { - e#num : - save_ring3_context - mov bl, num - jmp exc_c -} exc_wo_code 0,1,2,3,4,5,6,15,16,19 - -macro exc_w_code [num] { - e#num : - add esp, 4 - save_ring3_context - mov bl, num - jmp exc_c -} exc_w_code 8,9,10,11,12,13,17,18 - - -uglobal - pf_err_code dd ? -endg - -page_fault_exc: ; foolproof: selectors are clobbered ... - pop [ss:pf_err_code] ; actually, until the next #PF - save_ring3_context - mov bl, 14 - -exc_c: ; exceptions (all but 7th - #NM) - ; stack frame when exception/interrupt from ring3 + pushad (i.e right here) - reg_ss equ esp+0x30 - reg_esp3 equ esp+0x2C - reg_eflags equ esp+0x28 - reg_cs3 equ esp+0x24 - reg_eip equ esp+0x20 - ; this if frame from pushad - reg_eax equ esp+0x1C - reg_ecx equ esp+0x18 - reg_edx equ esp+0x14 - reg_ebx equ esp+0x10 - reg_esp0 equ esp+0x0C - reg_ebp equ esp+0x08 - reg_esi equ esp+0x04 - reg_edi equ esp+0x00 - - mov ax, app_data ; exception - mov ds, ax ; load proper values - mov es, ax ; to registers - cld ; clear the direction flag - movzx ebx, bl -; redirect to V86 manager? (EFLAGS & 0x20000) != 0? - test byte[reg_eflags+2], 2 - jnz v86_exc_c - cmp bl, 14 ; #PF - jne @f - call page_fault_handler ; SEE: core/memory.inc - @@: - mov esi, [current_slot] - btr [esi+APPDATA.except_mask], ebx - jnc @f - mov eax, [esi+APPDATA.exc_handler] - test eax, eax - jnz IRetToUserHook - @@: - cli - mov eax, [esi+APPDATA.debugger_slot] - test eax, eax - jnz .debug -; not debuggee => say error and terminate - call show_error_parameters - sti - mov [edx + TASKDATA.state], TSTATE_TERMINATING - call wakeup_osloop - call change_task -; If we're here, then the main OS thread has crashed before initializing IDLE thread. -; Or they both have crashed. Anyway, things are hopelessly broken. - hlt - jmp $-1 -.debug: -; we are debugged process, notify debugger and suspend ourself -; eax=debugger PID - mov ecx, 1 ; debug_message code=other_exception - cmp bl, 1 ; #DB - jne .notify ; notify debugger and suspend ourself - mov ebx, dr6 ; debug_message data=DR6_image - xor edx, edx - mov dr6, edx - mov edx, dr7 - mov cl, not 8 - .l1: - shl dl, 2 - jc @f - and bl, cl - @@: - sar cl, 1 - jc .l1 - mov cl, 3 ; debug_message code=debug_exception -.notify: - push ebx ; debug_message data - mov ebx, [TASK_BASE] - push [ebx+TASKDATA.pid] ; PID - push ecx ; debug_message code ((here: ecx==1/3)) - mov cl, 12 ; debug_message size - call debugger_notify ;; only ONE using, inline ??? SEE: core/debug.inc - add esp, 12 - mov edx, [TASK_BASE] - mov [edx+TASKDATA.state], TSTATE_RUN_SUSPENDED - call change_task ; SEE: core/shed.inc - restore_ring3_context - iretd - -IRetToUserHook: - xchg eax, [reg_eip] - sub dword[reg_esp3], 8 - mov edi, [reg_esp3] - stosd - mov [edi], ebx - restore_ring3_context -; simply return control to interrupted process -unknown_interrupt: - iretd - -;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -; bl - error vector -show_error_parameters: - cmp bl, 0x06 - jnz .no_ud - push ebx - mov ebx, ud_user_message - mov ebp, notifyapp - call fs_execute_from_sysdir_param - pop ebx -.no_ud: - mov edx, [TASK_BASE];not scratched below - if lang eq sp - DEBUGF 1, "K : Proceso - terminado forzado PID: %x [%s]\n", [edx+TASKDATA.pid], [current_slot] - else - DEBUGF 1, "K : Process - forced terminate PID: %x [%s]\n", [edx+TASKDATA.pid], [current_slot] - end if - cmp bl, 0x08 - jb .l0 - cmp bl, 0x11 - jbe .l1 - .l0: - mov bl, 0x09 - .l1: - mov eax, [msg_fault_sel+ebx*4 - 0x08*4] - DEBUGF 1, "K : %s\n", eax - mov eax, [reg_cs3+4] - mov edi, msg_sel_app - mov ebx, [reg_esp3+4] - cmp eax, app_code - je @f - mov edi, msg_sel_ker - mov ebx, [reg_esp0+4] - @@: - DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4] - DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4] - DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx - DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi - - DEBUGF 1, "K : Stack dump:\n" - push eax ebx ecx edx - call .check_ESP - test eax, eax - jnz .error_ESP - DEBUGF 1, "K : [ESP+00]: %x",[ebx] - add ebx, 4 - call .check_ESP - test eax, eax - jnz .error_ESP - DEBUGF 1, " [ESP+04]: %x",[ebx] - add ebx, 4 - call .check_ESP - test eax, eax - jnz .error_ESP - DEBUGF 1, " [ESP+08]: %x\n",[ebx] - add ebx, 4 - call .check_ESP - test eax, eax - jnz .error_ESP - DEBUGF 1, "K : [ESP+12]: %x",[ebx] - add ebx, 4 - call .check_ESP - test eax, eax - jnz .error_ESP - DEBUGF 1, " [ESP+16]: %x",[ebx] - add ebx, 4 - call .check_ESP - test eax, eax - jnz .error_ESP - DEBUGF 1, " [ESP+20]: %x\n",[ebx] - add ebx, 4 - call .check_ESP - test eax, eax - jnz .error_ESP - DEBUGF 1, "K : [ESP+24]: %x",[ebx] - add ebx, 4 - call .check_ESP - test eax, eax - jnz .error_ESP - DEBUGF 1, " [ESP+28]: %x",[ebx] - add ebx, 4 - call .check_ESP - test eax, eax - jnz .error_ESP - DEBUGF 1, " [ESP+32]: %x\n",[ebx] - pop edx ecx ebx eax - ret -.error_ESP: - pop edx ecx ebx eax - DEBUGF 1, "\n" - DEBUGF 1, "K : Unexpected end of the stack\n" - ret -;-------------------------------------- -.check_ESP: - push ebx - shr ebx, 12 - mov ecx, ebx - shr ecx, 10 - mov edx, [master_tab+ecx*4] - test edx, PG_READ - jz .fail ; page table is not created - ; incorrect address in the program - - mov eax, [page_tabs+ebx*4] - test eax, 2 - jz .fail ; address not reserved for use. error - - pop ebx - xor eax, eax - ret - -.fail: - pop ebx - xor eax, eax - dec eax - ret -;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - - restore reg_ss - restore reg_esp3 - restore reg_eflags - restore reg_cs - restore reg_eip - restore reg_eax - restore reg_ecx - restore reg_edx - restore reg_ebx - restore reg_esp0 - restore reg_ebp - restore reg_esi - restore reg_edi - - -align 4 -lock_application_table: - push eax ecx edx - mov ecx, application_table_mutex - call mutex_lock - - mov eax, [current_slot_idx] - shl eax, BSF sizeof.TASKDATA - add eax, TASK_TABLE+TASKDATA.pid - mov eax, [eax] - - mov [application_table_owner], eax - - pop edx ecx eax - - ret - -align 4 -unlock_application_table: - push eax ecx edx - - mov [application_table_owner], 0 - mov ecx, application_table_mutex - call mutex_unlock - - pop edx ecx eax - - ret - -; sysfn 64 implementation -align 4 -syscall_resize_app_memory: -; in: eax = 64 - function number -; ebx = 1 - number of its only subfunction -; ecx = new amount of memory -; out: -; eax = 0 - success -; eax = 1 - out of memory - -; cmp eax,1 - dec ebx - jnz .no_application_mem_resize - - mov eax, [pg_data.pages_free] - shl eax, 12 - cmp eax, ecx - jae @f - - xor eax, eax - inc eax - jmp .store_result -@@: - stdcall new_mem_resize, ecx -.store_result: - mov [esp+32], eax -.no_application_mem_resize: - ret - -iglobal -; process_terminating db 'K : Process - terminating',13,10,0 -; process_terminated db 'K : Process - done',13,10,0 - msg_obj_destroy db 'K : destroy app object',13,10,0 -endg - -; param -; esi= slot - -align 4 -terminate: ; terminate application -destroy_thread: - - .slot equ esp+4 ;locals - .process equ esp ;ptr to parent process - - - push esi ;save .slot - - shl esi, 8 - mov edx, [SLOT_BASE+esi+APPDATA.process] - test edx, edx - jnz @F - pop esi - shl esi, BSF sizeof.TASKDATA - mov [TASK_TABLE+esi+TASKDATA.state], TSTATE_FREE - ret -@@: - push edx ;save .process - lea edx, [SLOT_BASE+esi] - call scheduler_remove_thread - call lock_application_table - -; if the process is in V86 mode... - mov eax, [.slot] - shl eax, 8 - mov esi, [eax+SLOT_BASE+APPDATA.pl0_stack] - add esi, RING0_STACK_SIZE - cmp [eax+SLOT_BASE+APPDATA.saved_esp0], esi - jz .nov86 -; ...it has page directory for V86 mode - mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0] - mov ecx, [esi+4] - mov [eax+SLOT_BASE+APPDATA.process], ecx -; ...and I/O permission map for V86 mode - mov ecx, [esi+12] - mov [eax+SLOT_BASE+APPDATA.io_map], ecx - mov ecx, [esi+8] - mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx -.nov86: -; destroy per-thread kernel objects - mov esi, [.slot] - shl esi, 8 - add esi, SLOT_BASE+APP_OBJ_OFFSET -@@: - mov eax, [esi+APPOBJ.fd] - test eax, eax - jz @F - - cmp eax, esi - je @F - - push esi - call [eax+APPOBJ.destroy] - DEBUGF 1,"%s",msg_obj_destroy - pop esi - jmp @B -@@: - mov esi, [.slot] - cmp [fpu_owner], esi ; if user fpu last -> fpu user = 2 - jne @F - - mov [fpu_owner], 2 - mov eax, [sizeof.APPDATA*2+SLOT_BASE+APPDATA.fpu_state] - clts - bt [cpu_caps], CAPS_SSE - jnc .no_SSE - fxrstor [eax] - jmp @F -.no_SSE: - fnclex - frstor [eax] -@@: - - mov [KEY_COUNT], byte 0 ; empty keyboard buffer - mov [BTN_COUNT], byte 0 ; empty button buffer - - -; remove defined hotkeys - mov eax, hotkey_list -.loop: - cmp [eax+8], esi - jnz .cont - mov ecx, [eax] - jecxz @f - push dword [eax+12] - pop dword [ecx+12] -@@: - mov ecx, [eax+12] - push dword [eax] - pop dword [ecx] - xor ecx, ecx - mov [eax], ecx - mov [eax+4], ecx - mov [eax+8], ecx - mov [eax+12], ecx -.cont: - add eax, 16 - cmp eax, hotkey_list+256*16 - jb .loop -; get process PID - mov eax, esi - shl eax, BSF sizeof.TASKDATA - mov eax, [eax+TASK_TABLE+TASKDATA.pid] -; compare current lock input with process PID - cmp eax, [PID_lock_input] - jne @f - - xor eax, eax - mov [PID_lock_input], eax -@@: -; remove hotkeys in buffer - mov eax, hotkey_buffer -.loop2: - cmp [eax], esi - jnz .cont2 - and dword [eax+4], 0 - and dword [eax], 0 -.cont2: - add eax, 8 - cmp eax, hotkey_buffer+120*8 - jb .loop2 - - mov ecx, esi ; remove buttons - bnewba2: - mov edi, [BTN_ADDR] - mov eax, edi - cld - movzx ebx, word [edi] - inc bx - bnewba: - dec bx - jz bnmba - add eax, 0x10 - cmp cx, [eax] - jnz bnewba - pusha - mov ecx, ebx - inc ecx - shl ecx, 4 - mov ebx, eax - add eax, 0x10 - call memmove - dec dword [edi] - popa - jmp bnewba2 - bnmba: - - pusha ; save window coordinates for window restoring - cld - shl esi, BSF sizeof.WDATA - add esi, window_data - mov eax, [esi+WDATA.box.left] - mov [draw_limits.left], eax - add eax, [esi+WDATA.box.width] - mov [draw_limits.right], eax - mov eax, [esi+WDATA.box.top] - mov [draw_limits.top], eax - add eax, [esi+WDATA.box.height] - mov [draw_limits.bottom], eax - - xor eax, eax - mov edi, esi - mov ecx, sizeof.WDATA/4 - rep stosd - - lea edi, [esi-window_data+draw_data] - mov ecx, sizeof.WDATA/4 - rep stosd - popa - -; debuggee test - pushad - mov edi, esi - shl edi, BSF sizeof.TASKDATA - mov eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot] - test eax, eax - jz .nodebug - movi ecx, 8 - push dword [TASK_TABLE+edi+TASKDATA.pid]; PID - push 2 - call debugger_notify - pop ecx - pop ecx -.nodebug: - popad - - mov ebx, [.slot] - shl ebx, 8 - push ebx - mov ebx, [SLOT_BASE+ebx+APPDATA.pl0_stack] - - stdcall kernel_free, ebx - - pop ebx - mov ebx, [SLOT_BASE+ebx+APPDATA.cur_dir] - stdcall kernel_free, ebx - - mov edi, [.slot] - shl edi, 8 - add edi, SLOT_BASE - - mov eax, [edi+APPDATA.io_map] - cmp eax, [SLOT_BASE+sizeof.APPDATA+APPDATA.io_map] - je @F - call free_page -@@: - mov eax, [edi+APPDATA.io_map+4] - cmp eax, [SLOT_BASE+sizeof.APPDATA+APPDATA.io_map+4] - je @F - call free_page -@@: - lea ebx, [edi+APPDATA.list] - list_del ebx ;destroys edx, ecx - - mov eax, 0x20202020 - stosd - stosd - stosd - mov ecx, 244/4 - xor eax, eax - rep stosd - - ; activate window - movzx eax, word [WIN_STACK + esi*2] - cmp eax, [thread_count] - jne .dont_activate - pushad - .check_next_window: - dec eax - cmp eax, 1 - jbe .nothing_to_activate - lea esi, [WIN_POS+eax*2] - movzx edi, word [esi] ; edi = process - shl edi, BSF sizeof.TASKDATA - cmp [TASK_TABLE + edi + TASKDATA.state], TSTATE_FREE ; skip free slots - je .check_next_window - add edi, window_data -; \begin{diamond}[19.09.2006] -; skip minimized windows - test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED - jnz .check_next_window -; \end{diamond} - call waredraw - .nothing_to_activate: - popad - .dont_activate: - - push esi ; remove hd1 & cd & flp reservation - shl esi, BSF sizeof.TASKDATA - mov esi, [esi+TASK_TABLE+TASKDATA.pid] - cmp [cd_status], esi - jnz @f - call free_cd_channel - and [cd_status], 0 -@@: - pop esi - cmp [bgrlockpid], esi - jnz @f - and [bgrlockpid], 0 - and [bgrlock], 0 -@@: - - pusha ; remove all port reservations - mov edx, esi - shl edx, BSF sizeof.TASKDATA - add edx, TASK_TABLE - mov edx, [edx+TASKDATA.pid] - - rmpr0: - - mov esi, [RESERVED_PORTS] - - test esi, esi - jz rmpr9 - - rmpr3: - - mov edi, esi - shl edi, 4 - add edi, RESERVED_PORTS - - cmp edx, [edi] - je rmpr4 - - dec esi - jnz rmpr3 - - jmp rmpr9 - - rmpr4: - - mov ecx, 256 - sub ecx, esi - shl ecx, 4 - - mov esi, edi - add esi, 16 - cld - rep movsb - - dec dword [RESERVED_PORTS] - - jmp rmpr0 - - rmpr9: - - popa - mov edi, esi ; do not run this process slot - shl edi, BSF sizeof.TASKDATA - mov [edi+TASK_TABLE + TASKDATA.state], TSTATE_FREE -; debugger test - terminate all debuggees - mov eax, 2 - mov ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot -.xd0: - cmp eax, [thread_count] - ja .xd1 - cmp dword [ecx], esi - jnz @f - and dword [ecx], 0 - pushad - xchg eax, ecx - mov ebx, 2 - call syscall_system - popad -@@: - inc eax - add ecx, 0x100 - jmp .xd0 -.xd1: -;release slot - - bts [thr_slot_map], esi - - mov ecx, [.process] - lea eax, [ecx+PROC.thr_list] - cmp eax, [eax+LHEAD.next] - jne @F - - call destroy_process.internal -@@: - sti ; .. and life goes on - - mov eax, [draw_limits.left] - mov ebx, [draw_limits.top] - mov ecx, [draw_limits.right] - mov edx, [draw_limits.bottom] - call calculatescreen - xor eax, eax - xor esi, esi - call redrawscreen - - call unlock_application_table - ;mov esi,process_terminated - ;call sys_msg_board_str - add esp, 8 - ret -restore .slot -restore .process - -; Three following procedures are used to guarantee that -; some part of kernel code will not be terminated from outside -; while it is running. -; Note: they do not protect a thread from terminating due to errors inside -; the thread; accessing a nonexisting memory would still terminate it. - -; First two procedures must be used in pair by thread-to-be-protected -; to signal the beginning and the end of an important part. -; It is OK to have nested areas. - -; The last procedure must be used by outside wanna-be-terminators; -; if it is safe to terminate the given thread immediately, it returns eax=1; -; otherwise, it returns eax=0 and notifies the target thread that it should -; terminate itself when leaving a critical area (the last critical area if -; they are nested). - -; Implementation. Those procedures use one dword in APPDATA for the thread, -; APPDATA.terminate_protection. -; * The upper bit is 1 during normal operations and 0 when terminate is requested. -; * Other bits form a number = depth of critical regions, -; plus 1 if the upper bit is 1. -; * When this dword goes to zero, the thread should be destructed, -; and the procedure in which it happened becomes responsible for destruction. - -; Enter critical area. Called by thread which wants to be protected. -proc protect_from_terminate - mov edx, [current_slot] -; Atomically increment depth of critical areas and get the old value. - mov eax, 1 - lock xadd [edx+APPDATA.terminate_protection], eax -; If the old value was zero, somebody has started to terminate us, -; so we are destructing and cannot do anything protected. -; Otherwise, return to the caller. - test eax, eax - jz @f - ret -@@: -; Wait for somebody to finish us. - call change_task - jmp @b -endp - -; Leave critical area. Called by thread which wants to be protected. -proc unprotect_from_terminate - mov edx, [current_slot] -; Atomically decrement depth of critical areas. - lock dec [edx+APPDATA.terminate_protection] -; If the result of decrement is zero, somebody has requested termination, -; but at that moment we were inside a critical area; terminate now. - jz syscall_end -; Otherwise, return to the caller. - ret -endp - -; Request termination of thread identified by edx = SLOT_BASE + slot*sizeof.APPDATA. -; Called by anyone. -proc request_terminate - xor eax, eax ; set return value -; Atomically clear the upper bit. If it was already zero, then -; somebody has requested termination before us, so just exit. - lock btr [edx+APPDATA.terminate_protection], 31 - jnc .unsafe -; Atomically decrement depth of critical areas. - lock dec [edx+APPDATA.terminate_protection] -; If the result of decrement is nonzero, the target thread is inside a -; critical area; leave termination to leaving that area. - jnz .unsafe -; Otherwise, it is safe to kill the target now and the caller is responsible -; for this. Return eax=1. - inc eax -.unsafe: - ret -endp - diff --git a/kernel/branches/Kolibri-F/core/syscall.inc b/kernel/branches/Kolibri-F/core/syscall.inc deleted file mode 100644 index 4f0f4adc0..000000000 --- a/kernel/branches/Kolibri-F/core/syscall.inc +++ /dev/null @@ -1,186 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; SYSENTER ENTRY ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -align 32 -sysenter_entry: - ; Setting up the stack - mov esp, [ss:tss._esp0] - sti - push ebp ; save app esp + 4 - mov ebp, [ebp] ; ebp - original ebp - ;------------------ - pushad - cld - - call protect_from_terminate - - movzx eax, byte [esp+28] - mov edx, dword [esp+20] - call dword [servetable2 + eax * 4] - - call unprotect_from_terminate - popad - ;------------------ - xchg ecx, [ss:esp] ; in the stack top - app ecx, ecx - app esp + 4 - sub ecx, 4 - xchg edx, [ecx] ; edx - return point, & save original edx - push edx - mov edx, [ss:esp + 4] - mov [ecx + 4], edx ; save original ecx - pop edx - sysexit - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; SYSTEM CALL ENTRY ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -align 16 -i40: - pushad - cld - call protect_from_terminate - movzx eax, byte [esp+28] - mov edx, dword [esp+20] - call dword [servetable2 + eax * 4] - call unprotect_from_terminate - popad - iretd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; SYSCALL ENTRY ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -align 32 -syscall_entry: - ; cli syscall clear IF - xchg esp, [ss:tss._esp0] - push ecx - lea ecx, [esp+4] - xchg ecx, [ss:tss._esp0] - sti - push ecx - mov ecx, [ecx] - ;------------------ - pushad - cld - call protect_from_terminate - - movzx eax, byte [esp+28] - mov edx, dword [esp+20] - call dword [servetable2 + eax * 4] - - call unprotect_from_terminate - popad - ;------------------ - mov ecx, [ss:esp+4] - pop esp - sysret - -iglobal - ;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; SYSTEM FUNCTIONS TABLE ;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;; - align 4 - servetable2: - - dd syscall_draw_window ; 0 - define and draw the window; - dd syscall_setpixel ; 1 - put pixel in the window; - dd syscall_getkey ; 2 - get the code of the pressed key; - dd syscall_clock ; 3 - get system time; - dd syscall_writetext ; 4 - draw text string; - dd syscall_delay_hs_unprotected ; 5 - delay; - dd syscall_undefined ; 6 - system call undefined; - dd syscall_putimage ; 7 - draw image in the window; - dd syscall_button ; 8 - define/delete the button; - dd syscall_thread_info ; 9 - information on execution thread; - dd syscall_waitforevent ; 10 - wait for event; - dd syscall_checkforevent ; 11 - check for event, no wait; - dd syscall_redrawstat ; 12 - begin/end window redraw; - dd syscall_drawrect ; 13 - draw a rectangle in the window; - dd syscall_getscreensize ; 14 - get screen size; - dd syscall_background ; 15 - working with the background; - dd syscall_cachetodiskette ; 16 - save ramdisk on a floppy; - dd syscall_getbutton ; 17 - get the identifier of the pressed button; - dd syscall_system ; 18 - system services; - dd syscall_undefined ; 19 - system call undefined; - dd syscall_midi ; 20 - reset MIDI and output MIDI; - dd syscall_setup ; 21 - setting system parameters; - dd syscall_settime ; 22 - setting date, time, clock and alarm-clock; - dd syscall_wait_event_timeout ; 23 - wait for event with timeout; - dd syscall_cdaudio ; 24 - work with a CD player; - dd syscall_putarea_backgr ; 25 - put area to background; - dd syscall_getsetup ; 26 - get system parameters; - dd syscall_undefined ; 27 - system call undefined; - dd syscall_undefined ; 28 - system call undefined; - dd syscall_date ; 29 - get date; - dd syscall_current_directory ; 30 - get/set current directory; - dd syscall_undefined ; 31 - system call undefined; - dd syscall_undefined ; 32 - system call undefined; - dd syscall_undefined ; 33 - system call undefined; - dd syscall_getpixel_WinMap ; 34 - find out who the screen point belongs to; - dd syscall_getpixel ; 35 - read the color of the pixel on the screen; - dd syscall_getarea ; 36 - read the screen area; - dd syscall_get_mouse_pos ; 37 - work with the mouse; - dd syscall_drawline ; 38 - draw a line; - dd syscall_getbackground ; 39 - get background info; - dd syscall_set_eventmask ; 40 - set event mask; - dd syscall_undefined ; 41 - system call undefined; - dd syscall_undefined ; 42 - system call undefined; - dd syscall_outport ; 43 - input / output to the port; - dd syscall_undefined ; 44 - system call undefined; - dd syscall_undefined ; 45 - system call undefined; - dd syscall_reserveportarea ; 46 - reserve port area and free port area; - dd syscall_putnumber ; 47 - print a number to the window; - dd syscall_window_styles ; 48 - window display styles; - dd syscall_apm ; 49 - Advanced Power Management (APM); - dd syscall_set_window_shape ; 50 - window shape & scale; - dd syscall_threads ; 51 - threads; - dd syscall_undefined ; 52 - system call undefined; - dd syscall_undefined ; 53 - system call undefined; - dd syscall_clipboard ; 54 - working with the clipboard; - dd syscall_sound_interface ; 55 - sound interface; - dd syscall_undefined ; 56 - system call undefined; - dd syscall_pcibios ; 57 - PCI BIOS32; - dd syscall_undefined ; 58 - system call undefined; - dd syscall_undefined ; 59 - system call undefined; - dd syscall_IPC ; 60 - Inter Process Communication(IPC); - dd syscall_dga ; 61 - direct graphics access; - dd syscall_pci_api ; 62 - PCI functions; - dd syscall_msg_board ; 63 - system message board; - dd syscall_resize_app_memory ; 64 - resize application memory usage; - dd syscall_putimage_palette ; 65 - display an image with a palette in the window; - dd syscall_process_def ; 66 - process definitions - keyboard; - dd syscall_move_window ; 67 - window move or resize; - dd syscall_some_intrenal_services ; 68 - some internal services; - dd syscall_debug_services ; 69 - debug services; - dd syscall_file_system_lfn ; 70 - file system interface; - dd syscall_window_settings ; 71 - window settings; - dd syscall_send_window_msg ; 72 - send window message; - dd syscall_blit_32 ; 73 - graphic blitter; - dd syscall_network ; 74 - work with network devices; - dd syscall_socket ; 75 - work with network sockets; - dd syscall_protocols ; 76 - network options and statistics; - dd syscall_posix_subsystem ; 77 - POSIX subsystem; - dd syscall_undefined ; 78 - system call undefined; - dd syscall_undefined ; 79 - system call undefined; - dd syscall_fs_diff_encodings ; 80 - file system interface for different encodings; - - times 255 - ( ($-servetable2) /4 ) dd syscall_undefined - dd syscall_end ; -1-end application - -endg diff --git a/kernel/branches/Kolibri-F/core/taskman.inc b/kernel/branches/Kolibri-F/core/taskman.inc deleted file mode 100644 index fd375a41f..000000000 --- a/kernel/branches/Kolibri-F/core/taskman.inc +++ /dev/null @@ -1,1057 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2021. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License. ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -GREEDY_KERNEL = 0 - -struct APP_HEADER_00_ - banner dq ? - version dd ? ;+8 - start dd ? ;+12 - i_end dd ? ;+16 - mem_size dd ? ;+20 - i_param dd ? ;+24 -ends - -struct APP_HEADER_01_ - banner dq ? - version dd ? ;+8 - start dd ? ;+12 - i_end dd ? ;+16 - mem_size dd ? ;+20 - stack_top dd ? ;+24 - i_param dd ? ;+28 - i_icon dd ? ;+32 -ends - -struct APP_HDR - cmdline rd 1 ;0x00 - path rd 1 ;0x04 - eip rd 1 ;0x08 - esp rd 1 ;0x0C - _edata rd 1 ;0x10 - _emem rd 1 ;0x14 - img_base rd 1 ;0x18 - img_size rd 1 - filename_size rd 1 - cmdline_size rd 1 - path_string rd 1 -ends - -macro _clear_ op -{ mov ecx, op/4 - xor eax, eax - cld - rep stosd -} - -align 4 -_strnlen: - mov edx, ecx - xor eax, eax - repne scasb - jne @F - inc ecx -@@: - mov eax, edx - sub eax, ecx - retn - -fs_execute_from_sysdir: - xor ebx, ebx -fs_execute_from_sysdir_param: - stdcall kernel_alloc, maxPathLength - push eax ebx - mov esi, ebp - mov edi, eax - xor eax, eax - call getFullPath - pop ecx ebx - xor edx, edx -proc fs_execute -; edx = flags -; ecx -> cmdline -; ebx -> absolute file path -; eax = string length - locals - cmdline rd 1 - flags rd 1 - slot rd 1 ; index of new thread slot - slot_base rd 1 ; base address of it -; app header data - hdr_cmdline rd 1 - hdr_path rd 1 - hdr_eip rd 1 - hdr_esp rd 1 - hdr_edata rd 1 - hdr_emem rd 1 - file_base rd 1 - file_size rd 1 - filename_size rd 1 - cmdline_size rd 1 - path_string rd 1 - endl - - mov [flags], edx - mov [cmdline], ecx - mov [path_string], ebx - mov [filename_size], eax - mov esi, -ERROR_FILE_NOT_FOUND - test eax, eax - jz .err_file - stdcall load_file, ebx - test eax, eax - jz .err_file - - mov [file_base], eax - mov [file_size], ebx - lea ebx, [hdr_cmdline] - call test_app_header ; fill our app header data locals with values from header of given program (if its correct) - mov esi, -0x1F - test eax, eax - jz .err_hdr - - call lock_application_table - call alloc_thread_slot ; create a slot for new thread - mov esi, -0x20 ; too many processes - test eax, eax - jz .err_0 - - mov [slot], eax - shl eax, 8 - lea edi, [SLOT_BASE+eax] - mov [slot_base], edi -; clean extended information about process - mov ecx, sizeof.APPDATA/4 - xor eax, eax - cld - rep stosd -; write application name ( APPDATA.appname ) - stdcall strrchr, [path_string], '/' - lea esi, [eax+1] ; -> name without path - mov ecx, 11 - mov edi, [slot_base] -@@: - call utf8to16 - call uni2ansi_char - cmp al, '.' - jz @f - test al, al - jz @f - stosb - loop @b -@@: - mov edi, [cmdline] - xor eax, eax - test edi, edi - jz @f - mov ecx, 65535 - call _strnlen - cmp eax, 256 - jb @f -; if cmdline length >= 256 then increase needed memory size by this length - lea ebx, [eax+1] - add [hdr_emem], ebx -@@: - mov [cmdline_size], eax - stdcall create_process, [hdr_emem] ; create a new process - mov esi, -30 ; no memory - test eax, eax - jz .err_hdr - -; add new process to the list - mov ebx, [sys_proc+LHEAD.prev] - __list_add eax, ebx, sys_proc -; fill the structure fields: - mov ebx, [hdr_emem] - mov [eax+PROC.mem_used], ebx - -; write that main thread of app belongs to new process - mov ebx, [slot_base] - mov [ebx+APPDATA.process], eax - -; initialize the thread list of process: at this moment it consists only of one main thread - lea edx, [ebx+APPDATA.list] - lea ecx, [eax+PROC.thr_list] - list_add_tail edx, ecx - -; allocate space and copy app header data locals and cmdline string there, put pointer to exec_params of new thread - mov eax, [cmdline_size] - add eax, sizeof.APP_HDR - stdcall kernel_alloc, eax - mov [ebx+APPDATA.exec_params], eax - mov edi, eax - lea esi, [hdr_cmdline] - mov ecx, sizeof.APP_HDR/4 - rep movsd - mov ecx, [cmdline_size] - mov esi, [cmdline] - rep movsb -; set other parameters of application - lea eax, [hdr_cmdline] - stdcall set_app_params , [slot], eax, [flags] - mov eax, [process_number] ; return process number - call unlock_application_table - ret - -.err_0: - call unlock_application_table -.err_hdr: - stdcall kernel_free, [file_base] -.err_file: - stdcall kernel_free, [path_string] - mov eax, esi - ret -endp - -align 4 -test_app_header: - virtual at eax - APP_HEADER_00 APP_HEADER_00_ - end virtual - virtual at eax - APP_HEADER_01 APP_HEADER_01_ - end virtual - - cmp dword [eax], 'MENU' - jne .fail - cmp word [eax+4], 'ET' - jne .fail - - cmp [eax+6], word '00' - jne .check_01_header - - mov ecx, [APP_HEADER_00.start] - mov [ebx+APP_HDR.eip], ecx - mov edx, [APP_HEADER_00.mem_size] - mov [ebx+APP_HDR._emem], edx - shr edx, 1 - sub edx, 0x10 - mov [ebx+APP_HDR.esp], edx - mov ecx, [APP_HEADER_00.i_param] - mov [ebx+APP_HDR.cmdline], ecx - mov [ebx+APP_HDR.path], 0 - mov edx, [APP_HEADER_00.i_end] - mov [ebx+APP_HDR._edata], edx - ret - - .check_01_header: - - cmp [eax+6], word '01' - je @f - cmp [eax+6], word '02' - jne .fail -@@: - mov ecx, [APP_HEADER_01.start] - mov [ebx+0x08], ecx - mov edx, [APP_HEADER_01.mem_size] - -; \begin{diamond}[20.08.2006] -; sanity check (functions 19,58 load app_i_end bytes and that must -; fit in allocated memory to prevent kernel faults) - cmp edx, [APP_HEADER_01.i_end] - jb .fail -; \end{diamond}[20.08.2006] - - mov [ebx+APP_HDR._emem], edx - mov ecx, [APP_HEADER_01.stack_top] - mov [ebx+APP_HDR.esp], ecx - mov edx, [APP_HEADER_01.i_param] - mov [ebx+APP_HDR.cmdline], edx - mov ecx, [APP_HEADER_01.i_icon] - mov [ebx+APP_HDR.path], ecx - mov edx, [APP_HEADER_01.i_end] - mov [ebx+APP_HDR._edata], edx - ret -.fail: - xor eax, eax - ret - -align 4 -alloc_thread_slot: -;input: -; none -;result: -; eax=[new_thread_slot]<>0 - ok -; 0 - failed. -;This function find least empty slot. -;It doesn't increase [thread_count]! - - - mov edx, thr_slot_map - pushfd - cli -.l1: - bsf eax, [edx] - jnz .found - add edx, 4 - cmp edx, thr_slot_map+32 - jb .l1 - - popfd - xor eax, eax - ret -.found: - btr [edx], eax - sub edx, thr_slot_map - lea eax, [eax+edx*8] - popfd - ret - -align 4 -proc create_process stdcall, app_size:dword - locals - process dd ? - app_tabs dd ? - endl - - push ebx - push esi - push edi - - xor eax, eax - mov [process], eax - - mov eax, [app_size] - add eax, 0x3FFFFF - shr eax, 22 - mov [app_tabs], eax - - stdcall kernel_alloc, 0x2000 - test eax, eax - jz .fail - mov [process], eax - - lea edi, [eax+PROC.heap_lock] - mov ecx, (PROC.ht_free-PROC.heap_lock)/4 - - list_init eax - add eax, PROC.thr_list - list_init eax - - xor eax, eax - cld - rep stosd - - mov [edi], dword (PROC.pdt_0 - PROC.htab)/4 - 3 - mov [edi+4], dword 3 ;reserve handles for stdin stdout and stderr - mov ecx, (PROC.pdt_0 - PROC.htab)/4 - add edi, 8 - inc eax -@@: - stosd - inc eax - cmp eax, ecx - jbe @B - - mov eax, edi - call get_pg_addr - mov [edi-4096+PROC.pdt_0_phys], eax - - mov ecx, (OS_BASE shr 20)/4 - xor eax, eax - rep stosd - - mov ecx, (OS_BASE shr 20)/4 - mov esi, sys_proc+PROC.pdt_0+(OS_BASE shr 20) - rep movsd - - mov eax, [edi-8192+PROC.pdt_0_phys] - or eax, PG_SWR - mov [edi-4096+(page_tabs shr 20)], eax - - lea edx, [edi-4096] - mov esi, [app_tabs] - -.alloc_page_dir: - call alloc_page - test eax, eax - jz .fail - or eax, PG_UWR - mov [edx], eax - - mov edi, [tmp_task_ptab] - stdcall map_page, edi, eax, PG_SWR - mov ecx, 1024 - xor eax, eax - rep stosd - - add edx, 4 - dec esi - jnz .alloc_page_dir - - stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP - mov eax, [process] - - pop edi - pop esi - pop ebx - ret -.fail: - mov ecx, [process] - jcxz @F - - call destroy_process -@@: - xor eax, eax - pop edi - pop esi - pop ebx - ret -endp - -align 4 -proc destroy_page_table stdcall, pg_tab:dword - - push esi - - mov esi, [pg_tab] - mov ecx, 1024 -.free: - mov eax, [esi] - test eax, 1 - jz .next - test eax, 2 - jz .next - test eax, 1 shl 9 - jnz .next ;skip shared pages - call free_page -.next: - add esi, 4 - dec ecx - jnz .free - pop esi - ret -endp - -align 4 -destroy_process: ;fastcall ecx= ptr to process - - lea eax, [ecx+PROC.thr_list] - cmp eax, [eax+LHEAD.next] - jne .exit - -align 4 -.internal: - push ecx - - mov esi, ecx - list_del esi - - mov esi, [esi+PROC.dlls_list_ptr] - call destroy_all_hdlls - - mov esi, [esp] - add esi, PROC.pdt_0 - mov edi, (0x80000000 shr 20)/4 -.destroy: - mov eax, [esi] - test eax, 1 - jz .next - and eax, not 0xFFF - stdcall map_page, [tmp_task_ptab], eax, PG_SWR - stdcall destroy_page_table, [tmp_task_ptab] - mov eax, [esi] - call free_page -.next: - add esi, 4 - dec edi - jnz .destroy - - call kernel_free ;ecx still in stack - stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP -.exit: - ret - -align 4 -get_pid: - mov eax, [TASK_BASE] - mov eax, [eax+TASKDATA.pid] - ret - -pid_to_slot: -;Input: -; eax - pid of process -;Output: -; eax - slot of process or 0 if process don't exists -;Search process by PID. - push ebx - push ecx - mov ebx, [thread_count] - shl ebx, BSF sizeof.TASKDATA ; multiply by size - ; add 2*32 cause: - ; [TASK_TABLE; TASK_TABLE + 32) isnt a task actually - ; skip first process in the task table - mov ecx, 2*32 - -.loop: -;ecx = offset of current process info entry -;ebx = maximum permitted offset - cmp [TASK_TABLE+ecx+TASKDATA.state], TSTATE_FREE - jz .endloop ;skip empty slots - cmp [TASK_TABLE+ecx+TASKDATA.pid], eax;check PID - jz .pid_found -.endloop: - add ecx, sizeof.TASKDATA - cmp ecx, ebx - jle .loop - - pop ecx - pop ebx - xor eax, eax - ret - -.pid_found: - shr ecx, BSF sizeof.TASKDATA ; divide by size - mov eax, ecx ;convert offset to index of slot - pop ecx - pop ebx - ret - - -align 4 -proc read_process_memory -;Input: -; eax - process slot -; ecx - buffer address -; edx - buffer size -; esi - start address in other process -;Output: -; eax - number of bytes read. - locals - slot dd ? - buff dd ? - r_count dd ? - offset dd ? - tmp_r_cnt dd ? - endl - - mov [slot], eax - mov [buff], ecx - and [r_count], 0 - mov [tmp_r_cnt], edx - mov [offset], esi - - pushad -.read_mem: - mov edx, [offset] - mov ebx, [tmp_r_cnt] - - mov ecx, 0x400000 - and edx, 0x3FFFFF - sub ecx, edx - cmp ecx, ebx - jbe @f - mov ecx, ebx -@@: - cmp ecx, 0x8000 - jna @F - mov ecx, 0x8000 -@@: - mov ebx, [offset] - - push ecx - stdcall map_memEx, [proc_mem_map], \ - [slot], ebx, ecx, PG_READ - pop ecx - - mov esi, [offset] - and esi, 0xfff - sub eax, esi - jbe .ret - cmp ecx, eax - jbe @f - mov ecx, eax - mov [tmp_r_cnt], eax -@@: - add esi, [proc_mem_map] - mov edi, [buff] - mov edx, ecx - rep movsb - add [r_count], edx - - add [offset], edx - sub [tmp_r_cnt], edx - jnz .read_mem -.ret: - popad - mov eax, [r_count] - ret -endp - -align 4 -proc write_process_memory -;Input: -; eax - process slot -; ecx - buffer address -; edx - buffer size -; esi - start address in other process -;Output: -; eax - number of bytes written - - locals - slot dd ? - buff dd ? - w_count dd ? - offset dd ? - tmp_w_cnt dd ? - endl - - mov [slot], eax - mov [buff], ecx - and [w_count], 0 - mov [tmp_w_cnt], edx - mov [offset], esi - - pushad -.read_mem: - mov edx, [offset] - mov ebx, [tmp_w_cnt] - - mov ecx, 0x400000 - and edx, 0x3FFFFF - sub ecx, edx - cmp ecx, ebx - jbe @f - mov ecx, ebx -@@: - cmp ecx, 0x8000 - jna @F - mov ecx, 0x8000 -@@: - mov ebx, [offset] - push ecx - stdcall map_memEx, [proc_mem_map], \ - [slot], ebx, ecx, PG_SWR - pop ecx - - mov edi, [offset] - and edi, 0xfff - sub eax, edi - jbe .ret - cmp ecx, eax - jbe @f - mov ecx, eax - mov [tmp_w_cnt], eax -@@: - add edi, [proc_mem_map] - mov esi, [buff] - mov edx, ecx - rep movsb - - add [w_count], edx - add [offset], edx - sub [tmp_w_cnt], edx - jnz .read_mem -.ret: - popad - mov eax, [w_count] - ret -endp - -;ebx = 1 - kernel thread -;ecx=thread entry point -;edx=thread stack pointer -;creation flags 0x01 - debugged -; 0x02 - kernel - -align 4 -proc new_sys_threads - locals - slot dd ? - flags dd ? - app_cmdline dd ? ;0x00 - app_path dd ? ;0x04 - app_eip dd ? ;0x08 - app_esp dd ? ;0x0C - app_mem dd ? ;0x10 - endl - - shl ebx, 1 - mov [flags], ebx - - xor eax, eax - mov [app_eip], ecx - mov [app_cmdline], eax - mov [app_esp], edx - mov [app_path], eax - - call lock_application_table - - call alloc_thread_slot - test eax, eax - jz .failed - - mov [slot], eax - - mov esi, [current_slot] - mov ebx, esi ;ebx=esi - pointer to extended information about current thread - - mov edi, eax - shl edi, 8 - add edi, SLOT_BASE - mov edx, edi ;edx=edi - pointer to extended infomation about new thread - mov ecx, sizeof.APPDATA/4 - xor eax, eax - cld - rep stosd ;clean extended information about new thread - mov esi, ebx - mov edi, edx - mov ecx, 11 - rep movsb ;copy process name - - - mov eax, [ebx+APPDATA.tls_base] - test eax, eax - jz @F - - push edx - stdcall user_alloc, 4096 - pop edx - test eax, eax - jz .failed1;eax=0 -@@: - mov [edx+APPDATA.tls_base], eax - - mov eax, [ebx+APPDATA.process] - mov [edx+APPDATA.process], eax - - lea ebx, [edx+APPDATA.list] - lea ecx, [eax+PROC.thr_list] - list_add_tail ebx, ecx ;add thread to process child's list - - lea eax, [app_cmdline] - stdcall set_app_params , [slot], eax, [flags] - - mov eax, [process_number] ;set result - call unlock_application_table - ret -.failed: - xor eax, eax -.failed1: - call unlock_application_table - dec eax ;-1 - ret -endp - -proc map_process_image stdcall, img_size:dword, file_base:dword, file_size:dword - - mov edx, [img_size] - mov esi, [file_base] - mov ecx, [file_size] - add edx, 4095 - add ecx, 4095 - shr edx, 12 ; total pages - shr ecx, 12 ; image pages - - mov edi, page_tabs - shr esi, 10 - add esi, edi - -.map_image: - lodsd - and eax, -4096 - or eax, PG_UWR - stosd - dec edx - loop .map_image - - test edx, edx - jz .done -.map_bss: - call alloc_page - test eax, eax - jz .fail - - or eax, PG_UWR - stosd - dec edx - jnz .map_bss - - mov edi, [file_size] - mov ecx, [img_size] - add edi, 4095 - and edi, -4096 - add ecx, 4095 - and ecx, -4096 - sub ecx, edi - shr ecx, 2 - xor eax, eax - rep stosd -.done: -.fail: - ret -endp - -align 4 -common_app_entry: - mov ebp, [current_slot] - mov ebp, [ebp+APPDATA.exec_params] - test ebp, ebp - jz .exit -; APPDATA.exec_params have first thread only, -; so second and next threads don't get here (they jump to .exit) - stdcall map_process_image, [ebp+APP_HDR._emem],\ - [ebp+APP_HDR.img_base], [ebp+APP_HDR.img_size] - mov esi, [ebp+APP_HDR.path_string] - mov edi, [ebp+APP_HDR.path] - mov ecx, [ebp+APP_HDR.filename_size] - cmp ecx, 1023 - jc @f - mov ecx, 1022 -@@: - push esi - test edi, edi - jz @f - stdcall is_region_userspace, edi, [ebp+APP_HDR.filename_size] - jz @f - mov al, '/' - stosb - rep movsb - mov byte [edi], 0 -@@: - call kernel_free - mov edi, [ebp+APP_HDR.cmdline] - test edi, edi - jz .check_tls_header - lea esi, [ebp+sizeof.APP_HDR] - mov ecx, [ebp+APP_HDR.cmdline_size] - cmp ecx, 256 - jb .copy_cmdline - mov edi, [ebp+APP_HDR._emem] - add edi, 4095 - and edi, -4096 - sub edi, ecx - dec edi - cmp word [6], '00' - jne @f - mov [APP_HEADER_00_.i_param], edi - jmp .copy_cmdline -@@: - mov [APP_HEADER_01_.i_param], edi -.copy_cmdline: - inc ecx ; keep in mind about 0 in the end - stdcall is_region_userspace, edi, ecx - jz .check_tls_header - dec ecx - rep movsb - mov byte [edi], 0 -.check_tls_header: - cmp word [6], '02' - jne .try_load_dll ;.cleanup - call init_heap - stdcall user_alloc, 4096 - mov edx, [current_slot] - mov [edx+APPDATA.tls_base], eax - mov [tls_data_l+2], ax - shr eax, 16 - mov [tls_data_l+4], al - mov [tls_data_l+7], ah - mov dx, app_tls - mov fs, dx -; { Patch by Coldy, For DLL autoload -.try_load_dll: -; Test app header version - mov ecx, dword[ebp+APP_HDR.img_base] - cmp dword[ecx+8], 2 - jne .cleanup -;if APP_HEADER.version = 2 => load lib/dll.obj & change eip to APP_STARTUP_THUNK - DEBUGF 1, 'K : App header version 2\n' - stdcall load_library, dll_lib_path, 0 - cmp eax, 0 - jne @f -; Something went wrong (TODO: Next 2 line is code copy after .cleanup) - stdcall free_kernel_space, [ebp+APP_HDR.img_base] - stdcall kernel_free, ebp - DEBUGF 1, 'K : DLL.OBJ not found! Terminate application!\n' - mov ebx, dll_error_msg - mov ebp, notifyapp - call fs_execute_from_sysdir_param -; Terminate process (TODO: Need jump to .cleanup after syscall_end ?) - call syscall_end - -@@: -; Find APP_STARTUP_THUNK in DLL.OBJ - sub eax, 4 - mov eax, [eax] - -;.change_eip: - mov ecx, [current_slot] - mov ecx, [ecx+APPDATA.pl0_stack] - mov [ecx+REG_EIP], eax - -; } End patch by Coldy, For DLL autoload -.cleanup: - stdcall free_kernel_space, [ebp+APP_HDR.img_base] - stdcall kernel_free, ebp - mov ebx, [current_slot] - cmp [ebx+APPDATA.debugger_slot], 0 - je .exit - mov eax, [TASK_BASE] - mov [eax+TASKDATA.state], TSTATE_RUN_SUSPENDED - call change_task -.exit: - popad - iretd - -EFL_IF = 0x0200 -EFL_IOPL1 = 0x1000 -EFL_IOPL2 = 0x2000 -EFL_IOPL3 = 0x3000 - -align 4 -proc set_app_params stdcall,slot:dword, params:dword, flags:dword - - locals - pl0_stack dd ? - endl - - mov eax, [xsave_area_size] - add eax, RING0_STACK_SIZE - stdcall kernel_alloc, eax - mov [pl0_stack], eax - - lea edi, [eax+RING0_STACK_SIZE] - - mov eax, [slot] - mov ebx, eax - - shl eax, 8 - mov [eax+SLOT_BASE+APPDATA.fpu_state], edi - mov [eax+SLOT_BASE+APPDATA.exc_handler], 0 - mov [eax+SLOT_BASE+APPDATA.except_mask], 0 - mov [eax+SLOT_BASE+APPDATA.terminate_protection], 80000001h - -;set default io permission map - mov ecx, [SLOT_BASE+sizeof.APPDATA+APPDATA.io_map] - mov [eax+SLOT_BASE+APPDATA.io_map], ecx - mov ecx, [SLOT_BASE+sizeof.APPDATA+APPDATA.io_map+4] - mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx - - mov esi, fpu_data - mov ecx, [xsave_area_size] - add ecx, 3 - shr ecx, 2 - rep movsd - - cmp [thread_count], ebx - adc [thread_count], 0 ; update number of processes - shl ebx, 8 - lea edx, [ebx+SLOT_BASE+APP_EV_OFFSET] - mov [SLOT_BASE+APPDATA.fd_ev+ebx], edx - mov [SLOT_BASE+APPDATA.bk_ev+ebx], edx - - add edx, APP_OBJ_OFFSET-APP_EV_OFFSET - mov [SLOT_BASE+APPDATA.fd_obj+ebx], edx - mov [SLOT_BASE+APPDATA.bk_obj+ebx], edx - - mov ecx, [def_cursor] - mov [SLOT_BASE+APPDATA.cursor+ebx], ecx - mov eax, [pl0_stack] - mov [SLOT_BASE+APPDATA.pl0_stack+ebx], eax - add eax, RING0_STACK_SIZE - mov [SLOT_BASE+APPDATA.saved_esp0+ebx], eax - - push ebx - stdcall kernel_alloc, maxPathLength - pop ebx - mov esi, [current_slot] - mov esi, [esi+APPDATA.cur_dir] - mov ecx, maxPathLength/4 - mov edi, eax - mov [ebx+SLOT_BASE+APPDATA.cur_dir], eax - rep movsd - - shr ebx, 3 - mov dword [TASK_TABLE+ebx+TASKDATA.mem_start], 0 - - mov ebx, [slot] - mov eax, ebx - shl ebx, 5 - lea ecx, [draw_data+ebx];ecx - pointer to draw data - -; set window state to 'normal' (non-minimized/maximized/rolled-up) state - mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL - mov [ebx+window_data+WDATA.fl_redraw], 1 - add ebx, TASK_TABLE ;ebx - pointer to information about process - mov [ebx+TASKDATA.wnd_number], al;set window number on screen = process slot - - mov [ebx+TASKDATA.event_mask], dword 1+2+4;set default event flags (see 40 function) - - inc dword [process_number] - mov eax, [process_number] - mov [ebx+TASKDATA.pid], eax ;set PID - -;set draw data to full screen - xor eax, eax - mov [ecx+0], dword eax - mov [ecx+4], dword eax - mov eax, [screen_workarea.right] - mov [ecx+8], eax - mov eax, [screen_workarea.bottom] - mov [ecx+12], eax - - mov ebx, [pl0_stack] - mov esi, [params] - lea ecx, [ebx+REG_EIP] - xor eax, eax - - mov [ebx+REG_RET], dword common_app_entry - mov [ebx+REG_EDI], eax - mov [ebx+REG_ESI], eax - mov [ebx+REG_EBP], eax - mov [ebx+REG_ESP], ecx;ebx+REG_EIP - mov [ebx+REG_EBX], eax - mov [ebx+REG_EDX], eax - mov [ebx+REG_ECX], eax - mov [ebx+REG_EAX], eax - - mov eax, [esi+APP_HDR.eip] - mov [ebx+REG_EIP], eax - mov [ebx+REG_CS], dword app_code - mov ecx, USER_PRIORITY - - test byte [flags], 2 - jz @F - - mov [ebx+REG_CS], dword os_code ; kernel thread - mov ecx, MAX_PRIORITY -@@: - mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF - - mov eax, [esi+APP_HDR.esp] - mov [ebx+REG_APP_ESP], eax - mov [ebx+REG_SS], dword app_data - - lea edx, [ebx+REG_RET] - mov ebx, [slot] - shl ebx, 5 - mov [ebx*8+SLOT_BASE+APPDATA.saved_esp], edx - - xor edx, edx; process state - running -; set if debuggee - test byte [flags], 1 - jz .no_debug - mov eax, [current_slot_idx] - mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot], eax -.no_debug: - mov [TASK_TABLE+ebx+TASKDATA.state], dl - lea edx, [SLOT_BASE+ebx*8] - call scheduler_add_thread - ret -endp - -align 4 -get_stack_base: - mov eax, [current_slot] - mov eax, [eax+APPDATA.pl0_stack] - ret - - -include "debug.inc" diff --git a/kernel/branches/Kolibri-F/core/test_malloc.asm b/kernel/branches/Kolibri-F/core/test_malloc.asm deleted file mode 100644 index ac42df8c7..000000000 --- a/kernel/branches/Kolibri-F/core/test_malloc.asm +++ /dev/null @@ -1,250 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2009-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; Tests of malloc()/free() from the kernel heap. -; This file is not included in the kernel, it is just test application. -use32 - db 'MENUET01' - dd 1, start, i_end, mem, mem, 0, 0 - -start: -; Zero-initialize uglobals (as in kernel at boot) - mov ecx, (zeroend - zerostart + 3) / 4 - xor eax, eax - mov edi, zerostart - rep stosd -; Initialize small heap (as in kernel at boot) - call init_malloc -; Run tests - call run_test1 - call run_test2 - call run_test3 -; All is OK, return - or eax, -1 - int 0x40 - -run_test1: -; basic test - mov eax, 1 - call malloc_with_test - mov byte [eax], 0xDD - mov esi, eax - mov eax, 1 - call malloc_with_test - cmp byte [esi], 0xDD - jnz memory_destroyed - mov byte [eax], 0xEE - xchg eax, esi - call free - cmp byte [esi], 0xEE - jnz memory_destroyed - xchg eax, esi - call free - ret - -run_test2: - ret - -run_test3: -; 1024 times run random operation. -; Randomly select malloc(random size from 1 to 1023) -; or free(random of previously allocated areas) - mov edi, 0x12345678 - xor esi, esi ; 0 areas allocated - mov ebx, 1024 -.loop: - imul edi, 1103515245 - add edi, 12345 - mov eax, edi - shr eax, 16 - test ebx, 64 - jz .prefer_free -.prefer_malloc: - test eax, 3 - jz .free - jmp @f -.prefer_free: - test eax, 3 - jnz .free -@@: - shr eax, 2 - and eax, 1023 - jz .loop - push ebx - push eax -; mov ecx, [saved_state_num] -; mov [saved_state+ecx*8], eax - push edi - call malloc_with_test - pop ecx - cmp ecx, edi - jnz edi_destroyed -; mov ecx, [saved_state_num] -; mov [saved_state+ecx*8+4], eax -; inc [saved_state_num] - pop ecx - pop ebx - inc esi - push ecx eax - push edi - mov edi, eax - mov eax, esi - rep stosb - pop edi - jmp .common -.free: - test esi, esi - jz .loop - xor edx, edx - div esi - sub edx, esi - neg edx - dec edx - mov eax, [esp+edx*8] -; mov ecx, [saved_state_num] -; mov [saved_state+ecx*8], -1 -; mov [saved_state+ecx*8+4], eax -; inc [saved_state_num] - mov ecx, [esp+edx*8+4] - push edi eax - mov edi, eax - mov al, [edi] - repz scasb - jnz memory_destroyed - pop eax edi - push ebx edx - push edi - call free - pop ecx - cmp ecx, edi - jnz edi_destroyed - pop edx ebx - dec esi - pop eax ecx - push edi - lea edi, [esp+4] -@@: - dec edx - js @f - xchg eax, [edi] - xchg ecx, [edi+4] - add edi, 8 - jmp @b -@@: - pop edi -.common: - dec ebx - jnz .loop -@@: - dec esi - js @f - pop eax ecx - call free - jmp @b -@@: - ret - -malloc_with_test: -; calls malloc() and checks returned value - call malloc - test eax, eax - jz generic_malloc_fail - call check_mutex - call check_range - ret - -; Stubs for kernel procedures used by heap code -mutex_init: - and dword [ecx], 0 - ret -mutex_lock: - inc dword [ecx] - ret -mutex_unlock: - dec dword [ecx] - ret - -kernel_alloc: - cmp dword [esp+4], bufsize - jnz error1 - mov eax, buffer - ret 4 - -macro $Revision [args] -{ -} - -; Error handlers -error1: - mov eax, 1 - jmp error_with_code - -generic_malloc_fail: - mov eax, 2 - jmp error_with_code - -check_mutex: - cmp dword [mst.mutex], 0 - jnz @f - ret -@@: - mov eax, 3 - jmp error_with_code - -check_range: - cmp eax, buffer - jb @f - cmp eax, buffer+bufsize - jae @f - ret -@@: - mov eax, 4 - jmp error_with_code - -memory_destroyed: - mov eax, 5 - jmp error_with_code - -edi_destroyed: - mov eax, 6 - jmp error_with_code - -error_with_code: - mov edx, saved_state_num -; eax = error code -; 1 signals error in testing code (wrong bufsize) -; 2 = malloc() returned NULL -; 3 = mutex not released -; 4 = weird returned value from malloc() -; 5 = memory destroyed by malloc() or free() - int3 ; simplest way to report error - jmp $-1 ; just in case - -; Include main heap code -include '../macros.inc' -include '../proc32.inc' -include '../struct.inc' -include '../const.inc' -include 'malloc.inc' - -i_end: - -align 4 -zerostart: -mst MEM_STATE - -align 16 -bufsize = 0x40000 ; change if malloc.inc changes -buffer rb bufsize -zeroend: - -saved_state_num dd ? -saved_state rd 0x10000 - -align 4 - rb 0x10000 ; for stack -mem: diff --git a/kernel/branches/Kolibri-F/core/timers.inc b/kernel/branches/Kolibri-F/core/timers.inc deleted file mode 100644 index 91e1e7ed4..000000000 --- a/kernel/branches/Kolibri-F/core/timers.inc +++ /dev/null @@ -1,229 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2012-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; Simple implementation of timers. All timers are organized in a double-linked -; list, and the OS loop after every timer tick processes the list. - -; This structure describes a timer for the kernel. -struct TIMER - Next dd ? - Prev dd ? -; These fields organize a double-linked list of all timers. - TimerFunc dd ? -; Function to be called when the timer is activated. - UserData dd ? -; The value that is passed as is to .TimerFunc. - Time dd ? -; Time at which the timer should be activated. - Interval dd ? -; Interval between activations of the timer, in 0.01s. -ends - -iglobal -align 4 -; The head of timer list. -timer_list: - dd timer_list - dd timer_list -endg -uglobal -; These two variables are used to synchronize access to the global list. -; Logically, they form an recursive mutex. Physically, the first variable holds -; the slot number of the current owner or 0, the second variable holds the -; recursion count. -; The mutex should be recursive to allow a timer function to add/delete other -; timers or itself. -timer_list_owner dd 0 -timer_list_numlocks dd 0 -; A timer function can delete any timer, including itself and the next timer in -; the chain. To handle such situation correctly, we keep the next timer in a -; global variable, so the removing operation can update it. -timer_next dd 0 -endg - -; This internal function acquires the lock for the global list. -lock_timer_list: - mov edx, [current_slot_idx] -@@: - xor eax, eax - lock cmpxchg [timer_list_owner], edx - jz @f - cmp eax, edx - jz @f - call change_task - jmp @b -@@: - inc [timer_list_numlocks] - ret - -; This internal function releases the lock for the global list. -unlock_timer_list: - dec [timer_list_numlocks] - jnz .nothing - mov [timer_list_owner], 0 -.nothing: - ret - -; This function adds a timer. -; If deltaStart is nonzero, the timer is activated after deltaStart hundredths -; of seconds starting from the current time. If interval is nonzero, the timer -; is activated every deltaWork hundredths of seconds starting from the first -; activation. The activated timer calls timerFunc as stdcall function with one -; argument userData. -; Return value is NULL if something has failed or some value which is opaque -; for the caller. Later this value can be used for cancel_timer_hs. -proc timer_hs stdcall uses ebx, deltaStart:dword, interval:dword, \ - timerFunc:dword, userData:dword -; 1. Allocate memory for the TIMER structure. -; 1a. Call the allocator. - movi eax, sizeof.TIMER - call malloc -; 1b. If allocation failed, return (go to 5) with eax = 0. - test eax, eax - jz .nothing -; 2. Setup the TIMER structure. - xchg ebx, eax -; 2a. Copy values from the arguments. - mov ecx, [interval] - mov [ebx+TIMER.Interval], ecx - mov ecx, [timerFunc] - mov [ebx+TIMER.TimerFunc], ecx - mov ecx, [userData] - mov [ebx+TIMER.UserData], ecx -; 2b. Get time of the next activation. - mov ecx, [deltaStart] - test ecx, ecx - jnz @f - mov ecx, [interval] -@@: - add ecx, [timer_ticks] - mov [ebx+TIMER.Time], ecx -; 3. Insert the TIMER structure to the global list. -; 3a. Acquire the lock. - call lock_timer_list -; 3b. Insert an item at ebx to the tail of the timer_list. - mov eax, timer_list - mov ecx, [eax+TIMER.Prev] - mov [ebx+TIMER.Next], eax - mov [ebx+TIMER.Prev], ecx - mov [eax+TIMER.Prev], ebx - mov [ecx+TIMER.Next], ebx -; 3c. Release the lock. - call unlock_timer_list -; 4. Return with eax = pointer to TIMER structure. - xchg ebx, eax -.nothing: -; 5. Returning. - ret -endp - -; This function removes a timer. -; The only argument is [esp+4] = the value which was returned from timer_hs. -cancel_timer_hs: - push ebx ; save used register to be stdcall -; 1. Remove the TIMER structure from the global list. -; 1a. Acquire the lock. - call lock_timer_list - mov ebx, [esp+4+4] -; 1b. Delete an item at ebx from the double-linked list. - mov eax, [ebx+TIMER.Next] - mov ecx, [ebx+TIMER.Prev] - mov [eax+TIMER.Prev], ecx - mov [ecx+TIMER.Next], eax -; 1c. If we are removing the next timer in currently processing chain, -; the next timer for this timer becomes new next timer. - cmp ebx, [timer_next] - jnz @f - mov [timer_next], eax -@@: -; 1d. Release the lock. - call unlock_timer_list -; 2. Free the TIMER structure. - xchg eax, ebx - call free -; 3. Return. - pop ebx ; restore used register to be stdcall - ret 4 ; purge one dword argument to be stdcall - -; This function is regularly called from osloop. It processes the global list -; and activates the corresponding timers. -check_timers: -; 1. Acquire the lock. - call lock_timer_list -; 2. Loop over all registered timers, checking time. -; 2a. Get the first item. - mov eax, [timer_list+TIMER.Next] - mov [timer_next], eax -.loop: -; 2b. Check for end of list. - cmp eax, timer_list - jz .done -; 2c. Get and store the next timer. - mov edx, [eax+TIMER.Next] - mov [timer_next], edx -; 2d. Check time for timer activation. -; We can't just compare [timer_ticks] and [TIMER.Time], since overflows are -; possible: if the current time is 0FFFFFFFFh ticks and timer should be -; activated in 3 ticks, the simple comparison will produce incorrect result. -; So we calculate the difference [timer_ticks] - [TIMER.Time]; if it is -; non-negative, the time is over; if it is negative, then either the time is -; not over or we have not processed this timer for 2^31 ticks, what is very -; unlikely. - mov edx, [timer_ticks] - sub edx, [eax+TIMER.Time] - js .next -; The timer should be activated now. -; 2e. Store the timer data in the stack. This is required since 2f can delete -; the timer, invalidating the content. - push [eax+TIMER.UserData] ; parameter for TimerFunc - push [eax+TIMER.TimerFunc] ; to be restored in 2g -; 2f. Calculate time of next activation or delete the timer if it is one-shot. - mov ecx, [eax+TIMER.Interval] - add [eax+TIMER.Time], ecx - test ecx, ecx - jnz .nodelete - stdcall cancel_timer_hs, eax -.nodelete: -; 2g. Activate timer, using data from the stack. - pop eax - call eax -.next: -; 2h. Advance to the next timer and continue the loop. - mov eax, [timer_next] - jmp .loop -.done: -; 3. Release the lock. - call unlock_timer_list -; 4. Return. - ret - -; This is a simplified version of check_timers that does not call anything, -; just checks whether check_timers should do something. -proc check_timers_has_work? - pushf - cli - mov eax, [timer_list+TIMER.Next] -.loop: - cmp eax, timer_list - jz .done_nowork - mov edx, [timer_ticks] - sub edx, [eax+TIMER.Time] - jns .done_haswork - mov eax, [eax+TIMER.Next] - jmp .loop -.done_nowork: - popf - xor eax, eax - ret -.done_haswork: - popf - xor eax, eax - inc eax - ret -endp diff --git a/kernel/branches/Kolibri-F/core/v86.inc b/kernel/branches/Kolibri-F/core/v86.inc deleted file mode 100644 index 97cf3bee3..000000000 --- a/kernel/branches/Kolibri-F/core/v86.inc +++ /dev/null @@ -1,907 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2007-2021. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; Virtual-8086 mode manager -; diamond, 2007, 2008 - -DEBUG_SHOW_IO = 0 - -struct V86_machine -; page directory - process dd ? -; mutex to protect all data from writing by multiple threads at one time - mutex dd ? -; i/o permission map - iopm dd ? -ends - -; Create V86 machine -; in: nothing -; out: eax = handle (pointer to struc V86_machine) -; eax = NULL => failure -; destroys: ebx, ecx, edx (due to malloc) -v86_create: -; allocate V86_machine structure - mov eax, sizeof.V86_machine - call malloc - test eax, eax - jz .fail -; initialize mutex - and dword [eax+V86_machine.mutex], 0 -; allocate tables - mov ebx, eax - - stdcall create_process, 4096 - test eax, eax - jz .fail2 - - mov [eax+PROC.mem_used], 4096 - mov [ebx+V86_machine.process], eax - - push 2000h - call kernel_alloc - test eax, eax - jz .fail2 - - mov [ebx+V86_machine.iopm], eax - -; initialize tables - push edi - mov edi, eax - mov eax, -1 - mov ecx, 2000h/4 - rep stosd - - mov eax, [ebx+V86_machine.process] - mov eax, [eax+PROC.pdt_0_phys] - - pushfd - cli - mov cr3, eax - -; now V86 specific: initialize known addresses in first Mb - -; first page - BIOS data (shared between all machines!) -; physical address = 0 -; linear address = OS_BASE -; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!) -; physical address = 0x9C000 -; linear address = 0x8009C000 -; (I have seen one computer with EBDA segment = 0x9D80, -; all other computers use less memory) - - mov eax, PG_UWR - mov [page_tabs], eax - invlpg [eax] - - mov byte [0x500], 0xCD - mov byte [0x501], 0x13 - mov byte [0x502], 0xF4 - mov byte [0x503], 0xCD - mov byte [0x504], 0x10 - mov byte [0x505], 0xF4 - - mov eax, 0x98000+PG_UWR - mov edi, page_tabs+0x98*4 - mov edx, 0x1000 - mov ecx, 8 -@@: - stosd - add eax, edx - loop @b - -; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!) -; physical address = 0xC0000 - - mov eax, 0xC0000+PG_UWR - mov edi, page_tabs+0xC0*4 - mov ecx, 64 -@@: - stosd - add eax, edx - loop @b - - mov eax, [sys_proc+PROC.pdt_0_phys] - mov cr3, eax - popfd - - pop edi - - mov eax, ebx - ret -.fail2: - mov eax, ebx - call free -.fail: - xor eax, eax - ret - -;not used -; Destroy V86 machine -; in: eax = handle -; out: nothing -; destroys: eax, ebx, ecx, edx (due to free) -;v86_destroy: -; push eax -; stdcall kernel_free, [eax+V86_machine.pagedir] -; pop eax -; jmp free - -; Translate V86-address to linear address -; in: eax=V86 address -; esi=handle -; out: eax=linear address -; destroys: nothing -v86_get_lin_addr: - push ecx edx - mov ecx, eax - shr ecx, 12 - mov edx, [page_tabs+ecx*4] - and eax, 0xFFF - and edx, 0xFFFFF000 - or eax, edx - pop edx ecx - ret - -;not used -; Sets linear address for V86-page -; in: eax=linear address (must be page-aligned) -; ecx=V86 page (NOT address!) -; esi=handle -; out: nothing -; destroys: nothing -;v86_set_page: -; push eax ebx -; mov ebx, [esi+V86_machine.pagedir] -; mov [ebx+ecx*4+0x1800], eax -; call get_pg_addr -; or al, 111b -; mov [ebx+ecx*4+0x1000], eax -; pop ebx eax -; ret - -; Allocate memory in V86 machine -; in: eax=size (in bytes) -; esi=handle -; out: eax=V86 address, para-aligned (0x10 multiple) -; destroys: nothing -; недописана!!! -;v86_alloc: -; push ebx ecx edx edi -; lea ebx, [esi+V86_machine.mutex] -; call wait_mutex -; add eax, 0x1F -; shr eax, 4 -; mov ebx, 0x1000 ; start with address 0x1000 (second page) -; mov edi, [esi+V86_machine.tables] -;.l: -; mov ecx, ebx -; shr ecx, 12 -; mov edx, [edi+0x1000+ecx*4] ; get linear address -; test edx, edx ; page allocated? -; jz .unalloc -; mov ecx, ebx -; and ecx, 0xFFF -; add edx, ecx -; cmp dword [edx], 0 ; free block? -; jnz .n -; cmp dword [edx+4], -; and [esi+V86_machine.mutex], 0 -; pop edi edx ecx ebx -; ret - -uglobal -sys_v86_machine dd ? -endg - -; Called from kernel.asm at first stages of loading -; Initialize system V86 machine (used to simulate BIOS int 13h) -init_sys_v86: - call v86_create - mov [sys_v86_machine], eax - test eax, eax - jz .ret - mov esi, eax -if ~DEBUG_SHOW_IO -; allow access to all ports - mov ecx, [esi+V86_machine.iopm] - xor eax, eax - mov edi, ecx - mov ecx, 10000h/8/4 - rep stosd -end if -.ret: - ret - -struct v86_regs -; don't change the order, it is important - edi dd ? - esi dd ? - ebp dd ? - dd ? ; ignored - ebx dd ? - edx dd ? - ecx dd ? - eax dd ? - eip dd ? - cs dd ? - eflags dd ? ; VM flag must be set! - esp dd ? - ss dd ? - es dd ? - ds dd ? - fs dd ? - gs dd ? -ends - -; Run V86 machine -; in: ebx -> registers for V86 (two structures: in and out) -; esi = handle -; ecx = expected end address (CS:IP) -; edx = IRQ to hook or -1 if not required -; out: structure pointed to by ebx is filled with new values -; eax = 1 - exception has occured, cl contains code -; eax = 2 - access to disabled i/o port, ecx contains port address -; eax = 3 - IRQ is already hooked by another VM -; destroys: nothing -v86_start: - - pushad - - cli - - mov ecx, [current_slot] - - push dword [ecx+APPDATA.io_map] - push dword [ecx+APPDATA.io_map+4] - push [ecx+APPDATA.process] - push [ecx+APPDATA.saved_esp0] - mov [ecx+APPDATA.saved_esp0], esp - mov [tss._esp0], esp - - mov eax, [esi+V86_machine.iopm] - call get_pg_addr - inc eax - mov dword [ecx+APPDATA.io_map], eax - mov dword [page_tabs + (tss._io_map_0 shr 10)], eax - - mov eax, [esi+V86_machine.iopm] - add eax, 0x1000 - call get_pg_addr - inc eax - mov dword [ecx+APPDATA.io_map+4], eax - mov dword [page_tabs + (tss._io_map_1 shr 10)], eax - - mov eax, [esi+V86_machine.process] - mov [ecx+APPDATA.process], eax - mov [current_process], eax - mov eax, [eax+PROC.pdt_0_phys] - mov cr3, eax - -; We do not enable interrupts, because V86 IRQ redirector assumes that -; machine is running -; They will be enabled by IRET. -; sti - - mov eax, esi - sub esp, sizeof.v86_regs - mov esi, ebx - mov edi, esp - mov ecx, sizeof.v86_regs/4 - rep movsd - - cmp edx, -1 - jz .noirqhook -uglobal -v86_irqhooks rd IRQ_RESERVED * 2 -endg - cmp [v86_irqhooks+edx*8], 0 - jz @f - cmp [v86_irqhooks+edx*8], eax - jz @f - mov esi, v86_irqerr - call sys_msg_board_str - inc [v86_irqhooks+edx*8+4] - mov eax, 3 - jmp v86_exc_c.exit -@@: - mov [v86_irqhooks+edx*8], eax - inc [v86_irqhooks+edx*8+4] -.noirqhook: - - popad - iretd - -; It is only possible to leave virtual-8086 mode by faulting to -; a protected-mode interrupt handler (typically the general-protection -; exception handler, which in turn calls the virtual 8086-mode monitor). - -iglobal - v86_exc_str1 db 'V86 : unexpected exception ',0 - v86_exc_str2 db ' at ',0 - v86_exc_str3 db ':',0 - v86_exc_str4 db 13,10,'V86 : faulted code:',0 - v86_exc_str5 db ' (unavailable)',0 - v86_newline db 13,10,0 - v86_io_str1 db 'V86 : access to disabled i/o port ',0 - v86_io_byte db ' (byte)',13,10,0 - v86_io_word db ' (word)',13,10,0 - v86_io_dword db ' (dword)',13,10,0 - v86_irqerr db 'V86 : IRQ already hooked',13,10,0 -endg - -v86_exc_c: -; Did we all that we have wanted to do? - cmp bl, 1 - jne @f - xor eax, eax - mov dr6, eax - @@: - mov eax, [esp+sizeof.v86_regs+10h+18h] - cmp word [esp+v86_regs.eip], ax - jnz @f - shr eax, 16 - cmp word [esp+v86_regs.cs], ax - jz .done -@@: -; Various system events, which must be handled, result in #GP - cmp bl, 13 - jnz .nogp -; If faulted EIP exceeds 0xFFFF, we have #GP and it is an error - cmp word [esp+v86_regs.eip+2], 0 - jnz .nogp -; Otherwise we can safely access byte at CS:IP -; (because it is #GP, not #PF handler) -; If we could get an exception just because of reading code bytes, -; we would have got it already and it wouldn't be #GP - movzx esi, word [esp+v86_regs.cs] - shl esi, 4 - add esi, [esp+v86_regs.eip] - lodsb - cmp al, 0xCD ; int xx command = CD xx - jz .handle_int - cmp al, 0xCF - jz .handle_iret - cmp al, 0xF3 - jz .handle_rep - cmp al, 0xEC - jz .handle_in - cmp al, 0xED - jz .handle_in_word - cmp al, 0xEE - jz .handle_out - cmp al, 0xEF - jz .handle_out_word - cmp al, 0xE4 - jz .handle_in_imm - cmp al, 0xE6 - jz .handle_out_imm - cmp al, 0x9C - jz .handle_pushf - cmp al, 0x9D - jz .handle_popf - cmp al, 0xFA - jz .handle_cli - cmp al, 0xFB - jz .handle_sti - cmp al, 0x66 - jz .handle_66 - jmp .nogp -.handle_int: - cmp word [esp+v86_regs.eip], 0xFFFF - jae .nogp - xor eax, eax - lodsb -; call sys_msg_board_byte -; simulate INT command -; N.B. It is possible that some checks need to be corrected, -; but at least in case of normal execution the code works. -.simulate_int: - cmp word [esp+v86_regs.esp], 6 - jae @f - mov bl, 12 ; #SS exception - jmp .nogp -@@: - movzx edx, word [esp+v86_regs.ss] - shl edx, 4 - push eax - movzx eax, word [esp+4+v86_regs.esp] - sub eax, 6 - add edx, eax - mov eax, edx - mov esi, [esp+4+sizeof.v86_regs+10h+4] - call v86_get_lin_addr - cmp eax, 0x1000 - jae @f - mov bl, 14 ; #PF exception - jmp .nogp -@@: - lea eax, [edx+5] - call v86_get_lin_addr - cmp eax, 0x1000 - jae @f - mov bl, 14 ; #PF exception - jmp .nogp -@@: - sub word [esp+4+v86_regs.esp], 6 - mov eax, [esp+4+v86_regs.eip] - cmp byte [esp+1], 0 - jnz @f - inc eax - inc eax -@@: - mov word [edx], ax - mov eax, [esp+4+v86_regs.cs] - mov word [edx+2], ax - mov eax, [esp+4+v86_regs.eflags] - mov word [edx+4], ax - pop eax - mov ah, 0 - mov cx, [eax*4] - mov word [esp+v86_regs.eip], cx - mov cx, [eax*4+2] - mov word [esp+v86_regs.cs], cx -; note that interrupts will be disabled globally at IRET - and byte [esp+v86_regs.eflags+1], not 3 ; clear IF and TF flags -; continue V86 execution - popad - iretd -.handle_iret: - cmp word [esp+v86_regs.esp], 0x10000 - 6 - jbe @f - mov bl, 12 - jmp .nogp -@@: - movzx edx, word [esp+v86_regs.ss] - shl edx, 4 - movzx eax, word [esp+v86_regs.esp] - add edx, eax - mov eax, edx - mov esi, [esp+sizeof.v86_regs+10h+4] - call v86_get_lin_addr - cmp eax, 0x1000 - jae @f - mov bl, 14 - jmp .nogp -@@: - lea eax, [edx+5] - call v86_get_lin_addr - cmp eax, 0x1000 - jae @f - mov bl, 14 - jmp .nogp -@@: - mov ax, [edx] - mov word [esp+v86_regs.eip], ax - mov ax, [edx+2] - mov word [esp+v86_regs.cs], ax - mov ax, [edx+4] - mov word [esp+v86_regs.eflags], ax - add word [esp+v86_regs.esp], 6 - popad - iretd -.handle_pushf: - cmp word [esp+v86_regs.esp], 1 - jnz @f - mov bl, 12 - jmp .nogp -@@: - movzx edx, word [esp+v86_regs.ss] - shl edx, 4 - mov eax, [esp+v86_regs.esp] - sub eax, 2 - movzx eax, ax - add edx, eax - mov eax, edx - mov esi, [esp+sizeof.v86_regs+10h+4] - call v86_get_lin_addr - cmp eax, 0x1000 - jae @f - mov bl, 14 ; #PF exception - jmp .nogp -@@: - lea eax, [edx+1] - call v86_get_lin_addr - cmp eax, 0x1000 - jae @f - mov bl, 14 - jmp .nogp -@@: - sub word [esp+v86_regs.esp], 2 - mov eax, [esp+v86_regs.eflags] - mov [edx], ax - inc word [esp+v86_regs.eip] - popad - iretd -.handle_pushfd: - cmp word [esp+v86_regs.esp], 4 - jae @f - mov bl, 12 ; #SS exception - jmp .nogp -@@: - movzx edx, word [esp+v86_regs.ss] - shl edx, 4 - movzx eax, word [esp+v86_regs.esp] - sub eax, 4 - add edx, eax - mov eax, edx - mov esi, [esp+sizeof.v86_regs+10h+4] - call v86_get_lin_addr - cmp eax, 0x1000 - jae @f - mov bl, 14 ; #PF exception - jmp .nogp -@@: - lea eax, [edx+3] - call v86_get_lin_addr - cmp eax, 0x1000 - jae @f - mov bl, 14 ; #PF exception - jmp .nogp -@@: - sub word [esp+v86_regs.esp], 4 - movzx eax, word [esp+v86_regs.eflags] - mov [edx], eax - add word [esp+v86_regs.eip], 2 - popad - iretd -.handle_popf: - cmp word [esp+v86_regs.esp], 0xFFFF - jnz @f - mov bl, 12 - jmp .nogp -@@: - movzx edx, word [esp+v86_regs.ss] - shl edx, 4 - movzx eax, word [esp+v86_regs.esp] - add edx, eax - mov eax, edx - mov esi, [esp+sizeof.v86_regs+10h+4] - call v86_get_lin_addr - cmp eax, 0x1000 - jae @f - mov bl, 14 ; #PF exception - jmp .nogp -@@: - lea eax, [edx+1] - call v86_get_lin_addr - cmp eax, 0x1000 - jae @f - mov bl, 14 - jmp .nogp -@@: - mov ax, [edx] - mov word [esp+v86_regs.eflags], ax - add word [esp+v86_regs.esp], 2 - inc word [esp+v86_regs.eip] - popad - iretd -.handle_popfd: - cmp word [esp+v86_regs.esp], 0x10000 - 4 - jbe @f - mov bl, 12 - jmp .nogp -@@: - movzx edx, word [esp+v86_regs.ss] - shl edx, 4 - movzx eax, word [esp+v86_regs.esp] - add edx, eax - mov eax, edx - mov esi, [esp+sizeof.v86_regs+10h+4] - call v86_get_lin_addr - cmp eax, 0x1000 - jae @f - mov bl, 14 - jmp .nogp -@@: - lea eax, [edx+3] - call v86_get_lin_addr - cmp eax, 0x1000 - jae @f - mov bl, 14 - jmp .nogp -@@: - mov eax, [edx] - mov word [esp+v86_regs.eflags], ax - add word [esp+v86_regs.esp], 4 - add word [esp+v86_regs.eip], 2 - popad - iretd -.handle_cli: - and byte [esp+v86_regs.eflags+1], not 2 - inc word [esp+v86_regs.eip] - popad - iretd -.handle_sti: - or byte [esp+v86_regs.eflags+1], 2 - inc word [esp+v86_regs.eip] - popad - iretd -.handle_rep: - cmp word [esp+v86_regs.eip], 0xFFFF - jae .nogp - lodsb - cmp al, 6Eh - jz .handle_rep_outsb - jmp .nogp -.handle_rep_outsb: -.handle_in: -.handle_out: -.invalid_io_byte: - movzx ebx, word [esp+v86_regs.edx] - mov ecx, 1 - jmp .invalid_io -.handle_in_imm: -.handle_out_imm: - cmp word [esp+v86_regs.eip], 0xFFFF - jae .nogp - lodsb - movzx ebx, al - mov ecx, 1 - jmp .invalid_io -.handle_66: - cmp word [esp+v86_regs.eip], 0xFFFF - jae .nogp - lodsb - cmp al, 0x9C - jz .handle_pushfd - cmp al, 0x9D - jz .handle_popfd - cmp al, 0xEF - jz .handle_out_dword - cmp al, 0xED - jz .handle_in_dword - jmp .nogp -.handle_in_word: -.handle_out_word: - movzx ebx, word [esp+v86_regs.edx] - mov ecx, 2 - jmp .invalid_io -.handle_in_dword: -.handle_out_dword: -.invalid_io_dword: - movzx ebx, word [esp+v86_regs.edx] - mov ecx, 4 -.invalid_io: - mov esi, v86_io_str1 - call sys_msg_board_str - mov eax, ebx - call sys_msg_board_dword - mov esi, v86_io_byte - cmp ecx, 1 - jz @f - mov esi, v86_io_word - cmp ecx, 2 - jz @f - mov esi, v86_io_dword -@@: - call sys_msg_board_str -if DEBUG_SHOW_IO - mov edx, ebx - mov ebx, 200 - call sys_delay_hs - mov esi, [esp+v86_regs.size+10h+4] - mov eax, [esi+V86_machine.iopm] -@@: - btr [eax], edx - inc edx - loop @b - popad - iretd -else - mov eax, 2 - jmp .exit -end if -.nogp: - - mov esi, v86_exc_str1 - call sys_msg_board_str - mov al, bl - call sys_msg_board_byte - mov esi, v86_exc_str2 - call sys_msg_board_str - mov ax, [esp+32+4] - call sys_msg_board_word - mov esi, v86_exc_str3 - call sys_msg_board_str - mov ax, [esp+32] - call sys_msg_board_word - mov esi, v86_exc_str4 - call sys_msg_board_str - mov ecx, 8 - movzx edx, word [esp+32+4] - shl edx, 4 - add edx, [esp+32] -@@: - mov esi, [esp+sizeof.v86_regs+10h+4] - mov eax, edx - call v86_get_lin_addr - cmp eax, 0x1000 - jb .nopage - mov esi, v86_exc_str3-2 - call sys_msg_board_str - mov al, [edx] - call sys_msg_board_byte - inc edx - loop @b - jmp @f -.nopage: - mov esi, v86_exc_str5 - call sys_msg_board_str -@@: - mov esi, v86_newline - call sys_msg_board_str - mov eax, 1 - jmp .exit - -.done: - xor eax, eax - -.exit: - mov [esp+sizeof.v86_regs+10h+1Ch], eax - mov [esp+sizeof.v86_regs+10h+18h], ebx - - mov edx, [esp+sizeof.v86_regs+10h+14h] - cmp edx, -1 - jz @f - dec [v86_irqhooks+edx*8+4] - jnz @f - and [v86_irqhooks+edx*8], 0 -@@: - - mov esi, esp - mov edi, [esi+sizeof.v86_regs+10h+10h] - add edi, sizeof.v86_regs - mov ecx, sizeof.v86_regs/4 - rep movsd - mov esp, esi - - cli - mov ecx, [current_slot] - pop eax - - mov [ecx+APPDATA.saved_esp0], eax - mov [tss._esp0], eax - pop eax - mov [ecx+APPDATA.process], eax - mov [current_process], eax - pop ebx - mov dword [ecx+APPDATA.io_map+4], ebx - mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx - pop ebx - mov dword [ecx+APPDATA.io_map], ebx - mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx - mov eax, [eax+PROC.pdt_0_phys] - mov cr3, eax - sti - - popad - ret - -;my05: -; mov dx, 30C2h -; mov cx, 4 -;.0: -; in al, dx -; cmp al, 0FFh -; jz @f -; test al, 4 -; jnz .1 -;@@: -; add dx, 8 -; in al, dx -; cmp al, 0FFh -; jz @f -; test al, 4 -; jnz .1 -;@@: -; loop .0 -; ret -;.1: -; or al, 84h -; out dx, al -;.2: -; mov dx, 30F7h -; in al, dx -; mov byte [BOOT_VAR + 48Eh], 0FFh -; ret - -align 4 -v86_irq: -; push irq/pushad/jmp v86_irq -; ebp = irq - lea esi, [esp+1Ch] - lea edi, [esi+4] - mov ecx, 8 - std - rep movsd - cld - mov edi, ebp - pop eax -v86_irq2: - mov esi, [v86_irqhooks+edi*8] ; get VM handle - mov eax, [esi+V86_machine.process] - mov ecx, [current_slot_idx] - shl ecx, 8 - cmp [SLOT_BASE+ecx+APPDATA.process], eax - jnz .notcurrent - lea eax, [edi+8] - cmp al, 10h - mov ah, 1 - jb @f - add al, 60h -@@: - jmp v86_exc_c.simulate_int -.notcurrent: - mov ebx, SLOT_BASE + 0x100 - mov ecx, [thread_count] -.scan: - cmp [ebx+APPDATA.process], eax - jnz .cont - push ecx - mov ecx, [ebx+APPDATA.saved_esp0] - cmp word [ecx-sizeof.v86_regs+v86_regs.esp], 6 - jb .cont2 - movzx edx, word [ecx-sizeof.v86_regs+v86_regs.ss] - shl edx, 4 - push eax - movzx eax, word [ecx-sizeof.v86_regs+v86_regs.esp] - sub eax, 6 - add edx, eax - mov eax, edx - call v86_get_lin_addr - cmp eax, 0x1000 - jb .cont3 - lea eax, [edx+5] - call v86_get_lin_addr - cmp eax, 0x1000 - jb .cont3 - pop eax - pop ecx - jmp .found -.cont3: - pop eax -.cont2: - pop ecx -.cont: - add ebx, 0x100 - loop .scan - mov ecx, edi - call irq_eoi - popad - iretd -.found: - mov eax, [eax+PROC.pdt_0_phys] - mov cr3, eax - mov esi, [ebx+APPDATA.saved_esp0] - sub word [esi-sizeof.v86_regs+v86_regs.esp], 6 - mov ecx, [esi-sizeof.v86_regs+v86_regs.eip] - mov word [edx], cx - mov ecx, [esi-sizeof.v86_regs+v86_regs.cs] - mov word [edx+2], cx - mov ecx, [esi-sizeof.v86_regs+v86_regs.eflags] - mov word [edx+4], cx - lea eax, [edi+8] - cmp al, 10h - jb @f - add al, 60h -@@: - mov cx, [eax*4] - mov word [esi-sizeof.v86_regs+v86_regs.eip], cx - mov cx, [eax*4+2] - mov word [esi-sizeof.v86_regs+v86_regs.cs], cx - and byte [esi-sizeof.v86_regs+v86_regs.eflags+1], not 3 - call update_counters - lea edi, [ebx + 0x100000000 - SLOT_BASE] - shr edi, 3 - add edi, TASK_TABLE - call find_next_task.found - call do_change_task - popad - iretd diff --git a/kernel/branches/Kolibri-F/crc.inc b/kernel/branches/Kolibri-F/crc.inc deleted file mode 100644 index c84a1594e..000000000 --- a/kernel/branches/Kolibri-F/crc.inc +++ /dev/null @@ -1,42 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2017. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License. ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; This crc32 routine doesn't use precomputed table to allow different -; polynomials, which is the first param. -; Partial hash in assumed to be eax (both in and out). -; Usage: -; 1. mov eax, -1 -; 2. stdcall crypto.crc32 zero or more times -; 3. xor eax, -1 -proc crc_32 _poly, _buffer, _length - push ebx ecx edx esi - - mov esi, [_buffer] -.next_byte: - dec [_length] - js .done - movzx ebx, byte[esi] - inc esi - mov ecx, 8 -.next_bit: - mov edx, eax - xor edx, ebx - shr eax, 1 - test edx, 1 - jz @f - xor eax, [_poly] -@@: - shr ebx, 1 - dec ecx - jnz .next_bit - jmp .next_byte -.done: - pop esi edx ecx ebx - ret -endp diff --git a/kernel/branches/Kolibri-F/data16.inc b/kernel/branches/Kolibri-F/data16.inc deleted file mode 100644 index 79fbb2698..000000000 --- a/kernel/branches/Kolibri-F/data16.inc +++ /dev/null @@ -1,87 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -flm db 0 -preboot_lfb db 0 -preboot_bootlog db 0 -boot_drive db 0 - -align 4 -old_ints_h: - dw 0x400 - dd 0 - dw 0 - -if ~ defined extended_primary_loader ; restart from memory is not supported in extended primary loader cfg -kernel_restart_bootblock: - db 1 ; version - dw 1 ; floppy image is in memory - dd 0 ; cannot save parameters -end if - -; table for move to extended memory (int 15h, ah=87h) -align 8 -movedesc: - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - - db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 - db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 - - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - -fwmovedesc: - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - - db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 - db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 - - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - -if defined extended_primary_loader -; look in PrimaryLoader.txt for the description -bootdevice dw 0 ; ax from primary loader -bootfs dw 0 ; bx from primary loader -bootcallback dd 0 ; ds:si from primary loader -; data for configuration file loading, look in PrimaryLoader.txt -config_file_struct: - dw 0, 4000h ; load to 4000:0000 - dw 16 ; read no more than 16*4K = 64K - db 'config.ini',0 -; data for configuration file parsing -macro config_variable string,parser -{ -local len -len dw 0 - db string -store word $ - len - 2 at len - dw parser -} -config_file_variables: - config_variable 'timeout', parse_timeout - config_variable 'resolution', parse_resolution - config_variable 'vbemode', parse_vbemode - config_variable 'biosdisks', parse_biosdisks - config_variable 'imgfrom', parse_imgfrom - config_variable 'syspath', parse_syspath - dw 0 -; data for image file loading, look in PrimaryLoader.txt -image_file_struct: - dw 0, 4000h ; load to 4000:0000 - dw 16 ; read no more than 16*4K = 64K - db 'kolibri.img',0 -end if diff --git a/kernel/branches/Kolibri-F/data32.inc b/kernel/branches/Kolibri-F/data32.inc deleted file mode 100644 index fa3c514e1..000000000 --- a/kernel/branches/Kolibri-F/data32.inc +++ /dev/null @@ -1,559 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2021. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -keymap: - - db '6',27 - db '1234567890-=',8,9 - db 'qwertyuiop[]',13 - db '~asdfghjkl;',39,96,0,'\zxcvbnm,./',0,'45 ' - db '@234567890123',180,178,184,'6',176,'7' - db 179,'8',181,177,183,185,182 - db 'AB?',0,'45 ' - db '@234567890123',180,178,184,'6',176,'7' - db 179,'8',181,177,183,185,182 - db 'AB>D',255,'FGHIJKLMNOPQRSTUVWXYZ' - db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - - -keymap_alt: - db ' ',27 - db ' @ $ {[]}\ ',8,9 - db ' ',13 - db ' ',0,' ',0,'4',0,' ' - db ' ',180,178,184,'6',176,'7' - db 179,'8',181,177,183,185,182 - db 'ABCD',255,'FGHIJKLMNOPQRSTUVWXYZ' - db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - - - -if lang eq ru - boot_initirq cp866 'Инициализация IRQ',0 - boot_picinit cp866 'Инициализация PIC',0 - boot_v86machine cp866 'Инициализация системной V86 машины',0 - boot_inittimer cp866 'Инициализация системного таймера (IRQ0)',0 - boot_initapic cp866 'Попытка инициализации APIC',0 - boot_enableirq cp866 'Включить прерывания 2, 13',0 - boot_disabling_ide cp866 'Запрещение прерываний в контроллере IDE',0 - boot_enabling_ide cp866 'Разрешение прерываний в контроллере IDE',0 - boot_set_int_IDE cp866 'Установка обработчиков прерываний IDE',0 - boot_detectfloppy cp866 'Поиск floppy дисководов',0 - boot_detecthdcd cp866 'Поиск жестких дисков и ATAPI приводов',0 - boot_getcache cp866 'Получение памяти для кэша',0 - boot_detectpart cp866 'Поиск разделов на дисковых устройствах',0 - boot_init_sys cp866 'Инициализация системного каталога /sys',0 - boot_loadlibs cp866 'Загрузка библиотек (.obj)',0 - boot_memdetect cp866 'Количество оперативной памяти',' ',' Мб',0 - boot_tss cp866 'Установка TSSs',0 - boot_cpuid cp866 'Чтение CPUIDs',0 -; boot_devices cp866 'Поиск устройств',0 - boot_timer cp866 'Установка таймера',0 - boot_initramdisk cp866 'Инициализация рамдиска',0 - boot_irqs cp866 'Переопределение IRQ',0 - boot_setmouse cp866 'Установка мыши',0 - boot_windefs cp866 'Установка настроек окон по умолчанию',0 - boot_bgr cp866 'Установка фона',0 - boot_resirqports cp866 'Резервирование IRQ и портов',0 - boot_setrports cp866 'Установка адресов IRQ',0 - boot_setostask cp866 'Создание процесса ядра',0 - boot_allirqs cp866 'Открытие всех IRQ',0 - boot_tsc cp866 'Чтение TSC',0 - boot_cpufreq cp866 'Частота процессора ',' ',' МГц',0 - boot_pal_ega cp866 'Установка EGA/CGA 320x200 палитры',0 - boot_pal_vga cp866 'Установка VGA 640x480 палитры',0 - boot_failed cp866 'Загрузка первого приложения не удалась',0 - boot_mtrr cp866 'Установка MTRR',0 - - boot_APIC_found cp866 'APIC включен', 0 - boot_APIC_nfound cp866 'APIC не найден', 0 -if preboot_blogesc - boot_tasking cp866 'Все готово для запуска, нажмитре ESC для старта',0 -end if -else if lang eq sp - include 'data32sp.inc' -else if lang eq et - include 'data32et.inc' -else - boot_initirq db 'Initialize IRQ',0 - boot_picinit db 'Initialize PIC',0 - boot_v86machine db 'Initialize system V86 machine',0 - boot_inittimer db 'Initialize system timer (IRQ0)',0 - boot_initramdisk db 'Initialize ramdisk',0 - boot_initapic db 'Try to initialize APIC',0 - boot_enableirq db 'Enable interrupts 2, 13',0 - boot_disabling_ide db 'Disable interrupts in IDE controller',0 - boot_enabling_ide db 'Enable interrupts in IDE controller',0 - boot_set_int_IDE db 'Set handler of interrupts for IDE',0 - boot_detectfloppy db 'Search floppy drives',0 - boot_detecthdcd db 'Search hard drives and ATAPI drives',0 - boot_getcache db 'Get memory for cache',0 - boot_detectpart db 'Search partitions on disk devices',0 - boot_init_sys db 'Initialize system directory /sys',0 - boot_loadlibs db 'Loading librares (.obj)',0 - boot_memdetect db 'Determining amount of memory',0 - boot_tss db 'Setting TSSs',0 - boot_cpuid db 'Reading CPUIDs',0 -; boot_devices db 'Detecting devices',0 - boot_setmouse db 'Setting mouse',0 - boot_windefs db 'Setting window defaults',0 - boot_bgr db 'Calculating background',0 - boot_resirqports db 'Reserving IRQs & ports',0 - boot_setostask db 'Setting OS task',0 - boot_allirqs db 'Unmasking IRQs',0 - boot_tsc db 'Reading TSC',0 - boot_cpufreq db 'CPU frequency is ',' ',' MHz',0 - boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0 - boot_pal_vga db 'Setting VGA 640x480 palette',0 - boot_failed db 'Failed to start first app',0 - boot_mtrr db 'Setting MTRR',0 - - boot_APIC_found db 'APIC enabled', 0 - boot_APIC_nfound db 'APIC not found', 0 -if preboot_blogesc - boot_tasking db 'All set - press ESC to start',0 -end if -end if - -;new_process_loading db 'K : New Process - loading',13,10,0 -;new_process_running db 'K : New Process - done',13,10,0 -start_not_enough_memory db 'K : New Process - not enough memory',13,10,0 - -msg_unresolved db 'unresolved ',0 -;msg_module db 'in module ',0 -;if ~ lang eq sp -;msg_version db 'incompatible driver version',13,10,0 -;msg_www db 'please visit www.kolibrios.org',13,10,0 -;end if -msg_CR db 13,10,0 - -szPS2MDriver db '/sys/drivers/PS2MOUSE.SYS',0 -;szCOM_MDriver db 'COM_MOUSE',0 -szVidintel db '/sys/drivers/vidintel.sys',0 -szUSB db 'USB',0 - -szEXPORTS db 'EXPORTS',0 -sz_EXPORTS db '_EXPORTS',0 - -szIMPORTS db 'IMPORTS',0 - -read_firstapp db '/sys/' -firstapp db '/sys/LAUNCHER',0 -notifyapp db '/sys/@notify',0 -if lang eq ru -ud_user_message cp866 'Ошибка: неподдерживаемая инструкция процессора',0 -mtrr_user_message cp866 '"Обнаружена проблема с конфигурацией MTRR.\nПроизводительность может быть пониженной" -dW',0 -else if ~ lang eq sp -ud_user_message db 'Error: unsupported processor instruction',0 -mtrr_user_message db '"There is a problem with MTRR configuration.\nPerformance can be low" -dW',0 -end if - -kernel_file_load: -; load kernel.mnt to _CLEAN_ZONE - dd 0 ; subfunction - dq 0 ; offset in file - dd 0x31000 ; number of bytes to read - dd _CLEAN_ZONE ; buffer for data - db '/sys/KERNEL.MNT',0 - -dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',0 -; { Patch by Coldy, For DLL autoload -dll_lib_path db '/RD/1/LIB/DLL.OBJ',0 -dll_error_msg db '"DLL.OBJ not found!\nTerminate application!" -dE',0 -; } End patch by Coldy, For DLL autoload -align 4 - -shmem_list: - .bk dd shmem_list - .fd dd shmem_list - -dll_list: - .bk dd dll_list - .fd dd dll_list - -pcidev_list: - .bk dd pcidev_list - .fd dd pcidev_list - -MAX_DEFAULT_DLL_ADDR = 0x80000000 -MIN_DEFAULT_DLL_ADDR = 0x70000000 -dll_cur_addr dd MIN_DEFAULT_DLL_ADDR - -; supported videomodes - - -; mike.dld { -;db 0 -;dd servetable-0x10000 -;align 4 -;draw_line dd __sys_draw_line -;draw_pointer dd __sys_draw_pointer -;//mike.dld, 2006-08-02 [ -;;drawbar dd __sys_drawbar -;;drawbar dd __sys_drawbar.forced -;drawbar dd vesa20_drawbar -;//mike.dld, 2006-08-02 ] -;putpixel dd __sys_putpixel -; } mike.dld - - -align 4 -keyboard dd 1 - -if lang eq en - SYSLANG = 1 -else if lang eq fi - SYSLANG = 2 -else if lang eq de - SYSLANG = 3 -else if lang eq ru - SYSLANG = 4 -else if lang eq fr - SYSLANG = 5 -else if lang eq et - SYSLANG = 6 -else if lang eq sp - SYSLANG = 7 -else if lang eq it - SYSLANG = 8 -else if lang eq ca - SYSLANG = 9 -else - display 'unsupported language specified',13,10 -end if -syslang dd SYSLANG - -boot_y dd 10 - -pci_bios_entry dd 0 - dw pci_code_sel - -if __DEBUG__ eq 1 - include_debug_strings -end if - -IncludeIGlobals - -align 16 -gdts: - - dw gdte-$-1 - dd gdts - dw 0 - -; Attention! Do not change the order of the first four selectors. They are used in Fast System Call -; must be : os_code, os_data, app_code, app_data, .... - -int_code_l: -os_code_l: - dw 0xffff - dw 0x0000 - db 0x00 - dw 11011111b *256 +10011010b - db 0x00 - -int_data_l: -os_data_l: - dw 0xffff - dw 0x0000 - db 0x00 - dw 11011111b *256 +10010010b - db 0x00 - -app_code_l: - dw 0xFFFF - dw 0 - db 0 - db cpl3 - dw G32+D32+0xF; - -app_data_l: - dw 0xFFFF - dw 0 - db 0 - db drw3 - dw G32+D32+0xF; - -; ------------- PCI BIOS ------------------ - -pci_code_32: - dw 0 ;lim 0-15 - dw 0 ;base 0-15 - db 0 ;base 16-23 - db cpl0 ;type - db D32 ;lim 16-19+props - db 0 ;base 24-31 - -pci_data_32: - dw 0 ;lim 0-15 - dw 0 ;base 0-15 - db 0 ;base 16-23 - db dpl0 ;type - db D32 ;lim 16-19+props - db 0 ;base 24-31 - -; --------------- APM --------------------- -apm_code_32: - dw 0x0f ; limit 64kb - db 0, 0, 0 - dw 11010000b *256 +10011010b - db 0x00 -apm_code_16: - dw 0x0f - db 0, 0, 0 - dw 10010000b *256 +10011010b - db 0x00 -apm_data_16: - dw 0x0f - db 0, 0, 0 - dw 10010000b *256 +10010010b - db 0x00 -; ----------------------------------------- - -graph_data_l: - - dw 0x7ff - dw 0x0000 - db 0x00 - dw 11010000b *256 +11110010b - db 0x00 -tss0_l: - dw sizeof.TSS-1 - dw tss and 0xFFFF - db (tss shr 16) and 0xFF - db 10001001b - dw (tss shr 16) and 0xFF00 - -tls_data_l: - dw 0x0FFF - dw 0 - db 0 - db drw3 - dw D32 - -gdte: - -diff16 "end of .data segment",0,$ -endofcode: - -align 16 -cur_saved_data: - rb 4096 -align 64 -fpu_data: - rb 0xa80 ; bochs avx512 -fpu_data_size = $ - fpu_data -draw_data: - rb 32*256 -BPSLine_calc_area rd MAX_SCREEN_HEIGHT -d_width_calc_area rd MAX_SCREEN_HEIGHT -mouseunder rd 16*24 - -mem_block_list rd 64*2 -mem_used_list rd 64*2 -mem_hash_cnt rd 64 - -thr_slot_map rd 8 - -_display display_t -bios_fb FRB - -mst MEM_STATE - -cpu_freq dq ? - -heap_mutex MUTEX -heap_size dd ? -heap_free dd ? -heap_blocks dd ? -free_blocks dd ? -mem_block_mask rd 2 -next_memblock dd ? - -pte_valid_mask dd ? -page_start dd ? -page_end dd ? -sys_page_map dd ? -os_stack_seg dd ? - -srv.fd dd ? -srv.bk dd ? - -LFBAddress dd ? - -PUTPIXEL dd ? -GETPIXEL dd ? - -if VESA_1_2_VIDEO -BANK_SWITCH dd ? ; reserved for vesa 1.2 -BANK_RW dd ? -end if - -MOUSE_PICTURE dd ? - -def_cursor dd ? -def_cursor_clock dd ? -current_cursor dd ? -hw_cursor dd ? -cur_saved_base dd ? - -cur.lock dd ? ; 1 - lock update, 2- hide -cur.left dd ? ; cursor clip box -cur.top dd ? -cur.w dd ? -cur.h dd ? - -ipc_tmp dd ? -ipc_pdir dd ? -ipc_ptab dd ? - -proc_mem_map dd ? -proc_mem_pdir dd ? -proc_mem_tab dd ? - -tmp_task_ptab dd ? - -default_io_map dd ? - -LFBSize dd ? - -current_process dd ? -current_slot dd ? ; pointer to APPDATA of current thread -current_slot_idx dd ? ; index of current thread slot -thread_count dd ? - -; device addresses -mididp dd ? -midisp dd ? - -cdbase dd ? -cdid dd ? - -hdbase dd ? ; for boot 0x1f0 -hdid dd ? -hdpos dd ? ; for boot 0x1 -cdpos dd ? - -;CPUID information -cpu_vendor rd 3 -cpu_sign dd ? -cpu_info dd ? -cpu_caps rd 4 - -xsave_area_size dd ? -xsave_eax dd ? -xsave_edx dd ? - -pg_data PG_DATA -heap_test dd ? - -skin_data dd ? - -mouse_active dd ? -mouse_pause dd ? - -BgrDrawMode dd ? -BgrDataWidth dd ? -BgrDataHeight dd ? - -buttontype dd ? -windowtypechanged dd ? - -debug_step_pointer dd ? - -lba_read_enabled dd ? ; 0 = disabled , 1 = enabled -pci_access_enabled dd ? ; 0 = disabled , 1 = enabled - -NumBiosDisks dd ? -BiosDisksData rb 200h ; struct BiosDiskData -BiosDiskCaches rb 80h*(cache_ide1-cache_ide0) -BiosDiskPartitions rd 80h - -img_background dd ? -mem_BACKGROUND dd ? -static_background_data dd ? - -hd1_status dd ? ; 0 - free : other - pid -application_table_owner dd ? ; 0 - free : other - pid -application_table_mutex MUTEX - -redrawmouse_unconditional dd ? - -MOUSE_SCROLL_H rw 1 -MOUSE_X: rw 1 -MOUSE_Y: rw 1 -MOUSE_SCROLL_V rw 1 - -X_UNDER rw 1 -Y_UNDER rw 1 -COLOR_TEMP dd ? -MOUSE_COLOR_MEM dd ? - -SCR_MODE rw 2 - -BTN_DOWN: rb 4 - -cpu_phys_addr_width db ? ; also known as MAXPHYADDR in Intel manuals -hdd_appl_data db ? ; 0 = system cache, 1 - application cache -cd_appl_data db ? ; 0 = system cache, 1 - application cache - -timer_ticks_enable db ? ; for cd driver - -REDRAW_BACKGROUND db ? - -align 16 -DRIVE_DATA: rb DRIVE_DATA_SIZE - -IncludeUGlobals - -uglobals_size = $ - endofcode - -if ~ lang eq sp -diff16 "end of .bss",0,$ -end if - -; check if kernel fits memmap -assert $-OS_BASE+0x1000 < TMP_STACK_TOP - -org (OS_BASE+0x0100000) - -; Currently size of memory allocated for the ramdisk is fixed. -; This should be revisited when/if memory map would become more dynamic. -RAMDISK_CAPACITY = 2880 ; in sectors - -RAMDISK: - rb RAMDISK_CAPACITY*512 - -_CLEAN_ZONE: -CLEAN_ZONE = _CLEAN_ZONE - OS_BASE - -BgrAuxTable rb 32768 -align 65536 -SB16Buffer rb 65536 - -align 4096 -BUTTON_INFO rb 64*1024 -RESERVED_PORTS: - rb 64*1024 -sys_pgmap: - rb 1024*1024/8 diff --git a/kernel/branches/Kolibri-F/data32et.inc b/kernel/branches/Kolibri-F/data32et.inc deleted file mode 100644 index 4345c7862..000000000 --- a/kernel/branches/Kolibri-F/data32et.inc +++ /dev/null @@ -1,48 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - - boot_initirq latin1 'Algväärtustan IRQ',0 - boot_picinit latin1 'Algväärtustan PIC',0 - boot_v86machine latin1 'Algväärtustan süsteemi V86 masinat',0 - boot_inittimer latin1 'Algväärtustan süsteemi taimerit (IRQ0)',0 - boot_initramdisk latin1 'Initialize ramdisk',0 - boot_initapic latin1 'Proovin Algväärtustada APIC',0 - boot_enableirq latin1 'Luban katkestused 2, 13',0 - boot_disabling_ide latin1 'Keelan IDE kontrolleri katkestused',0 - boot_enabling_ide latin1 'Luban IDE kontrolleri katkestused',0 - boot_set_int_IDE latin1 'Määran IDE kontrolleri halduri',0 - boot_detectfloppy latin1 'Otsin floppi kettaid',0 - boot_detecthdcd latin1 'Otsin kõvakettaid ja ATAPI seadmeid',0 - boot_getcache latin1 'Küsin puhvri mälu',0 - boot_detectpart latin1 'Otsin kettaseadmete partitsioone',0 - boot_init_sys latin1 'Algväärtustan süsteemi kataloogi /sys',0 - boot_loadlibs latin1 'Laadin mooduleid (.obj)',0 - boot_memdetect latin1 'Avastan mälu mahtu',0 - boot_tss latin1 'Määran TSSe',0 - boot_cpuid latin1 'Loen CPUIDd',0 -; boot_devices db 'Detecting devices',0 - boot_setmouse latin1 'Seadistan hiirt',0 - boot_windefs latin1 'Seadistan akende vaikeväärtusi',0 - boot_bgr latin1 'Kalkuleerin tausta',0 - boot_resirqports latin1 'Reserveerin IRQsi ja porte',0 - boot_setostask latin1 'Seadistan OS protsessi',0 - boot_allirqs latin1 'Unmasking IRQs',0 - boot_tsc latin1 'Loen TSC',0 - boot_cpufreq latin1 'CPU sagedus on ',' ',' MHz',0 - boot_pal_ega latin1 'Seadistan EGA/CGA 320x200 paletti',0 - boot_pal_vga latin1 'Seadistan VGA 640x480 paletti',0 - boot_failed latin1 'Esimese programmi käivitamine ebaõnnestus',0 - boot_mtrr latin1 'Määran MTRR',0 - - boot_APIC_found latin1 'APIC aktiveeritud', 0 - boot_APIC_nfound latin1 'APIC ei leitud', 0 -if preboot_blogesc - boot_tasking latin1 'Kõik valmis - vajuta ESC alustamiseks',0 -end if \ No newline at end of file diff --git a/kernel/branches/Kolibri-F/data32sp.inc b/kernel/branches/Kolibri-F/data32sp.inc deleted file mode 100644 index 6f421a110..000000000 --- a/kernel/branches/Kolibri-F/data32sp.inc +++ /dev/null @@ -1,54 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - - boot_initirq: cp850 'Inicializar IRQ',0 - boot_picinit: cp850 'Inicializar PIC',0 - boot_v86machine: cp850 'Inicializar sistema V86',0 - boot_inittimer: cp850 'Inicializar reloj del sistema (IRQ0)',0 - boot_initramdisk cp850 'Initialize ramdisk',0 - boot_initapic: cp850 'Prueba inicializar APIC',0 - boot_enableirq: cp850 'Habilitar interrupciones 2, 13',0 - boot_disabling_ide:cp850 'Habiliar interrupciones en controladores IDE',0 - boot_enabling_ide:cp850 'Habilitar interrupciones en controladores IDE',0 - boot_set_int_IDE: cp850 'Configuración del controlador de interrupciones para el IDE',0 - boot_detectfloppy:cp850 'Buscar unidades de disquete',0 - boot_detecthdcd: cp850 'Buscar discos duros y unidades ATAPI',0 - boot_getcache: cp850 'Tomar memoria para caché',0 - boot_detectpart: cp850 'Buscar particiones en discos',0 - boot_init_sys: cp850 'Inicializar directorio del sistema /sys',0 - boot_loadlibs: cp850 'Cargando librerías (.obj)',0 - boot_memdetect: cp850 'Determinando cantidad de memoria',0 - boot_tss: cp850 'Configurando TSSs',0 - boot_cpuid: cp850 'Leyendo CPUIDs',0 -; boot_devices: cp850 'Detectando dispositivos',0 - boot_setmouse: cp850 'Configurando el ratón',0 - boot_windefs: cp850 'Setting window defaults',0 - boot_bgr: cp850 'Calculating background',0 - boot_resirqports: cp850 'Reservando IRQs y puertos',0 - boot_setostask: cp850 'Configurando tarea OS',0 - boot_allirqs: cp850 'Desenmascarando IRQs',0 - boot_tsc: cp850 'Leyendo TSC',0 - boot_cpufreq: cp850 'La frequencia del CPU es ',' ',' MHz',0 - boot_pal_ega: cp850 'Configurando paleta EGA/CGA 320x200',0 - boot_pal_vga: cp850 'Configurando paleta VGA 640x480',0 - boot_failed: cp850 'Fallo al iniciar la primer aplicación',0 - boot_mtrr: cp850 'Configurando MTRR',0 - - boot_APIC_found: cp850 'APIC habilitado', 0 - boot_APIC_nfound: cp850 'APIC no encontrado', 0 -if preboot_blogesc - boot_tasking: cp850 'Todo configurado - presiona ESC para iniciar',0 -end if - -;msg_version: cp850 'versión incompatible del controlador',13,10,0 -;msg_www: cp850 'por favor, visita www.kolibrios.org',13,10,0 - -ud_user_message:cp850 'Error: instrucción no soportada por el procesador',0 -mtrr_user_message cp850 '"There is a problem with MTRR configuration.\nPerformance can be low" -dW',0 diff --git a/kernel/branches/Kolibri-F/detect/biosdisk.inc b/kernel/branches/Kolibri-F/detect/biosdisk.inc deleted file mode 100644 index 81a9f463a..000000000 --- a/kernel/branches/Kolibri-F/detect/biosdisk.inc +++ /dev/null @@ -1,122 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2008-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; Detect all BIOS hard drives. -; diamond, 2008 -; Do not include USB mass storages. CleverMouse, 2013 -; Read the number of sectors, bytes per sector. dunkaist, 2017 - - xor cx, cx - mov es, cx - mov di, BOOT_LO.bios_hd - mov byte [es:di-1], cl - cmp [preboot_biosdisk], 1 - jnz bdde - mov dl, 80h -bdds: - mov ah, 15h - push cx dx di - int 13h - pop di dx cx - jc bddc - test ah, ah - jz bddc - inc cx -; We are going to call int 13h/func 48h, Extended get drive parameters. -; The latest version of the EDD specification is 3.0. -; There are two slightly incompatible variants for version 3.0; -; original one from Phoenix in 1998, see e.g. -; http://www.t10.org/t13/technical/d98120r0.pdf, and T13 draft, -; http://www.t13.org/documents/UploadedDocuments/docs2004/d1572r3-EDD3.pdf -; T13 draft addresses more possible buses, so it gives additional 8 bytes -; for device path. -; Most BIOSes follow Phoenix, but T13 version is also known to be used -; (e.g. systems based on AMD Geode). -; Fortunately, there is an in/out length field, so -; it is easy to tell what variant was selected by the BIOS: -; Phoenix-3.0 has 42h bytes, T13-3.0 has 4Ah bytes. -; Note that 2.0 has 1Eh bytes, 1.1 has 1Ah bytes; both variants of 3.0 have -; the same structure for first 1Eh bytes, compatible with previous versions. -; Note also that difference between Phoenix-3.0 and T13-3.0 starts near the -; end of the structure, so the current code doesn't even need to distinguish. -; It needs, however, give at least 4Ah bytes as input and expect that BIOS -; could return 42h bytes as output while still giving all the information. - mov ah, 48h - push ds - push es - pop ds - mov si, 0xA000 - mov word [si], 4Ah - mov ah, 48h - int 13h - pop ds - jc bddc2 - cmp word [es:si], 1Eh - jb .noide - cmp word [es:si+1Ah], 0xFFFF - jz .noide - inc byte [es:BOOT_LO.bios_hd_cnt] - mov al, dl - stosb - push ds - push si - lds si, [es:si+1Ah] - mov al, [si+6] - and al, 0xF - stosb - mov al, byte [si+4] - shr al, 4 - and ax, 1 - cmp word [si], 1F0h - jz @f - inc ax - inc ax - cmp word [si], 170h - jz @f - or ax, -1 -; mov ax, -1 -@@: - stosw - pop si - pop ds - jmp bddc3 -.noide: - cmp word [es:si], 42h - jb .nousb - cmp word [es:si+28h], 'US' - jnz .nousb - cmp byte [es:si+2Ah], 'B' - jz bddc2 -.nousb: - inc byte [es:BOOT_LO.bios_hd_cnt] - mov al, dl - stosb - xor ax, ax - stosb - dec ax - stosw -; mov al, 0 -; stosb -; mov ax, -1 -; stosw -bddc3: - movzx eax, word[es:si+24] - stosd - mov eax, [es:si+16] - stosd - mov eax, [es:si+20] - stosd -bddc2: - cmp cl, [es:0x475] - jae bdde -bddc: - inc dl - jnz bdds -bdde: diff --git a/kernel/branches/Kolibri-F/detect/biosmem.inc b/kernel/branches/Kolibri-F/detect/biosmem.inc deleted file mode 100644 index bf032393d..000000000 --- a/kernel/branches/Kolibri-F/detect/biosmem.inc +++ /dev/null @@ -1,46 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2009-2017. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -; Query physical memory map from BIOS. -; diamond, 2009 - - push ds -; first call to fn E820 - mov eax, 0xE820 - xor ebx, ebx - mov es, bx - mov ds, bx - mov di, BOOT_LO.memmap_blocks - mov [BOOT_LO.memmap_block_cnt], ebx ; no blocks yet - mov ecx, 20 - mov edx, 'PAMS' ; 'SMAP' - int 15h - jc no_E820 - cmp eax, 'PAMS' - jnz no_E820 -e820_mem_loop: -; cmp byte [di+16], 1 ; ignore non-free areas -; jnz e820_mem_next - inc byte [BOOT_LO.memmap_block_cnt] - add di, sizeof.e820entry -e820_mem_next: -; consequent calls to fn E820 - test ebx, ebx - jz e820_test_done - cmp byte [BOOT_LO.memmap_block_cnt], MAX_MEMMAP_BLOCKS - jz e820_test_done - mov eax, 0xE820 - int 15h - jc e820_test_done - jmp e820_mem_loop -no_E820: -; let's hope for mem_test from init.inc -e820_test_done: - pop ds diff --git a/kernel/branches/Kolibri-F/detect/dev_fd.inc b/kernel/branches/Kolibri-F/detect/dev_fd.inc deleted file mode 100644 index 6e3fded9d..000000000 --- a/kernel/branches/Kolibri-F/detect/dev_fd.inc +++ /dev/null @@ -1,38 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -;*************************************************** -; clear the DRIVE_DATA table, -; search for FDDs and add them into the table -; author - Mario79 -;*************************************************** - xor eax, eax - mov edi, DRIVE_DATA - mov ecx, DRIVE_DATA_SIZE/4 - cld - rep stosd - - mov al, 0x10 - out 0x70, al - mov cx, 0xff -wait_cmos: - dec cx - test cx, cx - jnz wait_cmos - in al, 0x71 - mov [DRIVE_DATA], al - test al, al - jz @f - - stdcall attach_int_handler, 6, FDCInterrupt, 0 - DEBUGF 1, "K : Set IDE IRQ6 return code %x\n", eax - call floppy_init -@@: - diff --git a/kernel/branches/Kolibri-F/detect/dev_hdcd.inc b/kernel/branches/Kolibri-F/detect/dev_hdcd.inc deleted file mode 100644 index 24e256c3f..000000000 --- a/kernel/branches/Kolibri-F/detect/dev_hdcd.inc +++ /dev/null @@ -1,475 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -; HDD and CD search - - cmp [ecx+IDE_DATA.ProgrammingInterface], 0 - je EndFindHDD -FindHDD: - xor ebx, ebx - inc ebx - mov [DeviceNumber], 0 - cmp ecx, IDE_controller_1 - jz .find - add bl, 5 - add [DeviceNumber], sizeof.HD_DATA*4 - cmp ecx, IDE_controller_2 - jz .find - add bl, 5 - add [DeviceNumber], sizeof.HD_DATA*4 -.find: - mov [ChannelNumber], 1 - mov [DiskNumber], 0 - call FindHDD_1 - inc [DiskNumber] - call FindHDD_2 - inc [ChannelNumber] - dec [DiskNumber] - call FindHDD_2 - inc [DiskNumber] - call FindHDD_2 - jmp EndFindHDD -;----------------------------------------------------------------------------- -FindHDD_2: - add [DeviceNumber], sizeof.HD_DATA - shl byte [ebx+DRIVE_DATA], 2 -FindHDD_1: - DEBUGF 1, "K : Channel %d ",[ChannelNumber]:1 - DEBUGF 1, "Disk %d\n",[DiskNumber]:1 - push ecx ebx - call ReadHDD_ID - cmp [DevErrorCode], 7 - je .end - cmp [DevErrorCode], 0 - jne .FindCD - cmp [Sector512+6], word 16 - ja .FindCD - cmp [Sector512+12], word 255 - ja .FindCD - pop ebx - movzx eax, [DeviceNumber] - mov ecx, [Sector512+120] - mov dword[eax+hd0_data.sectors], ecx - and dword[eax+hd0_data.sectors+4], 0 - bt word [Sector512+166], 10 - jnc .Print_Device_Name - mov [eax+hd0_data.hd48], 1 - mov ecx, [Sector512+200] - mov dword[eax+hd0_data.sectors], ecx - mov ecx, [Sector512+204] - mov dword[eax+hd0_data.sectors+4], ecx - jmp .Print_Device_Name -;-------------------------------------- -.FindCD: - call DeviceReset - cmp [DevErrorCode], 0 - jne .end - call ReadCD_ID - cmp [DevErrorCode], 0 - jne .end - pop ebx - inc byte [ebx+DRIVE_DATA] -;-------------------------------------- -.Print_Device_Name: - inc byte [ebx+DRIVE_DATA] - pop ecx - pushad - movzx ebx, [ChannelNumber] - dec ebx - shl ebx, 1 - add bl, [DiskNumber] - shl ebx, 1 - call calculate_IDE_device_values_storage -;-------------------------------------- -.copy_dev_name: - mov esi, Sector512+27*2 - mov edi, dev_name - mov ecx, 20 - cld -;-------------------------------------- -@@: - lodsw - xchg ah, al - stosw - loop @b - DEBUGF 1, "K : Dev: %s \n", dev_name - xor eax, eax - mov ax, [Sector512+64*2] - DEBUGF 1, "K : PIO possible modes %x\n", al - mov ax, [Sector512+51*2] - mov al, ah - call convert_Sector512_value - DEBUGF 1, "K : PIO set mode %x\n", ah - mov ax, [Sector512+63*2] - DEBUGF 1, "K : Multiword DMA possible modes %x\n", al - mov al, ah - call convert_Sector512_value - DEBUGF 1, "K : Multiword DMA set mode %x\n", ah - mov ax, [Sector512+88*2] - DEBUGF 1, "K : Ultra DMA possible modes %x\n", al - mov [ebx+IDE_DEVICE.UDMA_possible_modes], al - mov al, ah - call convert_Sector512_value - DEBUGF 1, "K : Ultra DMA set mode %x\n", ah - mov [ebx+IDE_DEVICE.UDMA_set_mode], ah - popad - ret - -.end: - DEBUGF 1, "K : Device not found\n" - pop ebx ecx - ret -;----------------------------------------------------------------------------- -calculate_IDE_device_values_storage: - cmp ecx, IDE_controller_1 - jne @f - - add ebx, IDE_device_1 - jmp .exit -;-------------------------------------- -@@: - cmp ecx, IDE_controller_2 - jne @f - - add ebx, IDE_device_2 - jmp .exit -;-------------------------------------- -@@: - add ebx, IDE_device_3 -;-------------------------------------- -.exit: - ret -;----------------------------------------------------------------------------- -convert_Sector512_value: - mov ecx, 8 - xor ah, ah -;-------------------------------------- -@@: - test al, 1b - jnz .end - - shr al, 1 - inc ah - loop @b - - xor ah, ah -;-------------------------------------- -.end: - ret -;----------------------------------------------------------------------------- -; Address of reading sector in LBA mode -uglobal -SectorAddress dd ? -dev_name: - rb 41 -endg -;----------------------------------------------------------------------------- -;************************************************* -;* READING THE HARD DISK IDENTIFIER * -;* Input parameters are passed through the global* -;* variables: * -;* ChannelNumber - channel number (1 or 2); * -;* DiskNumber - disk number on channel (0 or 1) * -;* Block of identificational data is reading * -;* to Sector512 array. * -;************************************************* -ReadHDD_ID: -; set up CHS mode - mov [ATAAddressMode], 0 -; send device identification command - mov [ATAFeatures], 0 - mov [ATAHead], 0 - mov [ATACommand], 0xEC - call SendCommandToHDD - cmp [DevErrorCode], 0 ; check the error code - jne @@End ; finish, saving the error code - - mov dx, [ATABasePortAddr] - add dx, 7 ; address of state register - mov ecx, 0xffff -@@WaitCompleet: - ; Check command execution time - dec ecx - jz @@Error1 ; timeout error - ; Check if ready or not - in al, dx - test al, 80h ; BSY signal state - jnz @@WaitCompleet - - test al, 1 ; ERR signal state - jnz @@Error6 - - test al, 08h ; DRQ signal state - jz @@WaitCompleet -; Receive data block from controller - mov edi, Sector512 - mov dx, [ATABasePortAddr]; data register - mov cx, 256 ; number of word to receive - rep insw ; receive data block - ret -; write the error code -@@Error1: - mov [DevErrorCode], 1 - ret -@@Error6: - mov [DevErrorCode], 6 -@@End: - ret -;----------------------------------------------------------------------------- -uglobal -; Standart base addresses of channels 1 or 2 -StandardATABases dw ?, ? ; 1F0h, 170h -; Channel number -ChannelNumber db ? -; Disk number -DiskNumber db ? -DeviceNumber db ? -; Base address of ATA controller's port group -ATABasePortAddr dw ? -; ATA-command parameters -ATAFeatures db ? ; features -ATASectorCount db ? ; count of processing sectors -ATASectorNumber db ? ; initial sector number -ATACylinder dw ? ; initial cylinder number -ATAHead db ? ; initial head number -ATAAddressMode db ? ; addressing mode (0 - CHS, 1 - LBA) -ATACommand db ? ; executing command number -; Error code (0 - no errors, 1 - waiting time limit exceed -; 2 - incorrect code of addressing mode, -; 3 - incorrect channel number, 4 - incorrect disk number, -; 5 - incorrect head number, 6 - command execution error, -; 7 - time out when choosing channel) -DevErrorCode dd ? -endg -;----------------------------------------------------------------------------- -;**************************************************** -;* SEND COMMAND TO GIVEN DISK * -;* Input parameters are passed through the global * -;* variables: * -;* ChannelNumber - channel number (1 or 2); * -;* DiskNumber - disk number (0 or 1); * -;* ATAFeatures - "features"; * -;* ATASectorCount - sector count; * -;* ATASectorNumber - initial sector number; * -;* ATACylinder - initial cylinder number; * -;* ATAHead - initial head number; * -;* ATAAddressMode - addressing mode (0-CHS, 1-LBA); * -;* ATACommand - command code. * -;* If the function finished successfully: * -;* in ATABasePortAddr - base address of HDD; * -;* in DevErrorCode - zero. * -;* If error has occured then in DevErrorCode will * -;* be the error code. * -;**************************************************** -SendCommandToHDD: -; Check the addressing mode code - cmp [ATAAddressMode], 1 - ja @@Err2 -; Check the channel number correctness - movzx ebx, [ChannelNumber] - dec ebx - cmp ebx, 1 - ja @@Err3 -; Set the base address - shl ebx, 1 - mov ax, [ebx+StandardATABases] - mov [ATABasePortAddr], ax -; Waiting for HDD ready to receive a command - ; Choose desired disk - mov dx, [ATABasePortAddr] - add dx, 6 ; address of the heads register - mov al, [DiskNumber] - cmp al, 1 ; check the disk number - ja @@Err4 - - shl al, 4 - or al, 10100000b - out dx, al - ; Waiting for disk ready - inc dx - mov ecx, 0xfff -@@WaitHDReady: - ; Check waiting time - dec ecx - jz @@Err1 - ; Read the state register - in al, dx - ; Check the state of BSY signal - test al, 80h - jnz @@WaitHDReady - ; Check the state of DRQ signal - test al, 08h - jnz @@WaitHDReady -; load command to controller's registers - cli - mov dx, [ATABasePortAddr] - inc dx ; "features" register - mov al, [ATAFeatures] - out dx, AL - inc dx ; sector counter - mov al, [ATASectorCount] - out dx, AL - inc dx ; sector number register - mov al, [ATASectorNumber] - out dx, AL - inc dx ; cylinder number (low byte) - mov ax, [ATACylinder] - out dx, AL - inc dx ; cylinder number (high byte) - mov al, AH - out dx, AL - inc dx ; head number / disk number - mov al, [DiskNumber] - shl al, 4 - cmp [ATAHead], 0xF ; check head number - ja @@Err5 - - or al, [ATAHead] - or al, 10100000b - mov ah, [ATAAddressMode] - shl ah, 6 - or al, ah - out dx, al -; Send command - mov al, [ATACommand] - inc dx ; command register - out dx, al - sti -; reset the error sign - mov [DevErrorCode], 0 - ret -; write error code -@@Err1: - mov [DevErrorCode], 7 - ret -@@Err2: - mov [DevErrorCode], 2 - ret -@@Err3: - mov [DevErrorCode], 3 - ret -@@Err4: - mov [DevErrorCode], 4 - ret -@@Err5: - mov [DevErrorCode], 5 -; finish work - ret -;----------------------------------------------------------------------------- -;************************************************* -;* READ ATAPI DEVICE IDENTIFIER * -;* Input parameters are passed through the global* -;* variables: * -;* ChannelNumber - channel number; * -;* DiskNumber - disk number on channel. * -;* Block of identificational data is reading * -;* to Sector512 array. * * -;************************************************* -ReadCD_ID: -; Set CHS mode - mov [ATAAddressMode], 0 -; Send command for device identification - mov [ATAFeatures], 0 - mov [ATASectorCount], 0 - mov [ATASectorNumber], 0 - mov [ATACylinder], 0 - mov [ATAHead], 0 - mov [ATACommand], 0xA1 - call SendCommandToHDD - cmp [DevErrorCode], 0 ; check the error code - jne @@End_1 ; finish, saving the error code -; Wait for HDD data ready - mov dx, [ATABasePortAddr] - add dx, 7 ; port 1х7h - mov ecx, 0xffff -@@WaitCompleet_1: - ; Check time - dec ecx - jz @@Error1_1 ; time out error - ; Check readyness - in al, dx - test al, 80h ; BSY signal state - jnz @@WaitCompleet_1 - - test al, 1 ; ERR signal state - jnz @@Error6_1 - - test al, 08h ; DRQ signal state - jz @@WaitCompleet_1 -; Receive data block from controller - mov edi, Sector512 ; offset Sector512 - mov dx, [ATABasePortAddr] ; port 1x0h - mov cx, 256 ; words read count - rep insw - ret -; write the error code -@@Error1_1: - mov [DevErrorCode], 1 - ret -@@Error6_1: - mov [DevErrorCode], 6 -@@End_1: - ret -;----------------------------------------------------------------------------- -;************************************************* -;* DEVICE RESET * -;* Input parameters are passed through the global* -;* variables: * -;* ChannelNumber - channel number (1 or 2); * -;* DiskNumber - disk number (0 or 1). * -;************************************************* -DeviceReset: -; Check the channel number correctness - movzx ebx, [ChannelNumber] - dec ebx - cmp ebx, 1 - ja @@Err3_2 -; Set base address - shl ebx, 1 - mov dx, [ebx+StandardATABases] - mov [ATABasePortAddr], dx -; Choose desired disk - add dx, 6 ; address of heads register - mov al, [DiskNumber] - cmp al, 1 ; check disk number - ja @@Err4_2 - - shl al, 4 - or al, 10100000b - out dx, al -; Send the "Reset" command - mov al, 0x8 - inc dx ; command register - out dx, al - mov ecx, 0x80000 -@@WaitHDReady_1: - ; Check waiting time - dec ecx - je @@Err1_2 ; time out error - ; read the state register - in al, dx - ; Check the state of BSY signal - test al, 80h - jnz @@WaitHDReady_1 -; reset the error sign - mov [DevErrorCode], 0 - ret -; error processing -@@Err1_2: - mov [DevErrorCode], 1 - ret -@@Err3_2: - mov [DevErrorCode], 3 - ret -@@Err4_2: - mov [DevErrorCode], 4 -; write error code - ret -;----------------------------------------------------------------------------- -EndFindHDD: diff --git a/kernel/branches/Kolibri-F/detect/disks.inc b/kernel/branches/Kolibri-F/detect/disks.inc deleted file mode 100644 index 0001fb129..000000000 --- a/kernel/branches/Kolibri-F/detect/disks.inc +++ /dev/null @@ -1,15 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -include 'dev_fd.inc' -include 'dev_hdcd.inc' -include 'getcache.inc' -include 'sear_par.inc' - diff --git a/kernel/branches/Kolibri-F/detect/getcache.inc b/kernel/branches/Kolibri-F/detect/getcache.inc deleted file mode 100644 index c7f7bde80..000000000 --- a/kernel/branches/Kolibri-F/detect/getcache.inc +++ /dev/null @@ -1,209 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -;----------------------------------------------------------------------------- - pusha - - mov eax, [pg_data.pages_free] -; 1/32 - shr eax, 5 -; round off up to 8 pages - shr eax, 3 - shl eax, 3 -; translate pages in butes *4096 - shl eax, 12 -; check a upper size of the cache, no more than 1 Mb on the physical device - cmp eax, 1024*1024 - jbe @f - - mov eax, 1024*1024 - jmp .continue -;-------------------------------------- -@@: -; check a lower size of the cache, not less than 128 Kb on the physical device - cmp eax, 128*1024 - jae .continue - - mov eax, 128*1024 -;-------------------------------------- -.continue: - push ecx - mov ecx, 12 - mov esi, cache_ide0+IDE_CACHE.size - cld -@@: - mov [esi], eax - add esi, sizeof.IDE_CACHE - loop @b - - pop ecx - - xor eax, eax - mov [hdd_appl_data], 1 ;al - mov [cd_appl_data], 1 -;-------------------------------------- - test byte [DRIVE_DATA+1], 0x80 - je @f - - mov esi, cache_ide0 - call get_cache_ide -;-------------------------------------- -@@: - test byte [DRIVE_DATA+1], 0x20 - je @f - - mov esi, cache_ide1 - call get_cache_ide -;-------------------------------------- -@@: - test byte [DRIVE_DATA+1], 8 - je @f - - mov esi, cache_ide2 - call get_cache_ide -;-------------------------------------- -@@: - test byte [DRIVE_DATA+1], 2 - je @f - - mov esi, cache_ide3 - call get_cache_ide -;-------------------------------------- -@@: - test byte [DRIVE_DATA+6], 0x80 - je @f - - mov esi, cache_ide4 - call get_cache_ide -;-------------------------------------- -@@: - test byte [DRIVE_DATA+6], 0x20 - je @f - - mov esi, cache_ide5 - call get_cache_ide -;-------------------------------------- -@@: - test byte [DRIVE_DATA+6], 8 - je @f - - mov esi, cache_ide6 - call get_cache_ide -;-------------------------------------- -@@: - test byte [DRIVE_DATA+6], 2 - je @f - - mov esi, cache_ide7 - call get_cache_ide -;-------------------------------------- -@@: - test byte [DRIVE_DATA+11], 0x80 - je @f - - mov esi, cache_ide8 - call get_cache_ide -;-------------------------------------- -@@: - test byte [DRIVE_DATA+11], 0x20 - je @f - - mov esi, cache_ide9 - call get_cache_ide -;-------------------------------------- -@@: - test byte [DRIVE_DATA+11], 8 - je @f - - mov esi, cache_ide10 - call get_cache_ide -;-------------------------------------- -@@: - test byte [DRIVE_DATA+11], 2 - je end_get_cache - - mov esi, cache_ide11 - call get_cache_ide - - jmp end_get_cache -;----------------------------------------------------------------------------- -get_cache_ide: - and [esi+IDE_CACHE.search_start], 0 - and [esi+IDE_CACHE.appl_search_start], 0 - - push ecx -; DEBUGF 1, "K : IDE_CACHE.size %x\n", [esi+IDE_CACHE.size] - stdcall kernel_alloc, [esi+IDE_CACHE.size] - mov [esi+IDE_CACHE.pointer], eax - pop ecx - - mov edx, eax - mov eax, [esi+IDE_CACHE.size] - shr eax, 3 -; DEBUGF 1, "K : IDE_CACHE.system_data_size %x\n", eax - mov [esi+IDE_CACHE.system_data_size], eax - mov ebx, eax - imul eax, 7 -; DEBUGF 1, "K : IDE_CACHE.appl_data_size %x\n", eax - mov [esi+IDE_CACHE.appl_data_size], eax - add ebx, edx - mov [esi+IDE_CACHE.data_pointer], ebx - -.cd: - push ecx - mov eax, [esi+IDE_CACHE.system_data_size] - call calculate_for_cd - add eax, [esi+IDE_CACHE.pointer] - mov [esi+IDE_CACHE.system_data], eax - mov [esi+IDE_CACHE.system_sad_size], ecx - - push edi - mov edi, [esi+IDE_CACHE.pointer] - call clear_ide_cache - pop edi - - mov eax, [esi+IDE_CACHE.appl_data_size] - call calculate_for_cd - add eax, [esi+IDE_CACHE.data_pointer] - mov [esi+IDE_CACHE.appl_data], eax - mov [esi+IDE_CACHE.appl_sad_size], ecx - - push edi - mov edi, [esi+IDE_CACHE.data_pointer] - call clear_ide_cache - pop edi - - pop ecx - ret -;----------------------------------------------------------------------------- -calculate_for_cd: - push eax - mov ebx, eax - shr eax, 11 - shl eax, 3 - sub ebx, eax - shr ebx, 11 - mov ecx, ebx - shl ebx, 11 - pop eax - sub eax, ebx - dec ecx - ret -;----------------------------------------------------------------------------- -clear_ide_cache: - push eax - shl ecx, 1 - xor eax, eax - cld - rep stosd - pop eax - ret -;----------------------------------------------------------------------------- -end_get_cache: - popa diff --git a/kernel/branches/Kolibri-F/detect/init_ata.inc b/kernel/branches/Kolibri-F/detect/init_ata.inc deleted file mode 100644 index eccd10277..000000000 --- a/kernel/branches/Kolibri-F/detect/init_ata.inc +++ /dev/null @@ -1,492 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2014-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -;----------------------------------------------------------------------------- -; find the IDE controller in the device list -;----------------------------------------------------------------------------- - mov ecx, IDE_controller_1 - mov esi, pcidev_list -;-------------------------------------- -align 4 -.loop: - mov esi, [esi+PCIDEV.fd] - cmp esi, pcidev_list - jz find_IDE_controller_done - - mov eax, [esi+PCIDEV.class] -; shr eax, 4 -; cmp eax, 0x01018 - shr eax, 7 - cmp eax, 0x010180 shr 7 - jnz .loop -;-------------------------------------- -.found: - mov eax, [esi+PCIDEV.class] - DEBUGF 1, 'K : IDE controller programming interface %x\n', eax - mov [ecx+IDE_DATA.ProgrammingInterface], eax - mov [ecx+IDE_DATA.pcidev], esi - - mov ah, [esi+PCIDEV.bus] - mov al, 2 - mov bh, [esi+PCIDEV.devfn] -;-------------------------------------- - mov dx, 0x1F0 - test byte [esi+PCIDEV.class], 1 - jz @f - mov bl, 0x10 - push eax - call pci_read_reg - and eax, 0xFFFC - mov edx, eax - pop eax -@@: - DEBUGF 1, 'K : BAR0 IDE base addr %x\n', dx - mov [StandardATABases], dx - mov [ecx+IDE_DATA.BAR0_val], dx -;-------------------------------------- - mov dx, 0x3F4 - test byte [esi+PCIDEV.class], 1 - jz @f - mov bl, 0x14 - push eax - call pci_read_reg - and eax, 0xFFFC - mov edx, eax - pop eax -@@: - DEBUGF 1, 'K : BAR1 IDE base addr %x\n', dx - mov [ecx+IDE_DATA.BAR1_val], dx -;-------------------------------------- - mov dx, 0x170 - test byte [esi+PCIDEV.class], 4 - jz @f - mov bl, 0x18 - push eax - call pci_read_reg - and eax, 0xFFFC - mov edx, eax - pop eax -@@: - DEBUGF 1, 'K : BAR2 IDE base addr %x\n', dx - mov [StandardATABases+2], dx - mov [ecx+IDE_DATA.BAR2_val], dx -;-------------------------------------- - mov dx, 0x374 - test byte [esi+PCIDEV.class], 4 - jz @f - mov bl, 0x1C - push eax - call pci_read_reg - and eax, 0xFFFC - mov edx, eax - pop eax -@@: - DEBUGF 1, 'K : BAR3 IDE base addr %x\n', dx - mov [ecx+IDE_DATA.BAR3_val], dx -;-------------------------------------- - mov bl, 0x20 - push eax - call pci_read_reg - and eax, 0xFFFC - DEBUGF 1, 'K : BAR4 IDE controller register base addr %x\n', ax - mov [ecx+IDE_DATA.RegsBaseAddres], ax - pop eax -;-------------------------------------- - mov bl, 0x3C - push eax - call pci_read_reg - and eax, 0xFF - DEBUGF 1, 'K : IDE Interrupt %x\n', al - mov [ecx+IDE_DATA.Interrupt], ax - pop eax - - add ecx, sizeof.IDE_DATA -;-------------------------------------- - jmp .loop -;----------------------------------------------------------------------------- -uglobal -align 4 -;-------------------------------------- -IDE_controller_pointer dd ? -;-------------------------------------- -IDE_controller_1 IDE_DATA -IDE_controller_2 IDE_DATA -IDE_controller_3 IDE_DATA -;-------------------------------------- -cache_ide0 IDE_CACHE -cache_ide1 IDE_CACHE -cache_ide2 IDE_CACHE -cache_ide3 IDE_CACHE -cache_ide4 IDE_CACHE -cache_ide5 IDE_CACHE -cache_ide6 IDE_CACHE -cache_ide7 IDE_CACHE -cache_ide8 IDE_CACHE -cache_ide9 IDE_CACHE -cache_ide10 IDE_CACHE -cache_ide11 IDE_CACHE -;-------------------------------------- -IDE_device_1 rd 2 -IDE_device_2 rd 2 -IDE_device_3 rd 2 -;-------------------------------------- -endg - -;-------------------------------------- -; set Bus Master bit of Command PCI register -;-------------------------------------- -set_pci_command_bus_master: -PCI_COMMAND_BUS_MASTER = 0x0004 - push eax ecx - - mov ecx, [ecx+IDE_DATA.pcidev] - mov ah, [ecx+PCIDEV.bus] - mov al, 1 ; word - mov bh, [ecx+PCIDEV.devfn] - mov bl, 0x4 ; Command register - push eax - call pci_read_reg - mov ecx, eax - pop eax - test ecx, PCI_COMMAND_BUS_MASTER ; already set? - jnz @f - or ecx, PCI_COMMAND_BUS_MASTER - call pci_write_reg -@@: - pop ecx eax - ret - -;----------------------------------------------------------------------------- -; START of initialisation IDE ATA code -;----------------------------------------------------------------------------- -Init_IDE_ATA_controller: - cmp [ecx+IDE_DATA.ProgrammingInterface], 0 - jne @f - - ret -;-------------------------------------- -@@: - mov esi, boot_disabling_ide - call boot_log -;-------------------------------------- -; Disable IDE interrupts, because the search -; for IDE partitions is in the PIO mode. -;-------------------------------------- -.disable_IDE_interrupt: -; Disable interrupts in IDE controller for PIO - mov al, 2 - mov dx, [ecx+IDE_DATA.BAR1_val] ;0x3F4 - add dx, 2 ;0x3F6 - out dx, al - mov dx, [ecx+IDE_DATA.BAR3_val] ;0x374 - add dx, 2 ;0x376 - out dx, al -;----------------------------------------------------------------------------- -; set current ata bases -@@: - mov ax, [ecx+IDE_DATA.BAR0_val] - mov [StandardATABases], ax - mov ax, [ecx+IDE_DATA.BAR2_val] - mov [StandardATABases+2], ax - - mov esi, boot_detecthdcd - call boot_log -;-------------------------------------- -include 'dev_hdcd.inc' -;-------------------------------------- - ret -;----------------------------------------------------------------------------- -Init_IDE_ATA_controller_2: - cmp [ecx+IDE_DATA.ProgrammingInterface], 0 - jne @f - - ret -;-------------------------------------- -@@: - mov dx, [ecx+IDE_DATA.RegsBaseAddres] -; test whether it is our interrupt? - add dx, 2 - in al, dx - test al, 100b - jz @f -; clear Bus Master IDE Status register -; clear Interrupt bit - out dx, al -;-------------------------------------- -@@: - add dx, 8 -; test whether it is our interrupt? - in al, dx - test al, 100b - jz @f -; clear Bus Master IDE Status register -; clear Interrupt bit - out dx, al -;-------------------------------------- -@@: -; read status register and remove the interrupt request - mov dx, [ecx+IDE_DATA.BAR0_val] ;0x1F0 - add dx, 0x7 ;0x1F7 - in al, dx - mov dx, [ecx+IDE_DATA.BAR2_val] ;0x170 - add dx, 0x7 ;0x177 - in al, dx -;----------------------------------------------------------------------------- -; push eax edx -; mov dx, [ecx+IDE_DATA.RegsBaseAddres] -; xor eax, eax -; add dx, 2 -; in al, dx -; DEBUGF 1, "K : Primary Bus Master IDE Status Register %x\n", eax - -; add dx, 8 -; in al, dx -; DEBUGF 1, "K : Secondary Bus Master IDE Status Register %x\n", eax -; pop edx eax - -; cmp [ecx+IDE_DATA.RegsBaseAddres], 0 -; setnz [ecx+IDE_DATA.dma_hdd] -;----------------------------------------------------------------------------- -; set interrupts for IDE Controller -;----------------------------------------------------------------------------- - pushfd - cli -.enable_IDE_interrupt: - mov esi, boot_enabling_ide - call boot_log -; Enable interrupts in IDE controller for DMA - xor ebx, ebx - cmp ecx, IDE_controller_2 - jne @f - - add ebx, 5 - jmp .check_DRIVE_DATA -;-------------------------------------- -@@: - cmp ecx, IDE_controller_3 - jne .check_DRIVE_DATA - - add ebx, 10 -;-------------------------------------- -.check_DRIVE_DATA: - mov al, 0 - mov ah, [ebx+DRIVE_DATA+1] - test ah, 10100000b ; check for ATAPI devices - jz @f -;-------------------------------------- -.ch1_pio_set_ATAPI: - DEBUGF 1, "K : IDE CH1 PIO, because ATAPI drive present\n" - jmp .ch1_pio_set_for_all -;-------------------------------------- -.ch1_pio_set_no_devices: - DEBUGF 1, "K : IDE CH1 PIO because no devices\n" - jmp .ch1_pio_set_for_all -;------------------------------------- -.ch1_pio_set: - DEBUGF 1, "K : IDE CH1 PIO because device not support UDMA\n" -;------------------------------------- -.ch1_pio_set_for_all: - mov [ecx+IDE_DATA.dma_hdd_channel_1], al - jmp .ch2_check -;-------------------------------------- -@@: - xor ebx, ebx - call calculate_IDE_device_values_storage - - test ah, 1010000b - jz .ch1_pio_set_no_devices - - test ah, 1000000b - jz @f - - cmp [ebx+IDE_DEVICE.UDMA_possible_modes], al - je .ch1_pio_set - - cmp [ebx+IDE_DEVICE.UDMA_set_mode], al - je .ch1_pio_set -;-------------------------------------- -@@: - test ah, 10000b - jz @f - - add ebx, 2 - - cmp [ebx+IDE_DEVICE.UDMA_possible_modes], al - je .ch1_pio_set - - cmp [ebx+IDE_DEVICE.UDMA_set_mode], al - je .ch1_pio_set -;-------------------------------------- -@@: - mov dx, [ecx+IDE_DATA.BAR1_val] ;0x3F4 - add dx, 2 ;0x3F6 - out dx, al - call set_pci_command_bus_master - DEBUGF 1, "K : IDE CH1 DMA enabled\n" - mov [ecx+IDE_DATA.dma_hdd_channel_1], byte 1 -;-------------------------------------- -.ch2_check: - test ah, 1010b ; check for ATAPI devices - jz @f -;-------------------------------------- -.ch2_pio_set_ATAPI: - DEBUGF 1, "K : IDE CH2 PIO, because ATAPI drive present\n" - jmp .ch2_pio_set_for_all -;-------------------------------------- -.ch2_pio_set_no_devices: - DEBUGF 1, "K : IDE CH2 PIO because no devices\n" - jmp .ch2_pio_set_for_all -;-------------------------------------- -.ch2_pio_set: - DEBUGF 1, "K : IDE CH2 PIO because device not support UDMA\n" -;-------------------------------------- -.ch2_pio_set_for_all: - mov [ecx+IDE_DATA.dma_hdd_channel_2], al - jmp .set_interrupts_for_IDE_controllers -;-------------------------------------- -@@: - mov ebx, 4 - call calculate_IDE_device_values_storage - - test ah, 101b - jz .ch2_pio_set_no_devices - - test ah, 100b - jz @f - - cmp [ebx+IDE_DEVICE.UDMA_possible_modes], al - je .ch2_pio_set - - cmp [ebx+IDE_DEVICE.UDMA_set_mode], al - je .ch2_pio_set -;-------------------------------------- -@@: - test ah, 1b - jz @f - - add ebx, 2 - - cmp [ebx+IDE_DEVICE.UDMA_possible_modes], al - je .ch2_pio_set - - cmp [ebx+IDE_DEVICE.UDMA_set_mode], al - je .ch2_pio_set -;-------------------------------------- -@@: - mov dx, [ecx+IDE_DATA.BAR3_val] ;0x374 - add dx, 2 ;0x376 - out dx, al - call set_pci_command_bus_master - DEBUGF 1, "K : IDE CH2 DMA enabled\n" - mov [ecx+IDE_DATA.dma_hdd_channel_2], byte 1 -;-------------------------------------- -.set_interrupts_for_IDE_controllers: - mov esi, boot_set_int_IDE - call boot_log -;-------------------------------------- - mov eax, [ecx+IDE_DATA.ProgrammingInterface] -; cmp ax, 0x0180 -; je .pata_ide - -; cmp ax, 0x018a -; jne .sata_ide - - test al, 1 ; 0 - legacy PCI mode, 1 - native PCI mode - jnz .sata_ide -;-------------------------------------- -.pata_ide: - cmp [ecx+IDE_DATA.RegsBaseAddres], 0 - je .end_set_interrupts - - push ecx - stdcall attach_int_handler, 14, IDE_irq_14_handler, ecx - pop ecx - DEBUGF 1, "K : Set IDE IRQ14 return code %x\n", eax - push ecx - stdcall attach_int_handler, 15, IDE_irq_15_handler, ecx - DEBUGF 1, "K : Set IDE IRQ15 return code %x\n", eax - pop ecx - - jmp .end_set_interrupts -;-------------------------------------- -.sata_ide: -; cmp ax, 0x0185 -; je .sata_ide_1 - -; cmp ax, 0x018f -; jne .end_set_interrupts -;-------------------------------------- -;.sata_ide_1: -; Some weird controllers generate an interrupt even if IDE interrupts -; are disabled and no IDE devices. For example, notebook ASUS K72F - -; IDE controller 010185 generates false interrupt when we work with -; the IDE controller 01018f. For this reason, the interrupt handler -; does not need to be installed if both channel IDE controller -; running in PIO mode. - -; ...unfortunately, PCI interrupt can be shared with other devices -; which could enable it without consulting IDE code. -; So install the handler anyways and try to process -; even those interrupts which we are not expecting. - cmp [ecx+IDE_DATA.RegsBaseAddres], 0 - je .end_set_interrupts - - mov ax, [ecx+IDE_DATA.Interrupt] - movzx eax, al - push ecx - stdcall attach_int_handler, eax, IDE_common_irq_handler, ecx - pop ecx - DEBUGF 1, "K : Set IDE IRQ%d return code %x\n", [ecx+IDE_DATA.Interrupt]:1, eax -;-------------------------------------- -.end_set_interrupts: - popfd - ret -;----------------------------------------------------------------------------- -; END of initialisation IDE ATA code -;----------------------------------------------------------------------------- -find_IDE_controller_done: - mov ecx, IDE_controller_1 - mov [IDE_controller_pointer], ecx - call Init_IDE_ATA_controller - mov ecx, IDE_controller_2 - mov [IDE_controller_pointer], ecx - call Init_IDE_ATA_controller - mov ecx, IDE_controller_3 - mov [IDE_controller_pointer], ecx - call Init_IDE_ATA_controller -;----------------------------------------------------------------------------- - mov esi, boot_getcache - call boot_log -include 'getcache.inc' -;----------------------------------------------------------------------------- - mov esi, boot_detectpart - call boot_log -include 'sear_par.inc' -;----------------------------------------------------------------------------- - mov esi, boot_init_sys - call boot_log - call Parser_params - -if ~ defined extended_primary_loader -; ramdisk image should be loaded by extended primary loader if it exists -; READ RAMDISK IMAGE FROM HD -include '../boot/rdload.inc' -end if -;----------------------------------------------------------------------------- - mov ecx, IDE_controller_1 - mov [IDE_controller_pointer], ecx - call Init_IDE_ATA_controller_2 - mov ecx, IDE_controller_2 - mov [IDE_controller_pointer], ecx - call Init_IDE_ATA_controller_2 - mov ecx, IDE_controller_3 - mov [IDE_controller_pointer], ecx - call Init_IDE_ATA_controller_2 -;----------------------------------------------------------------------------- diff --git a/kernel/branches/Kolibri-F/detect/sear_par.inc b/kernel/branches/Kolibri-F/detect/sear_par.inc deleted file mode 100644 index 1c896a27b..000000000 --- a/kernel/branches/Kolibri-F/detect/sear_par.inc +++ /dev/null @@ -1,280 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -search_partitions: - push ecx -; 1. Fill missing parameters in HD_DATA structures. - xor eax, eax - mov edx, IDE_controller_1 - mov ax, [edx + IDE_DATA.BAR0_val] - mov [hd0_data.hdbase], ax - mov [hd1_data.hdbase], ax - mov ax, [edx + IDE_DATA.BAR2_val] - mov [hd2_data.hdbase], ax - mov [hd3_data.hdbase], ax - - mov edx, IDE_controller_2 - mov ax, [edx + IDE_DATA.BAR0_val] - mov [hd4_data.hdbase], ax - mov [hd5_data.hdbase], ax - mov ax, [edx + IDE_DATA.BAR2_val] - mov [hd6_data.hdbase], ax - mov [hd7_data.hdbase], ax - - mov edx, IDE_controller_3 - mov ax, [edx + IDE_DATA.BAR0_val] - mov [hd8_data.hdbase], ax - mov [hd9_data.hdbase], ax - mov ax, [edx + IDE_DATA.BAR2_val] - mov [hd10_data.hdbase], ax - mov [hd11_data.hdbase], ax -; 2. Notify the system about /hd* disks. -; For every existing disk, call ide_disk_add with correct parameters. -; Generate name "hdN" on the stack; this is 4 bytes including terminating zero. -;----------------------------------------------------------------------------- -; 2a. /hd0: exists if mask 0x40 in [DRIVE_DATA+1] is set, -; data: hd0_data, -; number of partitions: [DRIVE_DATA+2] - test [DRIVE_DATA+1], byte 0x40 - jz @f - - push 'hd0' - mov eax, esp ; name - mov edx, hd0_data - call ide_disk_add - mov [DRIVE_DATA+2], al - pop ecx ; restore the stack -;----------------------------------------------------------------------------- -@@: -; 2b. /hd1: exists if mask 0x10 in [DRIVE_DATA+1] is set, -; data: hd1_data, -; number of partitions: [DRIVE_DATA+3] - test [DRIVE_DATA+1], byte 0x10 - jz @f - - push 'hd1' - mov eax, esp - mov edx, hd1_data - call ide_disk_add - mov [DRIVE_DATA+3], al - pop ecx -;----------------------------------------------------------------------------- -@@: -; 2c. /hd2: exists if mask 4 in [DRIVE_DATA+1] is set, -; data: hd2_data, -; number of partitions: [DRIVE_DATA+4] - test [DRIVE_DATA+1], byte 4 - jz @f - - push 'hd2' - mov eax, esp - mov edx, hd2_data - call ide_disk_add - mov [DRIVE_DATA+4], al - pop ecx -;----------------------------------------------------------------------------- -@@: -; 2d. /hd3: exists if mask 1 in [DRIVE_DATA+1] is set, -; data: hd3_data, -; number of partitions: [DRIVE_DATA+5] - test [DRIVE_DATA+1], byte 1 - jz @f - - push 'hd3' - mov eax, esp - mov edx, hd3_data - call ide_disk_add - mov [DRIVE_DATA+5], al - pop ecx -;----------------------------------------------------------------------------- -@@: -; 2e. /hd4: exists if mask 0x40 in [DRIVE_DATA+6] is set, -; data: hd4_data, -; number of partitions: [DRIVE_DATA+7] - test [DRIVE_DATA+6], byte 0x40 - jz @f - - push 'hd4' - mov eax, esp ; name - mov edx, hd4_data - call ide_disk_add - mov [DRIVE_DATA+7], al - pop ecx -;----------------------------------------------------------------------------- -@@: -; 2f. /hd5: exists if mask 0x10 in [DRIVE_DATA+6] is set, -; data: hd5_data, -; number of partitions: [DRIVE_DATA+8] - test [DRIVE_DATA+6], byte 0x10 - jz @f - - push 'hd5' - mov eax, esp - mov edx, hd5_data - call ide_disk_add - mov [DRIVE_DATA+8], al - pop ecx -;----------------------------------------------------------------------------- -@@: -; 2g. /hd6: exists if mask 4 in [DRIVE_DATA+6] is set, -; data: hd6_data, -; number of partitions: [DRIVE_DATA+9] - test [DRIVE_DATA+6], byte 4 - jz @f - - push 'hd6' - mov eax, esp - mov edx, hd6_data - call ide_disk_add - mov [DRIVE_DATA+9], al - pop ecx -;----------------------------------------------------------------------------- -@@: -; 2h. /hd7: exists if mask 1 in [DRIVE_DATA+6] is set, -; data: hd7_data, -; number of partitions: [DRIVE_DATA+10] - test [DRIVE_DATA+6], byte 1 - jz @f - - push 'hd7' - mov eax, esp - mov edx, hd7_data - call ide_disk_add - mov [DRIVE_DATA+10], al - pop ecx -;----------------------------------------------------------------------------- -@@: -; 2i. /hd8: exists if mask 0x40 in [DRIVE_DATA+11] is set, -; data: hd8_data, -; number of partitions: [DRIVE_DATA+12] - test [DRIVE_DATA+11], byte 0x40 - jz @f - - push 'hd8' - mov eax, esp ; name - mov edx, hd8_data - call ide_disk_add - mov [DRIVE_DATA+12], al - pop ecx -;----------------------------------------------------------------------------- -@@: -; 2j. /hd9: exists if mask 0x10 in [DRIVE_DATA+11] is set, -; data: hd9_data, -; number of partitions: [DRIVE_DATA+13] - test [DRIVE_DATA+11], byte 0x10 - jz @f - - push 'hd9' - mov eax, esp - mov edx, hd9_data - call ide_disk_add - mov [DRIVE_DATA+13], al - pop ecx -;----------------------------------------------------------------------------- -@@: -; 2k. /hd10: exists if mask 4 in [DRIVE_DATA+11] is set, -; data: hd10_data, -; number of partitions: [DRIVE_DATA+14] - test [DRIVE_DATA+14], byte 4 - jz @f - - push 'hd10' - mov eax, esp - mov edx, hd10_data - call ide_disk_add - mov [DRIVE_DATA+9], al - pop ecx -;----------------------------------------------------------------------------- -@@: -; 2l. /hd11: exists if mask 1 in [DRIVE_DATA+11] is set, -; data: hd11_data, -; number of partitions: [DRIVE_DATA+15] - test [DRIVE_DATA+11], byte 1 - jz @f - - push 'hd11' - mov eax, esp - mov edx, hd11_data - call ide_disk_add - mov [DRIVE_DATA+15], al - pop ecx -;----------------------------------------------------------------------------- -@@: -; 3. Notify the system about /bd* disks. -; 3a. Check whether there are BIOS disks. If no, skip step 3. - xor esi, esi - cmp esi, [NumBiosDisks] - jz .nobd -; Loop over all disks. - push 0 - push 'bd' -.bdloop: -; 3b. Get the drive number for using in /bd* name. - lea eax, [esi*4] - movzx eax, [BiosDisksData+eax*4+BiosDiskData.DriveNumber] - sub al, 80h -; 3c. Convert eax to decimal and store starting with [esp+3]. -; First 2 bytes in [esp] are "bd". - lea edi, [esp+2] -; store digits in the stack, ending with -'0' - push -'0' -@@: - xor edx, edx -iglobal -align 4 -_10 dd 10 -endg - div [_10] - push edx - test eax, eax - jnz @b -; restore digits from the stack, this reverses the order; -; add '0', stop, when zero is reached -@@: - pop eax - add al, '0' - stosb - jnz @b -; 3e. Call the API with userdata = 80h + ecx. - mov eax, esp - lea edx, [esi+80h] - stdcall disk_add, bd_callbacks, eax, edx, 0 - test eax, eax - jz @f - stdcall disk_media_changed, eax, 1 -@@: -; 3f. Continue the loop. - inc esi - cmp esi, [NumBiosDisks] - jnz .bdloop - pop ecx ecx ; restore stack after name -.nobd: - jmp end_search_partitions -;----------------------------------------------------------------------------- -; Helper procedure for search_partitions, adds one IDE disk. -; For compatibility, number of partitions for IDE disks is kept in a separate -; variable, so the procedure returns number of partitions. -; eax -> name, edx -> disk data -proc ide_disk_add - stdcall disk_add, ide_callbacks, eax, edx, 0 - test eax, eax - jz @f - push eax - stdcall disk_media_changed, eax, 1 - pop eax - mov eax, [eax+DISK.NumPartitions] - cmp eax, 255 - jbe @f - mov eax, 255 -@@: - ret -endp -;----------------------------------------------------------------------------- -end_search_partitions: - pop ecx diff --git a/kernel/branches/Kolibri-F/detect/vortex86.inc b/kernel/branches/Kolibri-F/detect/vortex86.inc deleted file mode 100644 index 5dd751c00..000000000 --- a/kernel/branches/Kolibri-F/detect/vortex86.inc +++ /dev/null @@ -1,158 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; 20/11/2013 yogev_ezra: Initial version (Vortex86 SoC type detection) -; 26/11/2013 yogev_ezra: Added CPU speed modifier and MMX support flag detection -; Thanks for help to: dunkaist, eAndrew, hidnplayr, Mario - -$Revision$ - -VORTEX86DEBUG = 0 ; For testing in emulators and in non-Vortex86 CPU computers, set this to 1 -VORTEX86DEBUGVALUE = 'DMP5' ; FAKE port output = used for testing -NORTH_BRIDGE = 0x80000000 ; Base address of Vortex86 PCI North Bridge -SOUTH_BRIDGE = 0x80003800 ; Base address of Vortex86 PCI South Bridge - -; Detect Vortex86 CPU and generate CPU name in string format (PCI address at 93H~90H in Vortex86 North Bridge contains SoC type) -; Available Vortex86 CPU codes taken from Coreboot project. New codes should be added to "Vortex86SoClist" below -; #define DMP_CPUID_SX 0x31504d44 ("DMP1") -; #define DMP_CPUID_DX 0x32504d44 ("DMP2") -; #define DMP_CPUID_MX 0x33504d44 ("DMP3") -; #define DMP_CPUID_DX2 0x34504d44 ("DMP4") -; #define DMP_CPUID_MX_PLUS 0x35504d44 ("DMP5") -; #define DMP_CPUID_EX 0x37504d44 ("DMP7") - -iglobal -Vortex86CPUcode dd ? ; Vortex86 CPU code in HEX format (4 bytes), can be shown as string if converted to ASCII characters -Vortex86CPUid db 0 ; Vortex86 CPU id in integer format (1=Vortex86SX, 2=Vortex86DX, ...) -Vortex86SoCname db 'Vortex86 ',0 ; This variable will hold the full name of Vortex86 SoC -Vortex86SoClist: ; List of Vortex86 CPUs known today. Add new record to this list when new CPU becomes available - db 0x31, 'SX ' ; id=1 - db 0x32, 'DX ' ; id=2 - db 0x33, 'MX ' ; id=3 MMX is available starting from CPU code 'MX' (id=3) - db 0x34, 'DX2' ; id=4 - db 0x35, 'MX+' ; id=5 - db 0x37, 'EX ' ; id=7 -Vortex86SoCnum = ($ - Vortex86SoClist) / 4 ; Calculate the total number of known Vortex86 CPUs -endg - -; When in debug mode, perform SoC detection regardless of the actual CPU vendor (even for vendors other than DMP) -; When in normal (not debug) mode, check the CPU vendor first, and perform SoC detection only if vendor is 'Vortex86 SoC' -if ~ VORTEX86DEBUG - cmp [cpu_vendor], 'Vort' - jnz .Vortex86end ; If the CPU vendor is not 'Vortex86 SoC', skip the SoC detection -end if - - mov eax, NORTH_BRIDGE+0x90 ; 0x80000090 = PCI Configuration Address Register to read from (32-bit register - accessed as DWORD) - call .Vortex86PCIreg ; Get the CPU code from Vortex86 SoC North Bridge PCI register (Register Offset: 93H~90H) - -if VORTEX86DEBUG ; When in debug mode, pretend that we received port output equal to "VORTEX86DEBUGVALUE" - mov eax, VORTEX86DEBUGVALUE -end if - - DEBUGF 1, "K : Vortex86 SoC type register (93H~90H) returned 0x" - test eax, eax ; Check whether the port output was '\0' - jz .nullPCIoutput ; In case the result is '\0' (NULL), skip further testing and exit - mov [Vortex86CPUcode], eax ; Save HEX CPU code to Vortex86CPUcode (so it can be used later) - DEBUGF 1, "%x (%s): ", eax, Vortex86CPUcode ; Print the CPU code (as HEX and as string) to debug log - - mov ebx, 0x444d5000 ; Apply Vortex86 CPU code mask (all Vortex86 SoC have ID in form of "0xNN504d44") - bswap eax ; Assumed it is Vortex86 SoC, the highest byte identifies the exact CPU, so move it to the lowest byte - mov bl, al ; Copy SoC type to BL since EAX (that includes AL) is used implicitly in "LODSD" command below - cmp eax, ebx ; Now see whether the 3 higher bytes were "0x504d44" (which means it's Vortex86) - jnz .notVortex86 ; If it's not Vortex86 - go say so and exit - - sub al, 0x30 ; Current Vortex86 CPU codes are in the range of 31h-37h, so convert them to integer (1,2,...) - mov [Vortex86CPUid], al ; Save the CPUid (1=Vortex86SX, 2=Vortex86DX, ..., 7=Vortex86EX, ...) - - mov esi, Vortex86SoClist ; ESI points to the start of Vortex86SoClist (used implicitly in "LODSD" command below) - xor ecx, ecx ; Zero ECX (it is used as counter) - cld ; Clears the DF flag in the EFLAGS register (DF=0 --> String operations increment ESI) -@@: - inc ecx ; Increment our counter - cmp ecx, Vortex86SoCnum ; Check if we iterated Vortex86SoCnum times already (i.e. went over the entire Vortex86SoClist) - ja .unknownVortex86 ; If the entire list was tested and our CPU is not in that list, it is unknown Vortex86 SoC - lodsd ; Load DWORD at address DS:ESI into EAX (puts 1 line from Vortex86SoClist into EAX, then increments ESI) - cmp bl, al ; Check if our CPU matches the current record in the list - jne @b ; No match --> repeat with next record - - shr eax, 8 ; Match found --> drop the SoC type code from Vortex86SoClist name and replace it with \0 - mov dword [Vortex86SoCname+8], eax ; Concatenate it with prefix to receive complete SoC name (\0 is string termination) - - DEBUGF 1, "%s (id=%d)\n", Vortex86SoCname, [Vortex86CPUid]:1 ; Say what we have found (CPU name and id) - jmp .Vortex86 - -.notVortex86: ; In case this register is used by other CPUs for other purpose, it's interesting what it contains - DEBUGF 1, "not a Vortex86 CPU\n" - jmp .Vortex86end - -.unknownVortex86: ; It is Vortex86 CPU, but it's not in the list above - DEBUGF 1, "unknown Vortex86 CPU (id=%d)\n", [Vortex86CPUid]:1 ; Inform the user that the CPU is Vortex86 but name is unknown - -.Vortex86: - mov eax, NORTH_BRIDGE+0x60 ; 0x80000060 = PCI Configuration Address Register to read from (32-bit register - accessed as DWORD) - call .Vortex86PCIreg ; Get current flags of Vortex86SoC North Bridge STRAP Register (Register Offset: 63h~60h) - DEBUGF 1, "K : Vortex86 STRAP Register (63h~60h) returned 0x%x\n",eax - - mov eax, SOUTH_BRIDGE+0xC0 ; 0x800038C0 = PCI Configuration Address Register to read from (32-bit register - accessed as DWORD) - call .Vortex86PCIreg ; Flags of Vortex86 South Bridge Internal Peripheral Feature Control Register (Register Offset: C3h~C0h) - DEBUGF 1, "K : Vortex86 Internal Peripheral Feature Control Register (C3h~C0h) returned 0x%x\n",eax - - mov eax, SOUTH_BRIDGE+0xCC ; 0x800038CC = PCI Configuration Address Register to read from (8-bit register - accessed as BYTE) - call .Vortex86PCIreg ; Flags of Vortex86 South Bridge Internal Peripheral Feature Control Register III (Register Offset: CCh) - DEBUGF 1, "K : Vortex86 Internal Peripheral Feature Control Register III (CCh) returned 0x%x\n",al - - mov eax, NORTH_BRIDGE+0xA0 ; 0x800000A0 = PCI Configuration Address Register to read from (32-bit register - accessed as DWORD) - call .Vortex86PCIreg ; Get current flags of Vortex86SoC North Bridge Host Control Register (Register Offset: A3h~A0h) - DEBUGF 1, "K : Vortex86 Host Control Register (A3h~A0h) returned 0x%x: CPU speed is ",eax - mov bl, al ; The lower byte of Vortex86 Host Control Register contains CPU speed modifier and MMX support status - mov bh, al ; Backup the current AL value, so later we can test whether the value has changed - and bl, 00000111b ; CPU speed modifier is stored in bits 0-2. Value=0 means MAX speed, other values - speed reduction - jz .Vortex86CPUspeedMAX ; 0s in bits 0-2: CPU is at MAX speed (no need to modify) - inc ebx ; The actual value is 1 less than 'Divide by' setting (value '001' means 'Divide by 2', etc.) - DEBUGF 1, "reduced (divide by %d).\nK : Vortex86 changing CPU speed to ", bl ; Print the current CPU speed modifier to the log - and al, 11111000b ; At least one of the bits 0-2 contains 1: CPU is at reduced speed. Set bits 0-2 to 0s to change to MAX -.Vortex86CPUspeedMAX: - DEBUGF 1, "MAX\n" ; Now the CPU should be running at MAX speed (don't write the value to PCI port yet) - - cmp [Vortex86CPUid], 3 ; MMX is available starting from CPU code 'MX' (id=3) - jb .skipVortex86MMX ; No MMX support - skip MMX support status detection (for id=1,2) - DEBUGF 1, "K : Vortex86 MMX support status: MMX is " ; Bits 5-6 in Host Control Register contain MMX status - test al, 100000b ; On MMX-capable Vortex86 SoC, Bit5 = is MMX enabled? (1=Yes/0=No) - jnz .Vortex86MMXenabled ; MMX is already enabled (Bit5=1) - DEBUGF 1, "DISABLED - enabling it for this session\n" ; Print to the log that MMX is disabled - or al, 100000b ; Enable MMX support (don't write the value to PCI port yet) - jmp .AfterMMXenabled -.Vortex86MMXenabled: - DEBUGF 1, "ENABLED\n" ; Print to the log that MMX is enabled -.AfterMMXenabled: - DEBUGF 1, "K : Vortex86 MMX report to CPUID: " ; Print to the log what CPUID command knowns about MMX support - test al, 1000000b ; On MMX-capable Vortex86 SoC, Bit6 = report MMX support to CPUID? (1=Yes/0=No) - jnz .Vortex86MMXreported ; MMX is already reported to CPUID (Bit6=1) - DEBUGF 1, "OFF - turning it ON for this session\n" ; Print to the log that MMX will now be reported to CPUID - or al, 1000000b ; Turn on MMX reporting to CPUID (don't write the value to PCI port yet) - jmp .skipVortex86MMX -.Vortex86MMXreported: - DEBUGF 1, "ON\n" ; Print to the log that MMX reporting to CPUID is enabled - -.skipVortex86MMX: - cmp bh, al ; Check whether AL has changed before (if it did, we need to write it back to PCI port) - jz .Vortex86end ; No change - no need to write to the port - out dx, al ; Write the changed data to PCI port - DEBUGF 1, "K : Vortex86 Host Control Register (A3h~A0h) new value is 0x%x\n",eax - jmp .Vortex86end - -.Vortex86PCIreg: ; Procedure receives input register value in EAX, and returns the output value also in EAX - mov dx, 0xcf8 ; CF8h = Vortex86 PCI Configuration Address port - out dx, eax ; Send request to PCI address port to retrieve data from this address - mov dl, 0xfc ; CFCh = Vortex86 PCI Configuration Data port - in eax, dx ; Read data from PCI data port - ret - -.nullPCIoutput: ; Emulators and non-Vortex86 CPU computers will usually return \0 in this register - DEBUGF 1, "0 (NULL)\n" - -.Vortex86end: diff --git a/kernel/branches/Kolibri-F/docs/apm.txt b/kernel/branches/Kolibri-F/docs/apm.txt deleted file mode 100644 index 5b253195e..000000000 --- a/kernel/branches/Kolibri-F/docs/apm.txt +++ /dev/null @@ -1,518 +0,0 @@ ---------p-155300----------------------------- -INT 15 - Advanced Power Management v1.0+ - INSTALLATION CHECK - AX = 5300h - BX = device ID of system BIOS (0000h) -Return: CF clear if successful - AH = major version (BCD) - AL = minor version (BCD) - BX = 504Dh ("PM") - CX = flags (see #00472) - CF set on error - AH = error code (06h,09h,86h) (see #00473) -BUG: early versions of the Award Modular BIOS with built-in APM support - reportedly do not set BX on return - -Bitfields for APM flags: -Bit(s) Description (Table 00472) - 0 16-bit protected mode interface supported - 1 32-bit protected mode interface supported - 2 CPU idle call reduces processor speed - 3 BIOS power management disabled - 4 BIOS power management disengaged (APM v1.1) - 5-7 reserved - -(Table 00473) -Values for APM error code: - 01h power management functionality disabled - 02h interface connection already in effect - 03h interface not connected - 04h real-mode interface not connected - 05h 16-bit protected-mode interface already connected - 06h 16-bit protected-mode interface not supported - 07h 32-bit protected-mode interface already connected - 08h 32-bit protected-mode interface not supported - 09h unrecognized device ID - 0Ah invalid parameter value in CX - 0Bh (APM v1.1) interface not engaged - 0Ch (APM v1.2) function not supported - 0Dh (APM v1.2) Resume Timer disabled - 0Eh-1Fh reserved for other interface and general errors - 20h-3Fh reserved for CPU errors - 40h-5Fh reserved for device errors - 60h can't enter requested state - 61h-7Fh reserved for other system errors - 80h no power management events pending - 81h-85h reserved for other power management event errors - 86h APM not present - 87h-9Fh reserved for other power management event errors - A0h-FEh reserved - FFh undefined ---------p-155301----------------------------- -INT 15 - Advanced Power Management v1.0+ - CONNECT REAL-MODE INTERFACE - AX = 5301h - BX = device ID of system BIOS (0000h) -Return: CF clear if successful - CF set on error - AH = error code (02h,05h,07h,09h) (see #00473) -Note: on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 - compatibility mode until it is informed that the user supports a - newer version of APM (see AX=530Eh) -SeeAlso: AX=5302h,AX=5303h,AX=5304h ---------p-155302----------------------------- -INT 15 R - Advanced Power Management v1.0+ - CONNECT 16-BIT PROTMODE INTERFACE - AX = 5302h - BX = device ID of system BIOS (0000h) -Return: CF clear if successful - AX = real-mode segment base address of protected-mode 16-bit code - segment - BX = offset of entry point - CX = real-mode segment base address of protected-mode 16-bit data - segment - ---APM v1.1--- - SI = APM BIOS code segment length - DI = APM BIOS data segment length - CF set on error - AH = error code (02h,05h,06h,07h,09h) (see #00473) -Notes: the caller must initialize two consecutive descriptors with the - returned segment base addresses; these descriptors must be valid - whenever the protected-mode interface is called, and will have - their limits arbitrarily set to 64K. - the protected mode interface is invoked by making a far call with the - same register values as for INT 15; it must be invoked while CPL=0, - the code segment descriptor must have a DPL of 0, the stack must be - in a 16-bit segment and have enough room for BIOS use and possible - interrupts, and the current I/O permission bit map must allow access - to the I/O ports used for power management. - functions 00h-03h are not available from protected mode - on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 - compatibility mode until it is informed that the user supports a - newer version of APM (see AX=530Eh) -SeeAlso: AX=5301h,AX=5303h,AX=5304h ---------p-155303----------------------------- -INT 15 - Advanced Power Management v1.0+ - CONNECT 32-BIT PROTMODE INTERFACE - AX = 5303h - BX = device ID of system BIOS (0000h) -Return: CF clear if successful - AX = real-mode segment base address of protected-mode 32-bit code - segment - EBX = offset of entry point - CX = real-mode segment base address of protected-mode 16-bit code - segment - DX = real-mode segment base address of protected-mode 16-bit data - segment - ---APM v1.1--- - SI = APM BIOS code segment length - DI = APM BIOS data segment length - CF set on error - AH = error code (02h,05h,07h,08h,09h) (see #00473) -Notes: the caller must initialize three consecutive descriptors with the - returned segment base addresses for 32-bit code, 16-bit code, and - 16-bit data, respectively; these descriptors must be valid whenever - the protected-mode interface is called, and will have their limits - arbitrarily set to 64K. - the protected mode interface is invoked by making a far call to the - 32-bit code segment with the same register values as for INT 15; it - must be invoked while CPL=0, the code segment descriptor must have a - DPL of 0, the stack must be in a 32-bit segment and have enough room - for BIOS use and possible interrupts, and the current I/O permission - bit map must allow access to the I/O ports used for power management. - functions 00h-03h are not available from protected mode - on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 - compatibility mode until it is informed that the user supports a - newer version of APM (see AX=530Eh) -SeeAlso: AX=5301h,AX=5302h,AX=5304h ---------p-155304----------------------------- -INT 15 - Advanced Power Management v1.0+ - DISCONNECT INTERFACE - AX = 5304h - BX = device ID of system BIOS (0000h) -Return: CF clear if successful - CF set on error - AH = error code (03h,09h) (see #00473) -SeeAlso: AX=5301h,AX=5302h,AX=5303h ---------p-155305----------------------------- -INT 15 - Advanced Power Management v1.0+ - CPU IDLE - AX = 5305h -Return: CF clear if successful (after system leaves idle state) - CF set on error - AH = error code (03h,0Bh) (see #00473) -Notes: call when the system is idle and should be suspended until the next - system event or interrupt - should not be called from within a hardware interrupt handler to avoid - reentrance problems - if an interrupt causes the system to resume normal processing, the - interrupt may or may not have been handled when the BIOS returns - from this call; thus, the caller should allow interrupts on return - interrupt handlers may not retain control if the BIOS allows - interrupts while in idle mode even if they are able to determine - that they were called from idle mode - the caller should issue this call continuously in a loop until it needs - to perform some processing of its own -SeeAlso: AX=1000h,AX=5306h,INT 2F/AX=1680h ---------p-155306----------------------------- -INT 15 - Advanced Power Management v1.0+ - CPU BUSY - AX = 5306h -Return: CF clear if successful - CF set on error - AH = error code (03h,0Bh) (see #00473) -Notes: called to ensure that the system runs at full speed even on systems - where the BIOS is unable to recognize increased activity (especially - if interrupts are hooked by other programs and not chained to the - BIOS) - this call may be made even when the system is already running at full - speed, but it will create unnecessary overhead - should not be called from within a hardware interrupt handler to avoid - reentrance problems -SeeAlso: AX=5305h ---------p-155307----------------------------- -INT 15 - Advanced Power Management v1.0+ - SET POWER STATE - AX = 5307h - BX = device ID (see #00474) - CX = system state ID (see #00475) -Return: CF clear if successful - CF set on error - AH = error code (01h,03h,09h,0Ah,0Bh,60h) (see #00473) -Note: should not be called from within a hardware interrupt handler to avoid - reentrance problems -SeeAlso: AX=530Ch - -(Table 00474) -Values for APM device IDs: - 0000h system BIOS - 0001h all devices for which the system BIOS manages power - 01xxh display (01FFh for all attached display devices) - 02xxh secondary storage (02FFh for all attached secondary storage devices) - 03xxh parallel ports (03FFh for all attached parallel ports) - 04xxh serial ports (04FFh for all attached serial ports) ----APM v1.1+ --- - 05xxh network adapters (05FFh for all attached network adapters) - 06xxh PCMCIA sockets (06FFh for all) - 0700h-7FFFh reserved - 80xxh system battery devices (APM v1.2) - 8100h-DFFFh reserved - Exxxh OEM-defined power device IDs - F000h-FFFFh reserved - -(Table 00475) -Values for system state ID: - 0000h ready (not supported for device ID 0001h) - 0001h stand-by - 0002h suspend - 0003h off (not supported for device ID 0001h in APM v1.0) ----APM v1.1--- - 0004h last request processing notification (only for device ID 0001h) - 0005h last request rejected (only for device ID 0001h) - 0006h-001Fh reserved system states - 0020h-003Fh OEM-defined system states - 0040h-007Fh OEM-defined device states - 0080h-FFFFh reserved device states ---------p-155307CX0001----------------------- -INT 15 - Advanced Power Management v1.0+ - SYSTEM STAND-BY - AX = 5307h - CX = 0001h - BX = 0001h (device ID for all power-managed devices) -Return: CF clear -Notes: puts the entire system into stand-by mode; normally called in response - to a System Stand-by Request notification after any necessary - processing, but may also be invoked at the caller's discretion - should not be called from within a hardware interrupt handler to avoid - reentrance problems - the stand-by state is typically exited on an interrupt -SeeAlso: AX=4280h,AX=5307h/CX=0002h"SUSPEND",AX=5307h/CX=0003h,AX=530Bh ---------p-155307CX0002----------------------- -INT 15 - Advanced Power Management v1.0+ - SUSPEND SYSTEM - AX = 5307h - CX = 0002h - BX = 0001h (device ID for all power-managed devices) -Return: after system is resumed - CF clear -Notes: puts the entire system into a low-power suspended state; normally - called in response to a Suspend System Request notification after - any necessary processing, but may also be invoked at the caller's - discretion - should not be called from within a hardware interrupt handler to avoid - reentrance problems - the caller may need to update its date and time values because the - system could have been suspended for a long period of time -SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh ---------p-155307CX0003----------------------- -INT 15 - Advanced Power Management v1.2 - TURN OFF SYSTEM - AX = 5307h - CX = 0003h - BX = 0001h (device ID for all power-managed devices) -Return: after system is resumed - CF clear -Notes: if supported by the system's power supply, turns off the system power -SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh ---------p-155308----------------------------- -INT 15 - Advanced Power Management v1.0+ - ENABLE/DISABLE POWER MANAGEMENT - AX = 5308h - BX = device ID for all devices power-managed by APM - 0001h (APM v1.1+) - FFFFh (APM v1.0) - CX = new state - 0000h disabled - 0001h enabled -Return: CF clear if successful - CF set on error - AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473) -Notes: when power management is disabled, the system BIOS will not - automatically power down devices, enter stand-by or suspended mode, - or perform any power-saving actions in response to AX=5305h calls - should not be called from within a hardware interrupt handler to avoid - reentrance problems - the APM BIOS should never be both disabled and disengaged at the same - time -SeeAlso: AX=5309h,AX=530Dh,AX=530Fh ---------p-155309----------------------------- -INT 15 - Advanced Power Management v1.0+ - RESTORE POWER-ON DEFAULTS - AX = 5309h - BX = device ID for all devices power-managed by APM - 0001h (APM v1.1) - FFFFh (APM v1.0) -Return: CF clear if successful - CF set on error - AH = error code (03h,09h,0Bh) (see #00473) -Note: should not be called from within a hardware interrupt handler to avoid - reentrance problems -SeeAlso: AX=5308h ---------p-15530A----------------------------- -INT 15 - Advanced Power Management v1.0+ - GET POWER STATUS - AX = 530Ah - BX = device ID - 0001h all devices power-managed by APM - 80xxh specific battery unit number XXh (01h-FFh) (APM v1.2) -Return: CF clear if successful - BH = AC line status - 00h off-line - 01h on-line - 02h on backup power (APM v1.1) - FFh unknown - other reserved - BL = battery status (see #00476) - CH = battery flag (APM v1.1+) (see #00477) - CL = remaining battery life, percentage - 00h-64h (0-100) percentage of full charge - FFh unknown - DX = remaining battery life, time (APM v1.1) (see #00478) - ---if specific battery unit specified--- - SI = number of battery units currently installed - CF set on error - AH = error code (09h,0Ah) (see #00473) -Notes: should not be called from within a hardware interrupt handler to avoid - reentrance problems - supported in real mode (INT 15) and both 16-bit and 32-bit protected - mode - -(Table 00476) -Values for APM v1.0+ battery status: - 00h high - 01h low - 02h critical - 03h charging - FFh unknown - other reserved -SeeAlso: #00477,#00478 - -Bitfields for APM v1.1+ battery flag: -Bit(s) Description (Table 00477) - 0 high - 1 low - 2 critical - 3 charging - 4 selected battery not present (APM v1.2) - 5-6 reserved (0) - 7 no system battery -Note: all bits set (FFh) if unknown -SeeAlso: #00476,#00478 - -Bitfields for APM v1.1+ remaining battery life: -Bit(s) Description (Table 00478) - 15 time units: 0=seconds, 1=minutes - 14-0 battery life in minutes or seconds -Note: all bits set (FFFFh) if unknown -SeeAlso: #00476,#00477 ---------p-15530B----------------------------- -INT 15 - Advanced Power Management v1.0+ - GET POWER MANAGEMENT EVENT - AX = 530Bh -Return: CF clear if successful - BX = event code (see #00479) - CX = event information (APM v1.2) if BX=0003h or BX=0004h - bit 0: PCMCIA socket was powered down in suspend state - CF set on error - AH = error code (03h,0Bh,80h) (see #00473) -Notes: although power management events are often asynchronous, notification - will not be made until polled via this call to permit software to - only receive event notification when it is prepared to process - power management events; since these events are not very time- - critical, it should be sufficient to poll once or twice per second - the critical resume notification is made after the system resumes - from an emergency suspension; normally, the system BIOS only notifies - its partner that it wishes to suspend and relies on the partner to - actually request the suspension, but no notification is made on an - emergency suspension - should not be called from within a hardware interrupt handler to avoid - reentrance problems -SeeAlso: AX=5307h,AX=5307h/CX=0001h"STAND-BY",AX=5307h/CX=0002h"SUSPEND" - -(Table 00479) -Values for APM event code: - 0001h system stand-by request - 0002h system suspend request - 0003h normal resume system notification - 0004h critical resume system notification - 0005h battery low notification ----APM v1.1--- - 0006h power status change notification - 0007h update time notification - 0008h critical system suspend notification - 0009h user system standby request notification - 000Ah user system suspend request notification - 000Bh system standby resume notification ----APM v1.2--- - 000Ch capabilities change notification (see AX=5310h) ------- - 000Dh-00FFh reserved system events - 01xxh reserved device events - 02xxh OEM-defined APM events - 0300h-FFFFh reserved ---------p-15530C----------------------------- -INT 15 - Advanced Power Management v1.1+ - GET POWER STATE - AX = 530Ch - BX = device ID (see #00474) -Return: CF clear if successful - CX = system state ID (see #00475) - CF set on error - AH = error code (01h,09h) (see #00473) -SeeAlso: AX=5307h ---------p-15530D----------------------------- -INT 15 - Advanced Power Management v1.1+ - EN/DISABLE DEVICE POWER MANAGEMENT - AX = 530Dh - BX = device ID (see #00474) - CX = function - 0000h disable power management - 0001h enable power management -Return: CF clear if successful - CF set on error - AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473) -Desc: specify whether automatic power management should be active for a - given device -SeeAlso: AX=5308h,AX=530Fh ---------p-15530E----------------------------- -INT 15 - Advanced Power Management v1.1+ - DRIVER VERSION - AX = 530Eh - BX = device ID of system BIOS (0000h) - CH = APM driver major version (BCD) - CL = APM driver minor version (BCD) (02h for APM v1.2) -Return: CF clear if successful - AH = APM connection major version (BCD) - AL = APM connection minor version (BCD) - CF set on error - AH = error code (03h,09h,0Bh) (see #00473) -SeeAlso: AX=5300h,AX=5303h ---------p-15530F----------------------------- -INT 15 - Advanced Power Management v1.1+ - ENGAGE/DISENGAGE POWER MANAGEMENT - AX = 530Fh - BX = device ID (see #00474) - CX = function - 0000h disengage power management - 0001h engage power management -Return: CF clear if successful - CF set on error - AH = error code (01h,09h) (see #00473) -Notes: unlike AX=5308h, this call does not affect the functioning of the APM - BIOS - when cooperative power management is disengaged, the APM BIOS performs - automatic power management of the system or device -SeeAlso: AX=5308h,AX=530Dh ---------p-155310----------------------------- -INT 15 - Advanced Power Management v1.2 - GET CAPABILITIES - AX = 5310h - BX = device ID (see #00474) - 0000h (APM BIOS) - other reserved -Return: CF clear if successful - BL = number of battery units supported (00h if no system batteries) - CX = capabilities flags (see #00480) - CF set on error - AH = error code (01h,09h,86h) (see #00473) -Notes: this function is supported via the INT 15, 16-bit protected mode, and - 32-bit protected mode interfaces; it does not require that a - connection be established prior to use - this function will return the capabilities currently in effect, not - any new settings which have been made but do not take effect until - a system restart -SeeAlso: AX=5300h,AX=530Fh,AX=5311h,AX=5312h,AX=5313h - -Bitfields for APM v1.2 capabilities flags: -Bit(s) Description (Table 00480) - 15-8 reserved - 7 PCMCIA Ring Indicator will wake up system from suspend mode - 6 PCMCIA Ring Indicator will wake up system from standby mode - 5 Resume on Ring Indicator will wake up system from suspend mode - 4 Resume on Ring Indicator will wake up system from standby mode - 3 resume timer will wake up system from suspend mode - 2 resume timer will wake up system from standby mode - 1 can enter global suspend state - 0 can enter global standby state ---------p-155311----------------------------- -INT 15 - Advanced Power Management v1.2 - GET/SET/DISABLE RESUME TIMER - AX = 5311h - BX = device ID (see #00474) - 0000h (APM BIOS) - other reserved - CL = function - 00h disable Resume Timer - 01h get Resume Timer - 02h set Resume Timer - CH = resume time, seconds (BCD) - DL = resume time, minutes (BCD) - DH = resume time, hours (BCD) - SI = resume date (BCD), high byte = month, low byte = day - DI = resume date, year (BCD) -Return: CF clear if successful - ---if getting timer--- - CH = resume time, seconds (BCD) - DL = resume time, minutes (BCD) - DH = resume time, hours (BCD) - SI = resume date (BCD), high byte = month, low byte = day - DI = resume date, year (BCD) - CF set on error - AH = error code (03h,09h,0Ah,0Bh,0Ch,0Dh,86h) (see #00473) -Notes: this function is supported via the INT 15, 16-bit protected mode, and - 32-bit protected mode interfaces -SeeAlso: AX=5300h,AX=5310h,AX=5312h,AX=5313h ---------p-155312----------------------------- -INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE RESUME ON RING - AX = 5312h - BX = device ID (see #00474) - 0000h (APM BIOS) - other reserved - CL = function - 00h disable Resume on Ring Indicator - 01h enable Resume on Ring Indicator - 02h get Resume on Ring Indicator status -Return: CF clear if successful - CX = resume status (0000h disabled, 0001h enabled) - CF set on error - AH = error code (03h,09h,0Ah,0Bh,0Ch,86h) (see #00473) -Notes: this function is supported via the INT 15, 16-bit protected mode, and - 32-bit protected mode interfaces -SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5313h ---------p-155313----------------------------- -INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE TIMER-BASED REQUESTS - AX = 5313h - BX = device ID (see #00474) - 0000h (APM BIOS) - other reserved - CL = function - 00h disable timer-based requests - 01h enable timer-based requests - 02h get timer-based requests status -Return: CF clear if successful - CX = timer-based requests status (0000h disabled, 0001h enabled) - CF set on error - AH = error code (03h,09h,0Ah,0Bh,86h) (see #00473) -Notes: this function is supported via the INT 15, 16-bit protected mode, and - 32-bit protected mode interfaces - some BIOSes set AH on return even when successful -SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5312h diff --git a/kernel/branches/Kolibri-F/docs/doxygen/doxygen.cfg b/kernel/branches/Kolibri-F/docs/doxygen/doxygen.cfg deleted file mode 100644 index 8ea1e6b2e..000000000 --- a/kernel/branches/Kolibri-F/docs/doxygen/doxygen.cfg +++ /dev/null @@ -1,2612 +0,0 @@ -# Doxyfile 1.9.1 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the configuration -# file that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# https://www.gnu.org/software/libiconv/ for the list of possible encodings. -# The default value is: UTF-8. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = "KolibriOS kernel" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. This -# could be handy for archiving the generated documentation or if some version -# control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify a logo or an icon that is included -# in the documentation. The maximum height of the logo should not exceed 55 -# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy -# the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. -# The default value is: NO. - -CREATE_SUBDIRS = NO - -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII -# characters to appear in the names of generated files. If set to NO, non-ASCII -# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode -# U+3044. -# The default value is: NO. - -ALLOW_UNICODE_NAMES = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. -# The default value is: English. - -OUTPUT_LANGUAGE = English - -# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all generated output in the proper direction. -# Possible values are: None, LTR, RTL and Context. -# The default value is: None. - -OUTPUT_TEXT_DIRECTION = None - -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member -# descriptions after the members that are listed in the file and class -# documentation (similar to Javadoc). Set to NO to disable this. -# The default value is: YES. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief -# description of a member or function before the detailed description -# -# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. -# The default value is: YES. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator that is -# used to form the text in various listings. Each string in this list, if found -# as the leading text of the brief description, will be stripped from the text -# and the result, after processing the whole list, is used as the annotated -# text. Otherwise, the brief description is used as-is. If left blank, the -# following values are used ($name is automatically replaced with the name of -# the entity):The $name class, The $name widget, The $name file, is, provides, -# specifies, contains, represents, a, an and the. - -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief -# description. -# The default value is: NO. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. -# The default value is: NO. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path -# before files name in the file list and in the header files. If set to NO the -# shortest path that makes the file name unique will be used -# The default value is: YES. - -FULL_PATH_NAMES = YES - -# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. -# Stripping is only done if one of the specified strings matches the left-hand -# part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to -# strip. -# -# Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. -# This tag requires that the tag FULL_PATH_NAMES is set to YES. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the -# path mentioned in the documentation of a class, which tells the reader which -# header file to include in order to use a class. If left blank only the name of -# the header file containing the class definition is used. Otherwise one should -# specify the list of include paths that are normally passed to the compiler -# using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't -# support long names like on DOS, Mac, or CD-ROM. -# The default value is: NO. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) -# The default value is: NO. - -JAVADOC_AUTOBRIEF = NO - -# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line -# such as -# /*************** -# as being the beginning of a Javadoc-style comment "banner". If set to NO, the -# Javadoc-style will behave just like regular comments and it will not be -# interpreted by doxygen. -# The default value is: NO. - -JAVADOC_BANNER = NO - -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a -# multi-line C++ special comment block (i.e. a block of //! or /// comments) as -# a brief description. This used to be the default behavior. The new default is -# to treat a multi-line C++ comment block as a detailed description. Set this -# tag to YES if you prefer the old behavior instead. -# -# Note that setting this tag to YES also means that rational rose comments are -# not recognized any more. -# The default value is: NO. - -MULTILINE_CPP_IS_BRIEF = NO - -# By default Python docstrings are displayed as preformatted text and doxygen's -# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the -# doxygen's special commands can be used and the contents of the docstring -# documentation blocks is shown as doxygen documentation. -# The default value is: YES. - -PYTHON_DOCSTRING = YES - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new -# page for each member. If set to NO, the documentation of a member will be part -# of the file/class/namespace that contains it. -# The default value is: NO. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen -# uses this value to replace tabs by spaces in code fragments. -# Minimum value: 1, maximum value: 16, default value: 4. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that act as commands in -# the documentation. An alias has the form: -# name=value -# For example adding -# "sideeffect=@par Side Effects:\n" -# will allow you to put the command \sideeffect (or @sideeffect) in the -# documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines (in the resulting output). You can put ^^ in the value part of an -# alias to insert a newline as if a physical newline was in the original file. -# When you need a literal { or } or , in the value part of an alias you have to -# escape them by means of a backslash (\), this can lead to conflicts with the -# commands \{ and \} for these it is advised to use the version @{ and @} or use -# a double escape (\\{ and \\}) - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. For -# instance, some of the names that are used will be different. The list of all -# members will be omitted, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or -# Python sources only. Doxygen will then generate output that is more tailored -# for that language. For instance, namespaces will be presented as packages, -# qualified scopes will look different, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources. Doxygen will then generate output that is tailored for Fortran. -# The default value is: NO. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for VHDL. -# The default value is: NO. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice -# sources only. Doxygen will then generate output that is more tailored for that -# language. For instance, namespaces will be presented as modules, types will be -# separated into more groups, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_SLICE = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, -# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL, -# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: -# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser -# tries to guess whether the code is fixed or free formatted code, this is the -# default for Fortran type files). For instance to make doxygen treat .inc files -# as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. -# -# Note: For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. When specifying no_extension you should add -# * to the FILE_PATTERNS. -# -# Note see also the list of default file extension mappings. - -EXTENSION_MAPPING = inc=C asm=C - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See https://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up -# to that level are automatically included in the table of contents, even if -# they do not have an id attribute. -# Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 5. -# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. - -TOC_INCLUDE_HEADINGS = 5 - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. -# The default value is: NO. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. -# The default value is: NO. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. -# This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you -# should set this option to NO. -# The default value is: YES. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. -# The default value is: NO. - -DISTRIBUTE_GROUP_DOC = NO - -# If one adds a struct or class to a group and this option is enabled, then also -# any nested class or struct is added to the same group. By default this option -# is disabled and one has to add nested compounds explicitly via \ingroup. -# The default value is: NO. - -GROUP_NESTED_COMPOUNDS = NO - -# Set the SUBGROUPING tag to YES to allow class member groups of the same type -# (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent -# subgrouping. Alternatively, this can be done per class using the -# \nosubgrouping command. -# The default value is: YES. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions -# are shown inside the group in which they are included (e.g. using \ingroup) -# instead of on a separate page (for HTML and Man pages) or section (for LaTeX -# and RTF). -# -# Note that this feature does not work in combination with -# SEPARATE_MEMBER_PAGES. -# The default value is: NO. - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions -# with only public data fields or simple typedef fields will be shown inline in -# the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO, structs, classes, and unions are shown on a separate page (for HTML and -# Man pages) or section (for LaTeX and RTF). -# The default value is: NO. - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or -# enum is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically be -# useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. -# The default value is: NO. - -TYPEDEF_HIDES_STRUCT = NO - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can be -# an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The -# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range -# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest -# the optimal cache size from a speed point of view. -# Minimum value: 0, maximum value: 9, default value: 0. - -LOOKUP_CACHE_SIZE = 0 - -# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use -# during processing. When set to 0 doxygen will based this on the number of -# cores available in the system. You can set it explicitly to a value larger -# than 0 to get more control over the balance between CPU load and processing -# speed. At this moment only the input processing can be done using multiple -# threads. Since this is still an experimental feature the default is set to 1, -# which efficively disables parallel processing. Please report any issues you -# encounter. Generating dot graphs in parallel is controlled by the -# DOT_NUM_THREADS setting. -# Minimum value: 0, maximum value: 32, default value: 1. - -NUM_PROC_THREADS = 1 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will -# be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual -# methods of a class will be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIV_VIRTUAL = NO - -# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal -# scope will be included in the documentation. -# The default value is: NO. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO, -# only classes defined in header files are included. Does not have any effect -# for Java sources. -# The default value is: YES. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. If set to YES, local methods, -# which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO, only methods in the interface are -# included. -# The default value is: NO. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base name of -# the file that contains the anonymous namespace. By default anonymous namespace -# are hidden. -# The default value is: NO. - -EXTRACT_ANON_NSPACES = NO - -# If this flag is set to YES, the name of an unnamed parameter in a declaration -# will be determined by the corresponding definition. By default unnamed -# parameters remain unnamed in the output. -# The default value is: YES. - -RESOLVE_UNNAMED_PARAMS = YES - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# declarations. If set to NO, these declarations will be included in the -# documentation. -# The default value is: NO. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO, these -# blocks will be appended to the function's detailed documentation block. -# The default value is: NO. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation that is typed after a -# \internal command is included. If the tag is set to NO then the documentation -# will be excluded. Set it to YES to include the internal documentation. -# The default value is: NO. - -INTERNAL_DOCS = NO - -# With the correct setting of option CASE_SENSE_NAMES doxygen will better be -# able to match the capabilities of the underlying filesystem. In case the -# filesystem is case sensitive (i.e. it supports files in the same directory -# whose names only differ in casing), the option must be set to YES to properly -# deal with such files in case they appear in the input. For filesystems that -# are not case sensitive the option should be be set to NO to properly deal with -# output files written for symbols that only differ in casing, such as for two -# classes, one named CLASS and the other named Class, and to also support -# references to files without having to specify the exact matching casing. On -# Windows (including Cygwin) and MacOS, users should typically set this option -# to NO, whereas on Linux or other Unix flavors it should typically be set to -# YES. -# The default value is: system dependent. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES, the -# scope will be hidden. -# The default value is: NO. - -HIDE_SCOPE_NAMES = NO - -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will -# append additional text to a page's title, such as Class Reference. If set to -# YES the compound reference will be hidden. -# The default value is: NO. - -HIDE_COMPOUND_REFERENCE= NO - -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of -# the files that are included by a file in the documentation of that file. -# The default value is: YES. - -SHOW_INCLUDE_FILES = YES - -# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each -# grouped member an include statement to the documentation, telling the reader -# which file to include in order to use the member. -# The default value is: NO. - -SHOW_GROUPED_MEMB_INC = NO - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include -# files with double quotes in the documentation rather than with sharp brackets. -# The default value is: NO. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the -# documentation for inline members. -# The default value is: YES. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief -# descriptions of file, namespace and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. Note that -# this will also influence the order of the classes in the class list. -# The default value is: NO. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the -# (brief and detailed) documentation of class members so that constructors and -# destructors are listed first. If set to NO the constructors will appear in the -# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. -# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief -# member documentation. -# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting -# detailed member documentation. -# The default value is: NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy -# of group names into alphabetical order. If set to NO the group names will -# appear in their defined order. -# The default value is: NO. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between -# the prototype and the implementation of a member function even if there is -# only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still -# accept a match between prototype and implementation in such cases. -# The default value is: NO. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo -# list. This list is created by putting \todo commands in the documentation. -# The default value is: YES. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test -# list. This list is created by putting \test commands in the documentation. -# The default value is: YES. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug -# list. This list is created by putting \bug commands in the documentation. -# The default value is: YES. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) -# the deprecated list. This list is created by putting \deprecated commands in -# the documentation. -# The default value is: YES. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional documentation -# sections, marked by \if ... \endif and \cond -# ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the -# initial value of a variable or macro / define can have for it to appear in the -# documentation. If the initializer consists of more lines than specified here -# it will be hidden. Use a value of 0 to hide initializers completely. The -# appearance of the value of individual variables and macros / defines can be -# controlled using \showinitializer or \hideinitializer command in the -# documentation regardless of this setting. -# Minimum value: 0, maximum value: 10000, default value: 30. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES, the -# list will mention the files that were used to generate the documentation. -# The default value is: YES. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file -# version. For an example see the documentation. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can -# optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. -# -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE -# tag is left empty. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files containing -# the reference definitions. This must be a list of .bib files. The .bib -# extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. -# For LaTeX the style of the bibliography can be controlled using -# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. See also \cite for info how to create references. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES -# this implies that the warnings are on. -# -# Tip: Turn warnings on while writing the documentation. -# The default value is: YES. - -WARNINGS = YES - -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = YES - -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. -# The default value is: YES. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that -# are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. If -# EXTRACT_ALL is set to YES then this flag will automatically be disabled. -# The default value is: NO. - -WARN_NO_PARAMDOC = NO - -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS -# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but -# at the end of the doxygen process doxygen will return with a non-zero status. -# Possible values are: NO, YES and FAIL_ON_WARNINGS. -# The default value is: NO. - -WARN_AS_ERROR = NO - -# The WARN_FORMAT tag determines the format of the warning messages that doxygen -# can produce. The string should contain the $file, $line, and $text tags, which -# will be replaced by the file and line number from which the warning originated -# and the warning text. Optionally the format may contain $version, which will -# be replaced by the version of the file (if it could be obtained via -# FILE_VERSION_FILTER) -# The default value is: $file:$line: $text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning and error -# messages should be written. If left blank the output is written to standard -# error (stderr). - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -INPUT = - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: -# https://www.gnu.org/software/libiconv/) for the list of possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# Note the list of default checked file patterns might differ from the list of -# default file extension mappings. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), -# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl, -# *.ucf, *.qsf and *.ice. - -FILE_PATTERNS = *.inc *.asm - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = * - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command: -# -# -# -# where is the value of the INPUT_FILTER tag, and is the -# name of an input file. Doxygen will then use the output that the filter -# program writes to standard output. If FILTER_PATTERNS is specified, this tag -# will be ignored. -# -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: pattern=filter -# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how -# filters are used. If the FILTER_PATTERNS tag is empty or if none of the -# patterns match the file name, INPUT_FILTER is applied. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will also be used to filter the input files that are used for -# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). -# The default value is: NO. - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. -# The default value is: NO. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any -# special comment blocks from generated source code fragments. Normal C, C++ and -# Fortran comments will always remain visible. -# The default value is: YES. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# entity all documented functions referencing it will be listed. -# The default value is: NO. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES then for each documented function -# all documented entities called/used by that function will be listed. -# The default value is: NO. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES then the hyperlinks from functions in REFERENCES_RELATION and -# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will -# link to the documentation. -# The default value is: YES. - -REFERENCES_LINK_SOURCE = YES - -# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -# source code will show a tooltip with additional information such as prototype, -# brief description and links to the definition and documentation. Since this -# will make the HTML file larger and loading of large files a bit slower, you -# can opt to disable this feature. -# The default value is: YES. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -SOURCE_TOOLTIPS = YES - -# If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in -# source browser. The htags tool is part of GNU's global source tagging system -# (see https://www.gnu.org/software/global/global.html). You will need version -# 4.8.6 or higher. -# -# To use it do the following: -# - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file -# - Make sure the INPUT points to the root of the source tree -# - Run doxygen as normal -# -# Doxygen will invoke htags (and that will in turn invoke gtags), so these -# tools must be available from the command line (i.e. in the search path). -# -# The result: instead of the source browser generated by doxygen, the links to -# source code will now point to the output of htags. -# The default value is: NO. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a -# verbatim copy of the header file for each class for which an include is -# specified. Set to NO to disable this. -# See also: Section \class. -# The default value is: YES. - -VERBATIM_HEADERS = YES - -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the -# clang parser (see: -# http://clang.llvm.org/) for more accurate parsing at the cost of reduced -# performance. This can be particularly helpful with template rich C++ code for -# which doxygen's built-in parser lacks the necessary type information. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse_libclang=ON option for CMake. -# The default value is: NO. - -CLANG_ASSISTED_PARSING = NO - -# If clang assisted parsing is enabled and the CLANG_ADD_INC_PATHS tag is set to -# YES then doxygen will add the directory of each input to the include path. -# The default value is: YES. - -CLANG_ADD_INC_PATHS = YES - -# If clang assisted parsing is enabled you can provide the compiler with command -# line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories -# specified with INPUT and INCLUDE_PATH. -# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. - -CLANG_OPTIONS = - -# If clang assisted parsing is enabled you can provide the clang parser with the -# path to the directory containing a file called compile_commands.json. This -# file is the compilation database (see: -# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the -# options used when the source files were built. This is equivalent to -# specifying the -p option to a clang tool, such as clang-check. These options -# will then be passed to the parser. Any options specified with CLANG_OPTIONS -# will be added as well. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse_libclang=ON option for CMake. - -CLANG_DATABASE_PATH = - -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all -# compounds will be generated. Enable this if the project contains a lot of -# classes, structs, unions or interfaces. -# The default value is: YES. - -ALPHABETICAL_INDEX = YES - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each -# generated HTML page (for example: .htm, .php, .asp). -# The default value is: .html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a -# standard header. -# -# To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. -# the setting GENERATE_TREEVIEW). It is highly recommended to start with a -# default header using -# doxygen -w html new_header.html new_footer.html new_stylesheet.css -# YourConfigFile -# and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally -# uses. -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description -# of the possible markers and block names see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard -# footer. See HTML_HEADER for more information on how to generate a default -# footer and what special commands can be used inside the footer. See also -# section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style -# sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. -# See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. -# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as -# it is more robust and this tag (HTML_STYLESHEET) will in the future become -# obsolete. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefore more robust against future updates. -# Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that the -# files will be copied as-is; there are no commands or markers available. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# https://en.wikipedia.org/wiki/Hue for more information. For instance the value -# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 -# purple, and 360 is red again. -# Minimum value: 0, maximum value: 359, default value: 220. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A -# value of 255 will produce the most vivid colors. -# Minimum value: 0, maximum value: 255, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the -# luminance component of the colors in the HTML output. Values below 100 -# gradually make the output lighter, whereas values above 100 make the output -# darker. The value divided by 100 is the actual gamma applied, so 80 represents -# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not -# change the gamma. -# Minimum value: 40, maximum value: 240, default value: 80. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = NO - -# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML -# documentation will contain a main index with vertical navigation menus that -# are dynamically created via JavaScript. If disabled, the navigation index will -# consists of multiple levels of tabs that are statically embedded in every HTML -# page. Disable this option to support browsers that do not have JavaScript, -# like the Qt help browser. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_MENUS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries -# shown in the various tree structured indices initially; the user can expand -# and collapse entries dynamically later on. Doxygen will expand the tree to -# such a level that at most the specified number of entries are visible (unless -# a fully collapsed tree already exceeds this amount). So setting the number of -# entries 1 will produce a full collapsed tree by default. 0 is a special value -# representing an infinite number of entries and will result in a full expanded -# tree by default. -# Minimum value: 0, maximum value: 9999, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files will be -# generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: -# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To -# create a documentation set, doxygen will generate a Makefile in the HTML -# output directory. Running make will produce the docset in that directory and -# running make install will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy -# genXcode/_index.html for more information. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_DOCSET = NO - -# This tag determines the name of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# The default value is: Doxygen generated docs. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# This tag specifies a string that should uniquely identify the documentation -# set bundle. This should be a reverse domain-name style string, e.g. -# com.mycompany.MyDocSet. Doxygen will append .docset to the name. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. -# The default value is: org.doxygen.Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. -# The default value is: Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three -# additional HTML index files: index.hhp, index.hhc, and index.hhk. The -# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: -# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows. -# -# The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML -# files are now used as the Windows 98 help format, and will replace the old -# Windows help format (.hlp) on all Windows platforms in the future. Compressed -# HTML files also contain an index, a table of contents, and you can search for -# words in the documentation. The HTML workshop also contains a viewer for -# compressed HTML files. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_HTMLHELP = NO - -# The CHM_FILE tag can be used to specify the file name of the resulting .chm -# file. You can add a path in front of the file if the result should not be -# written to the html output directory. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_FILE = - -# The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. -# The file has to be specified with full path. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -HHC_LOCATION = - -# The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the main .chm file (NO). -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -GENERATE_CHI = NO - -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) -# and project file content. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_INDEX_ENCODING = - -# The BINARY_TOC flag controls whether a binary table of contents is generated -# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it -# enables the Previous and Next buttons. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members to -# the table of contents of the HTML help documentation and to the tree view. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location (absolute path -# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to -# run qhelpgenerator on the generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be -# generated, together with the HTML files, they form an Eclipse help plugin. To -# install this plugin and make it available under the help contents menu in -# Eclipse, the contents of the directory containing the HTML and XML files needs -# to be copied into the plugins directory of eclipse. The name of the directory -# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. -# After copying Eclipse needs to be restarted before the help appears. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the Eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have this -# name. Each documentation set should have its own identifier. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# If you want full control over the layout of the generated HTML pages it might -# be necessary to disable the index and replace it with your own. The -# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top -# of each HTML page. A value of NO enables the index and the value YES disables -# it. Since the tabs in the index contain the same information as the navigation -# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -DISABLE_INDEX = YES - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. If the tag -# value is set to YES, a side panel will be generated containing a tree-like -# index structure (just like the one that is generated for HTML Help). For this -# to work a browser that supports JavaScript, DHTML, CSS and frames is required -# (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_TREEVIEW = YES - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. -# -# Note that a value of 0 will completely suppress the enum values from appearing -# in the overview section. -# Minimum value: 0, maximum value: 20, default value: 4. -# This tag requires that the tag GENERATE_HTML is set to YES. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used -# to set the initial width (in pixels) of the frame in which the tree is shown. -# Minimum value: 0, maximum value: 1500, default value: 250. -# This tag requires that the tag GENERATE_HTML is set to YES. - -TREEVIEW_WIDTH = 250 - -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to -# external symbols imported via tag files in a separate window. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -EXT_LINKS_IN_WINDOW = NO - -# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg -# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see -# https://inkscape.org) to generate formulas as SVG images instead of PNGs for -# the HTML output. These images will generally look nicer at scaled resolutions. -# Possible values are: png (the default) and svg (looks nicer but requires the -# pdf2svg or inkscape tool). -# The default value is: png. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FORMULA_FORMAT = png - -# Use this tag to change the font size of LaTeX formulas included as images in -# the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML -# output directory to force them to be regenerated. -# Minimum value: 8, maximum value: 50, default value: 10. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANSPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - -# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands -# to create new LaTeX commands to be used in formulas as building blocks. See -# the section "Including formulas" for details. - -FORMULA_MACROFILE = - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# https://www.mathjax.org) which uses client side JavaScript for the rendering -# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX -# installed or if you want to formulas look prettier in the HTML output. When -# enabled you may also need to install MathJax separately and configure the path -# to it using the MATHJAX_RELPATH option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. -# Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. -# The default value is: HTML-CSS. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from https://www.mathjax.org before deployment. -# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2 - -# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax -# extension names that should be enabled during MathJax rendering. For example -# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: -# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an -# example see the documentation. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and -# should work on any modern browser. Note that when using HTML help -# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) -# there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then -# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to -# search using the keyboard; to jump to the search box use + S -# (what the is depends on the OS and browser, but it is typically -# , /