Memphis Идика и почитай ты спецификацию. Иш ты чего захотел, чтобы тебе ошибке о завершении команды выдовались до ее зовершения.
Memphis Согласен по поводу проверок на ошибки, мой код действительно сильно упрощен (было отсечено много "лишнего" дабы получить быстрый результат). Код заработал, но не учитывает нюансы оборудования. Постепенно, по мере изучения данной темы, буду "интеллектуализировать" его. УДМА конечно-же интересует, но я думал оставить его на потом, что бы не усложнять текущую задачу. Мне кажется, что ПИО для недоразвитой системы - наиболее простое решение. Но я могу пересмотреть свою точку зрения По поводу адреса Bus Master контроллера: он находится в конфигурационном пространстве PCI ?
dess Согласен по поводу проверок на ошибки, мой код действительно сильно упрощен - хотелось бы уточнить, чего Вы хотите - чисто теоретическую программку или реально действующий код ? Во втором случае - придется больше анализировать, ведь код должен работать с САТА/ПАТА хардами (старыми/новыми/ЛБА48/ЛБА28). Повторю еще раз - нельзя проверять только биты #80 & #8 !!! Вот живой пример - возьмите ПАТА хард ЛБА48, введите в его регистры чтение одного сектора для ЛБА=0FFFFFFFFFFFF в режиме ЛБА, дайте ему команду 24/29, дождитесь его готовности и посмотрите код статуса - будет код 59 (команда исполнилась с ошибкой - и это естественно - номер ЛБА жутко большой). Но в коде 59 установлен бит #8 (требование трансфера, да еще и ЛЕД харда сияет). Вы не имеете право проводить трансфер, хоть бит и установлен (да и трансфер какого сектора Вы произведете ?) - вначале надо проверить бит #1 - команда завершилась успешно ? По поводу адреса Bus Master контроллера: он находится в конфигурационном пространстве PCI ? - совершенно верно. Если у Вас стандартный ИДЕ от Интела, его адрес, скорее всего, будет 0F000h. Уточните. Я просто подстраиваюсь под Вашу конфигурацию, чтобы последующие фрагменты кода можно было испытать вживую. Не глядите, что мы с Pavia столкнулись лбами. Для Вас, как лицу незаинтересованному, думаю, истина превыше всего (проверяйте его и мой код, анализируйте).
Memphis На момент создания данной темы мне был необходим наилегчайший код чтения данных с HDD, так-как целью было подгрузить бинарник во время работы ассемблерного кода запущенного из под MS-DOS и выполняющегося в защищенном режиме процессора. В принципе цель достугнута (на моём оборудовании). Но как Вы правильно заметили про САТА/ПАТА/И_ВСЯКИЕ_ТАМ_АТА, для корректной работы функции необходимо нечто большее, чем у меня на данный момент. Беда только в отсутствии должной литературы по различным маркам железа. Поэтому я особо и не рвался. Но раз уж тема продолжает развиваться, то глупо было бы отнекиваться. Я готов проверять всё, что нужно проверять, чтобы всё корректно крутилось и не заедало. Начну с проверки #1-го бита, потом #80, и #8. По поводу всё того-же БасМастерса: мне казалось я улавливаю, что это такое, но сейчас не уверен. У меня Интеловский контроллер с одним ИДЕ и тремя САТА/ПАТА (на выбор в БИОСЕ). Я сканирую конфигурационное пространство ПИСИАЙ по всем шинам, устройствам, функциям и нахожу классы различного оборудования. Если речь идет об устройствах класса 01 (устройства массовой памяти), то известны порты контроллера: B800, B400, B000, А800, A400. Но подозреваю, что это не то, что Вас интересует... Если мои подозрения верны, то где мне искать адрес этого Мастера Шины ???
bus:00, dev:00, fn:0, class:060000, irq:00, 00000000 00000000 00000000 00000000 00000000 00000000 bus:00, dev:02, fn:0, class:030000, irq:0B, DFE00000 00008801 E0000008 DFE80000 00000000 00000000 bus:00, dev:1B, fn:0, class:040300, irq:05, DFEF8004 00000000 00000000 00000000 00000000 00000000 bus:00, dev:1C, fn:0, class:060400, irq:0B, 00000000 00000000 00030300 2000E0E0 0000FFF0 0001FFF1 bus:00, dev:1C, fn:1, class:060400, irq:0A, 00000000 00000000 00020200 2000D0D0 DFF0DFF0 0001FFF1 bus:00, dev:1D, fn:0, class:0C0300, irq:03, 00000000 00000000 00000000 00000000 00009001 00000000 bus:00, dev:1D, fn:1, class:0C0300, irq:0A, 00000000 00000000 00000000 00000000 00009401 00000000 bus:00, dev:1D, fn:2, class:0C0300, irq:06, 00000000 00000000 00000000 00000000 00009801 00000000 bus:00, dev:1D, fn:3, class:0C0300, irq:05, 00000000 00000000 00000000 00000000 0000A001 00000000 bus:00, dev:1D, fn:7, class:0C0320, irq:03, DFEFFC00 00000000 00000000 00000000 00000000 00000000 bus:00, dev:1E, fn:0, class:060401, irq:FF, 00000000 00000000 20010100 2280C0C0 0000FFF0 0001FFF1 bus:00, dev:1F, fn:0, class:060100, irq:00, 00000000 00000000 00000000 00000000 00000000 00000000 bus:00, dev:1F, fn:1, class:01018A, irq:00, 00000001 00000001 00000001 00000001 0000FFA1 00000000 bus:00, dev:1F, fn:2, class:01018F, irq:0B, 0000B801 0000B401 0000B001 0000A801 0000A401 00000000 bus:00, dev:1F, fn:3, class:0C0500, irq:0A, 00000000 00000000 00000000 00000000 00000401 00000000 bus:02, dev:00, fn:0, class:020000, irq:0A, DFFC0004 00000000 00000000 00000000 00000000 00000000
bus:00, dev:1F, fn:1, class:01018A, irq:00, 00000001 00000001 00000001 00000001 0000FFA1 00000000 это Легаси IDE его порты 1f0h 3f4h 170h 374h и его Bus Master Base Address 0FFA0h - порт bus:00, dev:1F, fn:2, class:01018F, irq:0B, 0000B801 0000B401 0000B001 0000A801 0000A401 00000000 это Нативе IDE его порты 0B800h 0B400h 0B000h 0A800h и его Bus Master Base Address 0A400h - порт
Pavia 1f0h 3f4h 170h 374h - немного Вас подправлю. Правильно так - 3F6h & 376h. dess Начну с проверки #1-го бита, потом #80, и #8. - нет. Сначала #80, затем #1 (обязательно по адресам 1F7h & 177h, но не 3F6h & 376 - именно надо для САТА !!!). Если это успешно - только тогда #8 - это гарантирует правильность трансфера для САТА/ПАТА хардов. И еще по ПИО уточните - читать/писать будете посекторно (АТА команды 20/24 & 30/34) или мультиблоком (АТА команды C4/29 & C5/39) ? Я сканирую конфигурационное пространство ПИСИАЙ по всем шинам, устройствам, функциям и нахожу классы - сложно и некрасиво. Ваши контроллеры в формате B/D/F & VendorId/DeviceId очень легко увидеть во время POSTа, когда на экран выдается PCI-таблица IRQ-номеров для контроллеров. Так легче детерминировать Ваши контроллеры. Есть второй вариант - в Диспетчере устройств раскроем IDE ATA/ATAPI контроллеры, щелкнем по самому контроллеру, на вкладке "Общие" - видим размещение его в формате B/D/F, на вкладке "Ресурсы" - адреса BMастера (покажите их мне). Затем щелкаем по каналам контроллера и списываем адреса I/O для вкладки "Ресурсы". Это надо проделать для обеих Ваших контроллеров.
Memphis Как раз таки правельно 3f4h. 3f4h -это база, просто используется только один регистр с индексом 2 (3f4h+2h=3f6h). 0B400h - это тоже база, а регистр будет 0B402h .
Pavia Вобще-то, 3F4h - регистр статуса флопоконтроллера. Но это не важно. Я указал реальные адреса, с которыми можно работать. Может это и база, спорить не хочу.
Memphis Еще и не такии чудеса есть к примеру порты PCI 0CF8h - 0CFBh задают адреса устройства. А intel еще впихнула перезагрузку 0CF9h(Можно сказать PCI reset). Собственно по этой причине у них номера устройств начинаются с 30h =). У других вендоров подругому. Сразу предвижу вопрос. Насчет портов, можно писать в 4 8-битных порта разом, тем самым объединяя их в 32 битный порт. -мануэл на процессор intel. Разве что можно вспомнить порт жеских данных где все-таки из одного порта читается 2 байта. Остальные полностью соответсвуют описанному выше.
Pavia можно писать в 4 8-битных порта разом, тем самым объединяя их в 32 битный порт - не для всех, а только для оговоренных особо. К примеру, инициализация таймера (к примеру, 42-й порт - надо дважды вывести по байту. Сразу записать слово не прокатит. порт жеских данных где все-таки из одного порта читается 2 байта - не согласен. Харды необычайно гибки. И хотя 40/80 пиновый ПАТА шлейф физически может 16 бит, хард прекрасно исполняет команды по трансферу ПИО типа rep insd/rep outsd (по 2-м фронтам за такт). Забавно, но он может также прокачивать по 16 проводам всего один байт. В моей жутко старой матерной БИОС есть фишка, когда во время ПОСТа тестируется ПАТА шлейф харда. Т.е. если в шлейфе повреждены жилы старшего байта, можно заставить хард производить трансфер байтами по исправным 8-ми младшим. Даже есть такая Set Features. Ну а про САТА совсем интересно говорить - может по кабельку также 8/16/32 бита за такт.
Memphis Ты опять не понял. В таймере один порт. А тут про порты находящиеся рядом. Насчет 8 для PATA у меня не работало. А вот 32 работало это давно известно как PIO32.
Pavia В таймере один порт - а мне известны такие адреса: 40/41/42/43 - со всеми приходилось работать. Впрочем, к теме это не относится, вернемся к этому позже, я подберу более удачные примеры.
IDE ATA/ATAPI контроллеры: ------------------------------- Intel(R) 82801G (ICH7 Family) Ultra ATA Storage Controllers - 27DF Размещение: PCI шина 0, устройство 31, функция 1 Диапазон ввода/вывода (I/O): FFA0 - FFAF Intel(R) 82801GB/GR/GH (ICH7 Family) Serial ATA Storage Controller - 27C0 Размещение: PCI шина 0, устройство 31, функция 2 Диапазон ввода/вывода (I/O): B800 - B807 Диапазон ввода/вывода (I/O): B400 - B403 Диапазон ввода/вывода (I/O): B000 - B007 Диапазон ввода/вывода (I/O): A800 - A803 Диапазон ввода/вывода (I/O): A400 - A40F IRQ: 23 Вторичный канал IDE Диапазон ввода/вывода (I/O): 0170 - 0177 Диапазон ввода/вывода (I/O): 0376 - 0376 IRQ: 15 Первичный канал IDE Диапазон ввода/вывода (I/O): 01F0 - 01F7 Диапазон ввода/вывода (I/O): 03F6 - 03F6 IRQ: 14 По поводу PIO: поскольку хард содержит кластерную структуру FAT32, то думаю, что есть смысл работать с кластерами и оперировать мультиблоками.
dess Замечательно. Все необходимое есть. Стандартный ИДЕ контроллер (27DF) содержит 2 БусМастер канала с адресами FFA0h & FFA8h. Для первичного канала адреса I/O 1F0h/3F6h. Для вторичного канала адреса I/O 170h/376h. САТА-контроллер (27C0) содержит 2 БусМастер канала с адресами A400h & A408h. Для первичного канала адреса I/O B800h/???h. Для вторичного канала адреса I/O B000h/???h. С ходу не смог определить у него адреса регистров управления. В принципе, в нашем случае можно обойтись и без них. Но для очистки совести, я позже скажу, что нужно сделать, чтобы найти их. Чем будем заниматься - добьем ПИО (мультиблок) или переключимся на УДМА ? Если второе, вопрос - нужно-ли подробно описывать Бус Мастер контроллер или сразу написать рабочий фрагмент кода и на нем проводить разбор полетов - буду пояснять, почему написал именно такие команды и как оно работает (по мере поступления вопросов) ? Кстати, немного о себе (в смысле интересов) тут: http://forum.ixbt.com/topic.cgi?id=11:38403
Memphis Здорово !!! Есть желание добить ПИО мультиблок в режиме ЛБА48 А дальше - по ходу ситуации. Заранее благодарен !
dess Для успешного чтения харда в режиме ЛБА48/ПИО мультиблоком необходимо определиться с размером самого блока. Самый простой путь - прочитать паспорт харда (АТА-команда 0ECh), посмотреть значение байта по смещению 76h - это и будет размер блока в секторах. Как правило, размер равен 10h, у некоторых встречал 20h (разумеется, программируется). А вот выше наверное не бывает. Собственно посекторное чтение (24h) отличается от блочного чтения (29h) незначительно - при посекторном после чтения очередного одного сектора надо ждать IRQ (или готовность) харда, при блочном - ждем готовность после прочтения всего блока. Для особо ленивых и не_любителей читать паспорта есть альтернатива (работа при неизвестном размере блока) - прочитали один сектор, проверили/подождали готовность, прочитали следующий сектор, опять проверка или если надо, ожидание готовности и т.д. Привожу фрагмент кода - чтение для харда Primary Master: Код (Text): start: jmp short begin ;------------------------------------------------ sect db 0FFh ; количество секторов для чтения multiple db 10h ; размер блока в секторах segm dw 6789h ; сегмент ОЗУ для чтения offs dw 870Fh ; смещение в сегменте для трансфера LBA_lo dd 11223344h ; мл. часть номера ЛБА LBA_hi dw 0000h ; ст. часть номера ЛБА ;------------------------------------------------ begin: mov al,0E0h mov dx,1F6h out dx,al inc dx lab0: in al,dx test al,80h jnz lab0 mov al,0 sub dx,6 out dx,al inc dx out dx,al mov al,sect out dx,al mov eax,LBA_lo + 3 mov cx,3 lab1: inc dx out dx,al shr eax,8 loop lab1 sub dx,2 mov eax,LBA_lo mov cl,3 lab1a: out dx,al shr eax,8 inc dx loop lab1a mov al,29h inc dx out dx,al mov ax,segm mov di,offs push di shr di,4 add ax,di mov es,ax ; !!!!! pop di and di,0Fh cld ; !!!!! mov bx,word ptr sect lab2: sub bl,bh ja short lab3 add bh,bl mov bl,0 lab3: movzx cx,bh shl cx,7 lab4: in al,dx test al,80h jnz lab4 test al,1 jnz short error ; !!!!! sub dx,7 rep insd test bl,bl mov ah,0 ; код 0 - без ошибок jz short exit mov ax,es push di shr di,4 add ax,di mov es,ax ; !!!!! pop di and di,0Fh add dx,7 jmp lab2 ;------------------------------------------------ error: mov ah,0Ah ; код ошибки на выход exit: int 3 Уточните для Вашего харда размер блока в секторах и номер ЛБА (внесите данные в бинарник). Очень хочу, чтобы этот код был испробован на ЛБА48 ПАТА харде, разумеется, отладчиком по шагам с номером сектора 0FFFFFFFFFFFF. Выкладываю полный текст фрагмента с бинарником - не запускайте его как COM-модуль, он заканчивается Int 3 (для отладчика) !!! http://slil.ru/26304354
Memphis Привет ! Благодарю за наглядный пример ! Начал разбор кода. Есть несколько вопросов: - в тексте используется команда insd - чтение двойного слова, в то время, как порт данных является шестнадцатибитным. Как это ??? Или в режиме LBA48 этот порт является 32-битным ? - в примере кода сколько блоков читается, один или несколько ?
dess в тексте используется команда insd - см. мой пост #52. Хард по умолчанию всегда может insw/insd (если он только не очень старый, не могущий PIO3/4). От моды LBA28/48/CHS НЕ ЗАВИСИТ !!! "D" по сравнению с "W" работает в 2 раза быстрее. в примере кода сколько блоков читается, один или несколько ? - читается 0FFh секторов. Они дробятся в мультиблоки по 10h секторов. Хотите прочитать 1 сектор - занесите это значение в переменную Sect. Ноль недопустим и бессмысленен. как порт данных является шестнадцатибитным - не факт. Когда я переводил свой IBM-хард в технологический режим, я в порт данных писал DWord !!!