From d9b8117616ab17eecc6a833ff524c53639c38cba Mon Sep 17 00:00:00 2001 From: "Marat Zakiyanov (Mario79)" Date: Tue, 25 Jun 2013 03:15:38 +0000 Subject: [PATCH] 1) SATA IDE support for HDD and ATAPI 2) PIO LBA48 read for HDD git-svn-id: svn://kolibrios.org@3702 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/blkdev/hd_drv.inc | 82 +++++++++++++++++++++++++++++--- kernel/trunk/boot/bootcode.inc | 79 +++++++++++++++++++++++++----- kernel/trunk/const.inc | 5 ++ kernel/trunk/detect/dev_hdcd.inc | 24 +++++++++- kernel/trunk/detect/sear_par.inc | 12 +++-- kernel/trunk/fs/fs_lfn.inc | 12 +++-- kernel/trunk/kernel.asm | 79 ++++++++++++++++++++++++++---- 7 files changed, 257 insertions(+), 36 deletions(-) diff --git a/kernel/trunk/blkdev/hd_drv.inc b/kernel/trunk/blkdev/hd_drv.inc index f472966b7e..52209833f2 100644 --- a/kernel/trunk/blkdev/hd_drv.inc +++ b/kernel/trunk/blkdev/hd_drv.inc @@ -50,11 +50,11 @@ hd_read: cmp [hdpos], 0x80 jae .bios ; hd_read_{dma,pio} use old ATA with 28 bit for sector number - cmp eax, 0x10000000 - jb @f - inc [hd_error] - jmp return_01 -@@: +; cmp eax, 0x10000000 +; jb @f +; inc [hd_error] +; jmp return_01 +;@@: ; DMA read is permitted if [allow_dma_access]=1 or 2 cmp [allow_dma_access], 2 ja .nodma @@ -101,10 +101,22 @@ align 4 hd_read_pio: push eax edx + ; Выбрать нужный диск + mov edx, [hdbase] + add edx, 6 ;адрес регистра головок + mov al, byte [hdid] + add al, 128+64+32 + out dx, al; номер головки/номер диска + call wait_for_hd_idle cmp [hd_error], 0 jne hd_read_error - + +; ATA with 28 or 48 bit for sector number? + mov eax, [esp+4] + cmp eax, 0x10000000 + jae .lba48 +.lba28: cli xor eax, eax mov edx, [hdbase] @@ -132,7 +144,45 @@ hd_read_pio: mov al, 20h out dx, al; ATACommand регистр команд sti - + jmp .continue +.lba48: + cli + xor eax, eax + mov edx, [hdbase] + inc edx + out dx, al ; Features Previous Reserved + out dx, al ; Features Current Reserved + inc edx + out dx, al ; Sector Count Previous Sector count (15:8) + inc eax + out dx, al ; Sector Count Current Sector count (7:0) + inc edx + mov eax, [esp+4] + rol eax,8 + out dx, al ; LBA Low Previous LBA (31:24) + xor eax,eax ; because only 32 bit cache + inc edx + out dx, al ; LBA Mid Previous LBA (39:32) + inc edx + out dx, al ; LBA High Previous LBA (47:40) + sub edx,2 + mov eax, [esp+4] + out dx, al ; LBA Low Current LBA (7:0) + shr eax, 8 + inc edx + out dx, al ; LBA Mid Current LBA (15:8) + shr eax, 8 + inc edx + out dx, al ; LBA High Current LBA (23:16) + inc edx + mov al, byte [hdid] + add al, 128+64+32 + out dx, al; номер головки/номер диска + inc edx + mov al, 24h ; READ SECTOR(S) EXT + out dx, al; ATACommand регистр команд + sti +.continue: call wait_for_sector_buffer cmp [hd_error], 0 @@ -245,6 +295,13 @@ cache_write_pio: jae .bad ; call disable_ide_int + ; Выбрать нужный диск + mov edx, [hdbase] + add edx, 6 ;адрес регистра головок + mov al, byte [hdid] + add al, 128+64+32 + out dx, al; номер головки/номер диска + call wait_for_hd_idle cmp [hd_error], 0 jne hd_write_error @@ -596,6 +653,12 @@ hdd_irq15: align 4 hd_read_dma: +; hd_read_dma use old ATA with 28 bit for sector number + cmp eax, 0x10000000 + jb @f + inc [hd_error] + ret +@@: push eax push edx mov edx, [dma_hdpos] @@ -819,6 +882,11 @@ write_cache_chain: uglobal IDEContrRegsBaseAddr dw ? +IDEContrProgrammingInterface dw ? +IDE_BAR0_val dw ? +IDE_BAR1_val dw ? +IDE_BAR2_val dw ? +IDE_BAR3_val dw ? endg ; \end{Mario79} diff --git a/kernel/trunk/boot/bootcode.inc b/kernel/trunk/boot/bootcode.inc index c4a2ac9ca3..9479d65cde 100644 --- a/kernel/trunk/boot/bootcode.inc +++ b/kernel/trunk/boot/bootcode.inc @@ -387,7 +387,12 @@ sayerr: push 0 pop es - and word [es:BOOT_IDE_BASE_ADDR], 0 + xor ax,ax + and word [es:BOOT_IDE_BASE_ADDR], ax ;0 + and word [es:BOOT_IDE_BAR0_16], ax ;0 + and word [es:BOOT_IDE_BAR1_16], ax ;0 + and word [es:BOOT_IDE_BAR2_16], ax ;0 + and word [es:BOOT_IDE_BAR3_16], ax ;0 ; \begin{Mario79} ; find HDD IDE DMA PCI device ; check for PCI BIOS @@ -402,29 +407,81 @@ sayerr: ; a) class 1, subclass 1, programming interface 0x80 mov ax, 0xB103 mov ecx, 1*10000h + 1*100h + 0x80 + mov [es:BOOT_IDE_PI_16], cx xor si, si ; device index = 0 int 0x1A - jnc .found -; b) class 1, subclass 1, programming interface 0x8A + jnc .found_1 +; b) class 1, subclass 1, programming interface 0x8f mov ax, 0xB103 - mov ecx, 1*10000h + 1*100h + 0x8A + mov ecx, 1*10000h + 1*100h + 0x8f + mov [es:BOOT_IDE_PI_16], cx xor si, si ; device index = 0 int 0x1A jnc .found ; c) class 1, subclass 1, programming interface 0x85 mov ax, 0xB103 mov ecx, 1*10000h + 1*100h + 0x85 - xor si, si + mov [es:BOOT_IDE_PI_16], cx + xor si, si ; device index = 0 int 0x1A - jc .nopci -.found: -; get memory base + jnc .found +; d) class 1, subclass 1, programming interface 0x8A + mov ax, 0xB103 + mov ecx, 1*10000h + 1*100h + 0x8A + mov [es:BOOT_IDE_PI_16], cx + xor si, si ; device index = 0 + int 0x1A + jnc .found + + jmp .nopci +.found_1: +; get memory base BAR4 mov ax, 0xB10A mov di, 0x20 ; memory base is config register at 0x20 + push cx int 0x1A - jc .nopci + jc .no_BAR4 ;.nopci and cx, 0xFFF0 ; clear address decode type mov [es:BOOT_IDE_BASE_ADDR], cx +.no_BAR4: + pop cx +.found: +; get memory base BAR0 + mov ax, 0xB10A + mov di, 0x10 ; memory base is config register at 0x20 + push cx + int 0x1A + jc .no_BAR0 ;.nopci + mov [es:BOOT_IDE_BAR0_16], cx +.no_BAR0: + pop cx +; get memory base BAR1 + mov ax, 0xB10A + mov di, 0x14 ; memory base is config register at 0x20 + push cx + int 0x1A + jc .no_BAR1 ;.nopci + mov [es:BOOT_IDE_BAR1_16], cx +.no_BAR1: + pop cx +; get memory base BAR2 + mov ax, 0xB10A + mov di, 0x18 ; memory base is config register at 0x20 + push cx + int 0x1A + jc .no_BAR2 ;.nopci + mov [es:BOOT_IDE_BAR2_16], cx +.no_BAR2: + pop cx +; get memory base BAR3 + mov ax, 0xB10A + mov di, 0x1C ; memory base is config register at 0x20 + push cx + int 0x1A + jc .no_BAR3 ;.nopci + mov [es:BOOT_IDE_BAR3_16], cx +.no_BAR3: + pop cx .nopci: ; \end{Mario79} @@ -550,8 +607,8 @@ end if ; 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_biosdisk-preboot_device], 1 - adc byte [di+preboot_biosdisk-preboot_device], 0 +; cmp byte [di+preboot_biosdisk-preboot_device], 1 +; adc byte [di+preboot_biosdisk-preboot_device], 0 ;; default value for VRR is OFF ; cmp byte [di+preboot_vrrm-preboot_device], 0 ; jnz @f diff --git a/kernel/trunk/const.inc b/kernel/trunk/const.inc index 06dda4a5af..35fdf74000 100644 --- a/kernel/trunk/const.inc +++ b/kernel/trunk/const.inc @@ -322,6 +322,11 @@ BOOT_APM_FLAGS equ 0x9046 ;unused BOOT_APM_CODE_32 equ 0x9050 BOOT_APM_CODE_16 equ 0x9052 BOOT_APM_DATA_16 equ 0x9054 +BOOT_IDE_BAR0_16 equ 0x9056 +BOOT_IDE_BAR1_16 equ 0x9058 +BOOT_IDE_BAR2_16 equ 0x905A +BOOT_IDE_BAR3_16 equ 0x905C +BOOT_IDE_PI_16 equ 0x905E TMP_FILE_NAME equ 0 TMP_CMD_LINE equ 1024 diff --git a/kernel/trunk/detect/dev_hdcd.inc b/kernel/trunk/detect/dev_hdcd.inc index 9284c95869..d4042be51b 100644 --- a/kernel/trunk/detect/dev_hdcd.inc +++ b/kernel/trunk/detect/dev_hdcd.inc @@ -44,6 +44,10 @@ FindHDD: jmp EndFindHDD FindHDD_1: + movzx eax,word [ChannelNumber] + DEBUGF 1, "K : Channel %d ",eax + movzx eax,byte [DiskNumber] + DEBUGF 1, "Disk %d\n",eax call ReadHDD_ID cmp [DevErrorCode], 0 jne FindHDD_2 @@ -52,7 +56,7 @@ FindHDD_1: cmp [Sector512+12], word 255 ja FindHDD_2 inc byte [DRIVE_DATA+1] - jmp FindHDD_2_2 + jmp Print_Device_Name FindHDD_2: call DeviceReset cmp [DevErrorCode], 0 @@ -62,6 +66,21 @@ FindHDD_1: jne FindHDD_2_2 inc byte [DRIVE_DATA+1] inc byte [DRIVE_DATA+1] +Print_Device_Name: + pushad + pushfd + mov esi,Sector512+27*2 + mov edi,dev_name + mov ecx,20 + cld +@@: + lodsw + xchg ah,al + stosw + loop @b + popfd + popad + DEBUGF 1, "K : Dev: %s \n", dev_name FindHDD_2_2: ret @@ -70,10 +89,11 @@ FindHDD_3: shl byte [DRIVE_DATA+1], 2 ret - ; Адрес считываемого сектора в режиме LBA uglobal SectorAddress DD ? +dev_name: + rb 41 endg ;************************************************* ;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА * diff --git a/kernel/trunk/detect/sear_par.inc b/kernel/trunk/detect/sear_par.inc index ec790899d2..3407307081 100644 --- a/kernel/trunk/detect/sear_par.inc +++ b/kernel/trunk/detect/sear_par.inc @@ -17,7 +17,8 @@ $Revision$ search_partitions_ide0: test [DRIVE_DATA+1], byte 0x40 jz search_partitions_ide1 - mov [hdbase], 0x1f0 + mov eax,[hd_address_table] + mov [hdbase], eax ;0x1f0 mov [hdid], 0x0 mov [hdpos], 1 mov [known_part], 1 @@ -39,7 +40,8 @@ $Revision$ search_partitions_ide1: test [DRIVE_DATA+1], byte 0x10 jz search_partitions_ide2 - mov [hdbase], 0x1f0 + mov eax,[hd_address_table] + mov [hdbase], eax ;0x1f0 mov [hdid], 0x10 mov [hdpos], 2 mov [known_part], 1 @@ -61,7 +63,8 @@ $Revision$ search_partitions_ide2: test [DRIVE_DATA+1], byte 0x4 jz search_partitions_ide3 - mov [hdbase], 0x170 + mov eax,[hd_address_table+16] + mov [hdbase], eax ;0x170 mov [hdid], 0x0 mov [hdpos], 3 mov [known_part], 1 @@ -83,7 +86,8 @@ $Revision$ search_partitions_ide3: test [DRIVE_DATA+1], byte 0x1 jz end_search_partitions_ide - mov [hdbase], 0x170 + mov eax,[hd_address_table+16] + mov [hdbase], eax ;0x170 mov [hdid], 0x10 mov [hdpos], 4 mov [known_part], 1 diff --git a/kernel/trunk/fs/fs_lfn.inc b/kernel/trunk/fs/fs_lfn.inc index 668eeea457..7f071fe929 100644 --- a/kernel/trunk/fs/fs_lfn.inc +++ b/kernel/trunk/fs/fs_lfn.inc @@ -525,25 +525,29 @@ fs_NumFloppyServices = ($ - fs_FloppyServices)/4 fs_OnHd0: call reserve_hd1 - mov [hdbase], 0x1F0 + mov eax,[hd_address_table] + mov [hdbase], eax ;0x1F0 mov [hdid], 0 push 1 jmp fs_OnHd fs_OnHd1: call reserve_hd1 - mov [hdbase], 0x1F0 + mov eax,[hd_address_table] + mov [hdbase], eax ;0x1F0 mov [hdid], 0x10 push 2 jmp fs_OnHd fs_OnHd2: call reserve_hd1 - mov [hdbase], 0x170 + mov eax,[hd_address_table+16] + mov [hdbase], eax ;0x170 mov [hdid], 0 push 3 jmp fs_OnHd fs_OnHd3: call reserve_hd1 - mov [hdbase], 0x170 + mov eax,[hd_address_table+16] + mov [hdbase], eax ;0x170 mov [hdid], 0x10 push 4 fs_OnHd: diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 9ce3ff586f..b8e0aa16e9 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -358,8 +358,40 @@ high_code: call mutex_init ; SAVE REAL MODE VARIABLES + xor eax,eax + mov ax, [BOOT_VAR + BOOT_IDE_PI_16] + mov [IDEContrProgrammingInterface], ax mov ax, [BOOT_VAR + BOOT_IDE_BASE_ADDR] mov [IDEContrRegsBaseAddr], ax + mov ax, [BOOT_VAR + BOOT_IDE_BAR0_16] + mov [IDE_BAR0_val], ax + + cmp ax,0 + je @f + cmp ax,1 + je @f + and ax,0xfff0 + mov [StandardATABases],ax + mov [hd_address_table],eax + mov [hd_address_table+8],eax +@@: + mov ax, [BOOT_VAR + BOOT_IDE_BAR1_16] + mov [IDE_BAR1_val], ax + mov ax, [BOOT_VAR + BOOT_IDE_BAR2_16] + mov [IDE_BAR2_val], ax + + cmp ax,0 + je @f + cmp ax,1 + je @f + and ax,0xfff0 + mov [StandardATABases+2],ax + mov [hd_address_table+16],eax + mov [hd_address_table+24],eax +@@: + mov ax, [BOOT_VAR + BOOT_IDE_BAR3_16] + mov [IDE_BAR3_val], ax + ; --------------- APM --------------------- ; init selectors @@ -1014,6 +1046,18 @@ end if @@: DEBUGF 1, "K : %d CPU detected\n", eax + movzx eax,[IDE_BAR0_val] + DEBUGF 1, "K : BAR0 %x \n", eax + movzx eax,[IDE_BAR1_val] + DEBUGF 1, "K : BAR1 %x \n", eax + movzx eax,[IDE_BAR2_val] + DEBUGF 1, "K : BAR2 %x \n", eax + movzx eax,[IDE_BAR3_val] + DEBUGF 1, "K : BAR3 %x \n", eax + movzx eax,[IDEContrRegsBaseAddr] + DEBUGF 1, "K : BAR4 %x \n", eax + movzx eax,[IDEContrProgrammingInterface] + DEBUGF 1, "K : IDEContrProgrammingInterface %x \n", eax ; START MULTITASKING ; A 'All set - press ESC to start' messages if need @@ -1028,6 +1072,17 @@ end if cmp [IDEContrRegsBaseAddr], 0 setnz [dma_hdd] + + cmp [dma_hdd],0 + je .print_pio +.print_dma: + DEBUGF 1, "K : IDE DMA mode\n" + jmp .continue + +.print_pio: + DEBUGF 1, "K : IDE PIO mode\n" +.continue: + mov [timer_ticks_enable], 1 ; for cd driver sti @@ -1585,23 +1640,27 @@ endg dec ecx jnz noprma - mov [cdbase], 0x1f0 + mov eax,[hd_address_table] + mov [cdbase], eax ;0x1f0 mov [cdid], 0xa0 noprma: dec ecx jnz noprsl - mov [cdbase], 0x1f0 + mov eax,[hd_address_table] + mov [cdbase], eax ;0x1f0 mov [cdid], 0xb0 noprsl: dec ecx jnz nosema - mov [cdbase], 0x170 + mov eax,[hd_address_table+16] + mov [cdbase], eax ;0x170 mov [cdid], 0xa0 nosema: dec ecx jnz nosesl - mov [cdbase], 0x170 + mov eax,[hd_address_table+16] + mov [cdbase], eax ;0x170 mov [cdid], 0xb0 nosesl: ret @@ -1630,7 +1689,8 @@ endg cmp ecx, 1 jnz noprmahd - mov [hdbase], 0x1f0 + mov eax,[hd_address_table] + mov [hdbase], eax ;0x1f0 and dword [hdid], 0x0 mov dword [hdpos], ecx ; call set_FAT32_variables @@ -1638,7 +1698,8 @@ endg cmp ecx, 2 jnz noprslhd - mov [hdbase], 0x1f0 + mov eax,[hd_address_table] + mov [hdbase], eax ;0x1f0 mov [hdid], 0x10 mov dword [hdpos], ecx ; call set_FAT32_variables @@ -1646,7 +1707,8 @@ endg cmp ecx, 3 jnz nosemahd - mov [hdbase], 0x170 + mov eax,[hd_address_table+16] + mov [hdbase], eax ;0x170 and dword [hdid], 0x0 mov dword [hdpos], ecx ; call set_FAT32_variables @@ -1654,7 +1716,8 @@ endg cmp ecx, 4 jnz noseslhd - mov [hdbase], 0x170 + mov eax,[hd_address_table+16] + mov [hdbase], eax ;0x170 mov [hdid], 0x10 mov dword [hdpos], ecx ; call set_FAT32_variables