/kernel/branches/Kolibri-F/detect/dev_fd.inc |
---|
0,0 → 1,38 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
@@: |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-F/detect/dev_hdcd.inc |
---|
0,0 → 1,475 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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: |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-F/detect/biosdisk.inc |
---|
0,0 → 1,122 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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: |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-F/detect/biosmem.inc |
---|
0,0 → 1,46 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/branches/Kolibri-F/detect/vortex86.inc |
---|
0,0 → 1,158 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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: |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/branches/Kolibri-F/detect/sear_par.inc |
---|
0,0 → 1,280 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-F/detect/init_ata.inc |
---|
0,0 → 1,492 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
;----------------------------------------------------------------------------- |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/branches/Kolibri-F/detect/disks.inc |
---|
0,0 → 1,15 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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' |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-F/detect/getcache.inc |
---|
0,0 → 1,209 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-F/detect/. |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |