/kernel/branches/kolibri-process/detect/biosdisk.inc |
---|
0,0 → 1,109 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2008-2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; Detect all BIOS hard drives. |
; diamond, 2008 |
; Do not include USB mass storages. CleverMouse, 2013 |
xor cx, cx |
mov es, cx |
mov di, 0x9080 |
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:0x907F] |
mov al, dl |
stosb |
push ds |
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 ds |
jmp bddc2 |
.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:0x907F] |
mov al, dl |
stosb |
xor ax, ax |
stosb |
dec ax |
stosw |
; mov al, 0 |
; stosb |
; mov ax, -1 |
; stosw |
bddc2: |
cmp cl, [es:0x475] |
jae bdde |
bddc: |
inc dl |
jnz bdds |
bdde: |
/kernel/branches/kolibri-process/detect/biosmem.inc |
---|
0,0 → 1,43 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2009-2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; 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, 0x9104 |
mov [di-4], ebx ; no blocks yet |
mov ecx, 20 |
mov edx, 0x534D4150 |
int 15h |
jc no_E820 |
cmp eax, 0x534D4150 |
jnz no_E820 |
e820_mem_loop: |
; cmp byte [di+16], 1 ; ignore non-free areas |
; jnz e820_mem_next |
inc byte [0x9100] |
add di, 20 |
e820_mem_next: |
; consequent calls to fn E820 |
test ebx, ebx |
jz e820_test_done |
cmp byte [0x9100], 32 |
jae 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 |
/kernel/branches/kolibri-process/detect/dev_fd.inc |
---|
0,0 → 1,38 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 4273 $ |
;*************************************************** |
; предварительная очистка области таблицы |
; поиск и занесение в таблицу приводов FDD |
; автор 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 |
@@: |
/kernel/branches/kolibri-process/detect/dev_hdcd.inc |
---|
0,0 → 1,423 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 3881 $ |
;****************************************************** |
; поиск приводов HDD и CD |
; автор исходного текста Кулаков Владимир Геннадьевич. |
; адаптация и доработка Mario79 |
;****************************************************** |
;**************************************************** |
;* ПОИСК HDD и CD * |
;**************************************************** |
cmp [IDEContrProgrammingInterface], 0 |
je EndFindHDD |
FindHDD: |
mov [ChannelNumber], 1 |
mov [DiskNumber], 0 |
call FindHDD_3 |
; mov ax,[Sector512+176] |
; mov [DRIVE_DATA+6],ax |
; mov ax,[Sector512+126] |
; mov [DRIVE_DATA+8],ax |
; mov ax,[Sector512+128] |
; mov [DRIVE_DATA+8],ax |
mov [DiskNumber], 1 |
call FindHDD_3 |
; mov al,[Sector512+176] |
; mov [DRIVE_DATA+7],al |
inc [ChannelNumber] |
mov [DiskNumber], 0 |
call FindHDD_3 |
; mov al,[Sector512+176] |
; mov [DRIVE_DATA+8],al |
mov [DiskNumber], 1 |
call FindHDD_1 |
; mov al,[Sector512+176] |
; mov [DRIVE_DATA+9],al |
jmp EndFindHDD |
FindHDD_1: |
DEBUGF 1, "K : Channel %d ",[ChannelNumber]:2 |
DEBUGF 1, "Disk %d\n",[DiskNumber]:1 |
call ReadHDD_ID |
cmp [DevErrorCode], 0 |
jne FindHDD_2 |
cmp [Sector512+6], word 16 |
ja FindHDD_2 |
cmp [Sector512+12], word 255 |
ja FindHDD_2 |
inc byte [DRIVE_DATA+1] |
jmp Print_Device_Name |
FindHDD_2: |
call DeviceReset |
cmp [DevErrorCode], 0 |
jne FindHDD_2_2 |
call ReadCD_ID |
cmp [DevErrorCode], 0 |
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 |
xor eax, eax |
mov ax, [Sector512+64*2] |
DEBUGF 1, "K : PIO mode %x\n", eax |
mov ax, [Sector512+63*2] |
DEBUGF 1, "K : Multiword DMA mode %x\n", eax |
mov ax, [Sector512+88*2] |
DEBUGF 1, "K : Ultra DMA mode %x\n", eax |
FindHDD_2_2: |
ret |
FindHDD_3: |
call FindHDD_1 |
shl byte [DRIVE_DATA+1], 2 |
ret |
; Адрес считываемого сектора в режиме LBA |
uglobal |
SectorAddress DD ? |
dev_name: |
rb 41 |
endg |
;************************************************* |
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА * |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала (1 или 2); * |
;* DiskNumber - номер диска на канале (0 или 1). * |
;* Идентификационный блок данных считывается * |
;* в массив Sector512. * |
;************************************************* |
ReadHDD_ID: |
; Задать режим CHS |
mov [ATAAddressMode], 0 |
; Послать команду идентификации устройства |
mov [ATAFeatures], 0 |
mov [ATAHead], 0 |
mov [ATACommand], 0ECh |
call SendCommandToHDD |
cmp [DevErrorCode], 0;проверить код ошибки |
jne @@End ;закончить, сохранив код ошибки |
mov DX, [ATABasePortAddr] |
add DX, 7 ;адрес регистра состояни |
mov ecx, 0xffff |
@@WaitCompleet: |
; Проверить время выполнения команды |
dec ecx |
; cmp ecx,0 |
jz @@Error1 ;ошибка тайм-аута |
; Проверить готовность |
in AL, DX |
test AL, 80h ;состояние сигнала BSY |
jnz @@WaitCompleet |
test AL, 1 ;состояние сигнала ERR |
jnz @@Error6 |
test AL, 08h ;состояние сигнала DRQ |
jz @@WaitCompleet |
; Принять блок данных от контроллера |
; mov AX,DS |
; mov ES,AX |
mov EDI, Sector512 ;offset Sector512 |
mov DX, [ATABasePortAddr];регистр данных |
mov CX, 256 ;число считываемых слов |
rep insw ;принять блок данных |
ret |
; Записать код ошибки |
@@Error1: |
mov [DevErrorCode], 1 |
ret |
@@Error6: |
mov [DevErrorCode], 6 |
@@End: |
ret |
iglobal |
; Стандартные базовые адреса каналов 1 и 2 |
StandardATABases DW 1F0h, 170h |
endg |
uglobal |
; Номер канала |
ChannelNumber DW ? |
; Номер диска |
DiskNumber DB ? |
; Базовый адрес группы портов контроллера ATA |
ATABasePortAddr DW ? |
; Параметры ATA-команды |
ATAFeatures DB ? ;особенности |
ATASectorCount DB ? ;количество обрабатываемых секторов |
ATASectorNumber DB ? ;номер начального сектора |
ATACylinder DW ? ;номер начального цилиндра |
ATAHead DB ? ;номер начальной головки |
ATAAddressMode DB ? ;режим адресации (0 - CHS, 1 - LBA) |
ATACommand DB ? ;код команды, подлежащей выполнению |
; Код ошибки (0 - нет ошибок, 1 - превышен допустимый |
; интервал ожидания, 2 - неверный код режима адресации, |
; 3 - неверный номер канала, 4 - неверный номер диска, |
; 5 - неверный номер головки, 6 - ошибка при выполнении |
; команды) |
DevErrorCode dd ? |
endg |
;**************************************************** |
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала (1 или 2); * |
;* DiskNumber - номер диска (0 или 1); * |
;* ATAFeatures - "особенности"; * |
;* ATASectorCount - количество секторов; * |
;* ATASectorNumber - номер начального сектора; * |
;* ATACylinder - номер начального цилиндра; * |
;* ATAHead - номер начальной головки; * |
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); * |
;* ATACommand - код команды. * |
;* После успешного выполнения функции: * |
;* в ATABasePortAddr - базовый адрес HDD; * |
;* в DevErrorCode - ноль. * |
;* При возникновении ошибки в DevErrorCode будет * |
;* возвращен код ошибки. * |
;**************************************************** |
SendCommandToHDD: |
; Проверить значение кода режима |
cmp [ATAAddressMode], 1 |
ja @@Err2 |
; Проверить корректность номера канала |
mov BX, [ChannelNumber] |
cmp BX, 1 |
jb @@Err3 |
cmp BX, 2 |
ja @@Err3 |
; Установить базовый адрес |
dec BX |
shl BX, 1 |
movzx ebx, bx |
mov AX, [ebx+StandardATABases] |
mov [ATABasePortAddr], AX |
; Ожидание готовности HDD к приему команды |
; Выбрать нужный диск |
mov DX, [ATABasePortAddr] |
add DX, 6 ;адрес регистра головок |
mov AL, [DiskNumber] |
cmp AL, 1 ;проверить номера диска |
ja @@Err4 |
shl AL, 4 |
or AL, 10100000b |
out DX, AL |
; Ожидать, пока диск не будет готов |
inc DX |
mov ecx, 0xfff |
; mov eax,[timer_ticks] |
; mov [TickCounter_1],eax |
@@WaitHDReady: |
; Проверить время ожидани |
dec ecx |
; cmp ecx,0 |
jz @@Err1 |
; mov eax,[timer_ticks] |
; sub eax,[TickCounter_1] |
; cmp eax,300 ;ожидать 300 тиков |
; ja @@Err1 ;ошибка тайм-аута |
; Прочитать регистр состояни |
in AL, DX |
; Проверить состояние сигнала BSY |
test AL, 80h |
jnz @@WaitHDReady |
; Проверить состояние сигнала DRQ |
test AL, 08h |
jnz @@WaitHDReady |
; Загрузить команду в регистры контроллера |
cli |
mov DX, [ATABasePortAddr] |
inc DX ;регистр "особенностей" |
mov AL, [ATAFeatures] |
out DX, AL |
inc DX ;счетчик секторов |
mov AL, [ATASectorCount] |
out DX, AL |
inc DX ;регистр номера сектора |
mov AL, [ATASectorNumber] |
out DX, AL |
inc DX ;номер цилиндра (младший байт) |
mov AX, [ATACylinder] |
out DX, AL |
inc DX ;номер цилиндра (старший байт) |
mov AL, AH |
out DX, AL |
inc DX ;номер головки/номер диска |
mov AL, [DiskNumber] |
shl AL, 4 |
cmp [ATAHead], 0Fh;проверить номер головки |
ja @@Err5 |
or AL, [ATAHead] |
or AL, 10100000b |
mov AH, [ATAAddressMode] |
shl AH, 6 |
or AL, AH |
out DX, AL |
; Послать команду |
mov AL, [ATACommand] |
inc DX ;регистр команд |
out DX, AL |
sti |
; Сбросить признак ошибки |
mov [DevErrorCode], 0 |
ret |
; Записать код ошибки |
@@Err1: |
mov [DevErrorCode], 1 |
ret |
@@Err2: |
mov [DevErrorCode], 2 |
ret |
@@Err3: |
mov [DevErrorCode], 3 |
ret |
@@Err4: |
mov [DevErrorCode], 4 |
ret |
@@Err5: |
mov [DevErrorCode], 5 |
; Завершение работы программы |
ret |
;************************************************* |
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI * |
;* Входные параметры передаются через глобальные * |
;* перменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале. * |
;* Идентификационный блок данных считывается * |
;* в массив Sector512. * |
;************************************************* |
ReadCD_ID: |
; Задать режим CHS |
mov [ATAAddressMode], 0 |
; Послать команду идентификации устройства |
mov [ATAFeatures], 0 |
mov [ATASectorCount], 0 |
mov [ATASectorNumber], 0 |
mov [ATACylinder], 0 |
mov [ATAHead], 0 |
mov [ATACommand], 0A1h |
call SendCommandToHDD |
cmp [DevErrorCode], 0;проверить код ошибки |
jne @@End_1 ;закончить, сохранив код ошибки |
; Ожидать готовность данных HDD |
mov DX, [ATABasePortAddr] |
add DX, 7 ;порт 1х7h |
mov ecx, 0xffff |
@@WaitCompleet_1: |
; Проверить врем |
dec ecx |
; cmp ecx,0 |
jz @@Error1_1 ;ошибка тайм-аута |
; Проверить готовность |
in AL, DX |
test AL, 80h ;состояние сигнала BSY |
jnz @@WaitCompleet_1 |
test AL, 1 ;состояние сигнала ERR |
jnz @@Error6_1 |
test AL, 08h ;состояние сигнала DRQ |
jz @@WaitCompleet_1 |
; Принять блок данных от контроллера |
; mov AX,DS |
; mov ES,AX |
mov EDI, Sector512 ;offset Sector512 |
mov DX, [ATABasePortAddr];порт 1x0h |
mov CX, 256;число считываемых слов |
rep insw |
ret |
; Записать код ошибки |
@@Error1_1: |
mov [DevErrorCode], 1 |
ret |
@@Error6_1: |
mov [DevErrorCode], 6 |
@@End_1: |
ret |
;************************************************* |
;* СБРОС УСТРОЙСТВА * |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала (1 или 2); * |
;* DiskNumber - номер диска (0 или 1). * |
;************************************************* |
DeviceReset: |
; Проверить корректность номера канала |
mov BX, [ChannelNumber] |
cmp BX, 1 |
jb @@Err3_2 |
cmp BX, 2 |
ja @@Err3_2 |
; Установить базовый адрес |
dec BX |
shl BX, 1 |
movzx ebx, bx |
mov DX, [ebx+StandardATABases] |
mov [ATABasePortAddr], DX |
; Выбрать нужный диск |
add DX, 6 ;адрес регистра головок |
mov AL, [DiskNumber] |
cmp AL, 1 ;проверить номера диска |
ja @@Err4_2 |
shl AL, 4 |
or AL, 10100000b |
out DX, AL |
; Послать команду "Сброс" |
mov AL, 08h |
inc DX ;регистр команд |
out DX, AL |
mov ecx, 0x80000 |
@@WaitHDReady_1: |
; Проверить время ожидани |
dec ecx |
; cmp ecx,0 |
je @@Err1_2 ;ошибка тайм-аута |
; Прочитать регистр состояни |
in AL, DX |
; Проверить состояние сигнала BSY |
test AL, 80h |
jnz @@WaitHDReady_1 |
; Сбросить признак ошибки |
mov [DevErrorCode], 0 |
ret |
; Обработка ошибок |
@@Err1_2: |
mov [DevErrorCode], 1 |
ret |
@@Err3_2: |
mov [DevErrorCode], 3 |
ret |
@@Err4_2: |
mov [DevErrorCode], 4 |
; Записать код ошибки |
ret |
EndFindHDD: |
/kernel/branches/kolibri-process/detect/disks.inc |
---|
0,0 → 1,15 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 2455 $ |
include 'dev_fd.inc' |
include 'dev_hdcd.inc' |
include 'getcache.inc' |
include 'sear_par.inc' |
/kernel/branches/kolibri-process/detect/getcache.inc |
---|
0,0 → 1,130 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 3742 $ |
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 @f |
mov eax, 128*1024 |
@@: |
.continue: |
mov [cache_ide0_size], eax |
mov [cache_ide1_size], eax |
mov [cache_ide2_size], eax |
mov [cache_ide3_size], eax |
xor eax, eax |
mov [hdd_appl_data], 1;al |
mov [cd_appl_data], 1 |
test byte [DRIVE_DATA+1], 2 |
je .ide2 |
mov esi, cache_ide3 |
call get_cache_ide |
.ide2: |
test byte [DRIVE_DATA+1], 8 |
je .ide1 |
mov esi, cache_ide2 |
call get_cache_ide |
.ide1: |
test byte [DRIVE_DATA+1], 0x20 |
je .ide0 |
mov esi, cache_ide1 |
call get_cache_ide |
.ide0: |
test byte [DRIVE_DATA+1], 0x80 |
je @f |
mov esi, cache_ide0 |
call get_cache_ide |
@@: |
jmp end_get_cache |
get_cache_ide: |
and [esi+cache_ide0_search_start-cache_ide0], 0 |
and [esi+cache_ide0_appl_search_start-cache_ide0], 0 |
push ecx |
stdcall kernel_alloc, [esi+cache_ide0_size-cache_ide0] |
mov [esi+cache_ide0_pointer-cache_ide0], eax |
pop ecx |
mov edx, eax |
mov eax, [esi+cache_ide0_size-cache_ide0] |
shr eax, 3 |
mov [esi+cache_ide0_system_data_size-cache_ide0], eax |
mov ebx, eax |
imul eax, 7 |
mov [esi+cache_ide0_appl_data_size-cache_ide0], eax |
add ebx, edx |
mov [esi+cache_ide0_data_pointer-cache_ide0], ebx |
.cd: |
push ecx |
mov eax, [esi+cache_ide0_system_data_size-cache_ide0] |
call calculate_for_cd |
add eax, [esi+cache_ide0_pointer-cache_ide0] |
mov [esi+cache_ide0_system_data-cache_ide0], eax |
mov [esi+cache_ide0_system_sad_size-cache_ide0], ecx |
push edi |
mov edi, [esi+cache_ide0_pointer-cache_ide0] |
call clear_ide_cache |
pop edi |
mov eax, [esi+cache_ide0_appl_data_size-cache_ide0] |
call calculate_for_cd |
add eax, [esi+cache_ide0_data_pointer-cache_ide0] |
mov [esi+cache_ide0_appl_data-cache_ide0], eax |
mov [esi+cache_ide0_appl_sad_size-cache_ide0], ecx |
push edi |
mov edi, [esi+cache_ide0_data_pointer-cache_ide0] |
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 |
/kernel/branches/kolibri-process/detect/sear_par.inc |
---|
0,0 → 1,139 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 3742 $ |
search_partitions: |
; 1. Fill missing parameters in HD_DATA structures. |
mov eax, [hd_address_table] |
mov [hd0_data.hdbase], eax ;0x1f0 |
mov [hd1_data.hdbase], eax |
mov eax, [hd_address_table+16] |
mov [hd2_data.hdbase], eax |
mov [hd3_data.hdbase], eax |
; 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 |
@@: |
; 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. |
movzx eax, byte [BiosDisksData+esi*4] |
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: |
/kernel/branches/kolibri-process/detect/vortex86.inc |
---|
0,0 → 1,158 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2013. 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: 4310 $ |
VORTEX86DEBUG = 0 ; For testing in emulators and in non-Vortex86 CPU computers, set this to 1 |
VORTEX86DEBUGVALUE = 0x35504d44 ; 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: |