476 lines
15 KiB
PHP
476 lines
15 KiB
PHP
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|||
|
;; ;;
|
|||
|
;; 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:
|