Rev 4291 | Rev 4578 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4291 | Rev 4420 | ||
---|---|---|---|
Line 3... | Line 3... | ||
3 | ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 7... | Line 7... | ||
7 | 7 | ||
Line 8... | Line 8... | ||
8 | $Revision: 4291 $ |
8 | $Revision: 4420 $ |
9 | 9 | ||
10 | - | ||
11 | ; Low-level driver for HDD access |
10 | |
12 | ; DMA support by Mario79 |
11 | ; Low-level driver for HDD access |
13 | ; Access through BIOS by diamond |
12 | ; DMA support by Mario79 |
14 | ; LBA48 support by Mario79 |
13 | ; LBA48 support by Mario79 |
15 | ;----------------------------------------------------------------------------- |
14 | ;----------------------------------------------------------------------------- |
Line 30... | Line 29... | ||
30 | dd ide_write |
29 | dd ide_write |
31 | dd 0 ; no flush function |
30 | dd 0 ; no flush function |
32 | dd 0 ; use default cache size |
31 | dd 0 ; use default cache size |
33 | .end: |
32 | .end: |
Line 34... | Line -... | ||
34 | - | ||
35 | bd_callbacks: |
- | |
36 | dd bd_callbacks.end - bd_callbacks ; strucsize |
- | |
37 | dd 0 ; no close function |
- | |
38 | dd 0 ; no closemedia function |
- | |
39 | dd bd_querymedia |
- | |
40 | dd bd_read_interface |
- | |
41 | dd bd_write_interface |
- | |
42 | dd 0 ; no flush function |
- | |
43 | dd 0 ; use default cache size |
- | |
44 | .end: |
- | |
45 | 33 | ||
46 | hd0_data HD_DATA ?, 0, 1 |
34 | hd0_data HD_DATA ?, 0, 1 |
47 | hd1_data HD_DATA ?, 0x10, 2 |
35 | hd1_data HD_DATA ?, 0x10, 2 |
48 | hd2_data HD_DATA ?, 0, 3 |
36 | hd2_data HD_DATA ?, 0, 3 |
Line 281... | Line 269... | ||
281 | or dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF |
269 | or dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF |
282 | xor eax, eax |
270 | xor eax, eax |
283 | ret |
271 | ret |
284 | endp |
272 | endp |
Line 285... | Line -... | ||
285 | - | ||
286 | proc bd_read_interface stdcall uses edi, \ |
- | |
287 | userdata, buffer, startsector:qword, numsectors |
- | |
288 | ; userdata = old [hdpos] = 80h + index in NumBiosDisks |
- | |
289 | ; buffer = pointer to buffer for data |
- | |
290 | ; startsector = 64-bit start sector |
- | |
291 | ; numsectors = pointer to number of sectors on input, |
- | |
292 | ; must be filled with number of sectors really read |
- | |
293 | locals |
- | |
294 | sectors_todo dd ? |
- | |
295 | endl |
- | |
296 | ; 1. Initialize number of sectors: get number of requested sectors |
- | |
297 | ; and say that no sectors were read yet. |
- | |
298 | mov ecx, [numsectors] |
- | |
299 | mov eax, [ecx] |
- | |
300 | mov dword [ecx], 0 |
- | |
301 | mov [sectors_todo], eax |
- | |
302 | ; 2. Acquire the global lock. |
- | |
303 | mov ecx, ide_mutex |
- | |
304 | call mutex_lock |
- | |
305 | ; 3. Convert parameters to the form suitable for worker procedures. |
- | |
306 | ; Underlying procedures do not know about 64-bit sectors. |
- | |
307 | ; Worker procedures use global variables and edi for [buffer]. |
- | |
308 | cmp dword [startsector+4], 0 |
- | |
309 | jnz .fail |
- | |
310 | and [hd_error], 0 |
- | |
311 | mov eax, [userdata] |
- | |
312 | mov [hdpos], eax |
- | |
313 | mov eax, dword [startsector] |
- | |
314 | mov edi, [buffer] |
- | |
315 | ; 4. Worker procedures take one sectors per time, so loop over all sectors to read. |
- | |
316 | .sectors_loop: |
- | |
317 | call bd_read |
- | |
318 | cmp [hd_error], 0 |
- | |
319 | jnz .fail |
- | |
320 | mov ecx, [numsectors] |
- | |
321 | inc dword [ecx] ; one more sector is read |
- | |
322 | dec [sectors_todo] |
- | |
323 | jz .done |
- | |
324 | inc eax |
- | |
325 | jnz .sectors_loop |
- | |
326 | ; 5. Loop is done, either due to error or because everything is done. |
- | |
327 | ; Release the global lock and return the corresponding status. |
- | |
328 | .fail: |
- | |
329 | mov ecx, ide_mutex |
- | |
330 | call mutex_unlock |
- | |
331 | or eax, -1 |
- | |
332 | ret |
- | |
333 | .done: |
- | |
334 | mov ecx, ide_mutex |
- | |
335 | call mutex_unlock |
- | |
336 | xor eax, eax |
- | |
337 | ret |
- | |
338 | endp |
- | |
339 | - | ||
340 | proc bd_write_interface stdcall uses esi edi, \ |
- | |
341 | userdata, buffer, startsector:qword, numsectors |
- | |
342 | ; userdata = old [hdpos] = 80h + index in NumBiosDisks |
- | |
343 | ; buffer = pointer to buffer with data |
- | |
344 | ; startsector = 64-bit start sector |
- | |
345 | ; numsectors = pointer to number of sectors on input, |
- | |
346 | ; must be filled with number of sectors really written |
- | |
347 | locals |
- | |
348 | sectors_todo dd ? |
- | |
349 | endl |
- | |
350 | ; 1. Initialize number of sectors: get number of requested sectors |
- | |
351 | ; and say that no sectors were read yet. |
- | |
352 | mov ecx, [numsectors] |
- | |
353 | mov eax, [ecx] |
- | |
354 | mov dword [ecx], 0 |
- | |
355 | mov [sectors_todo], eax |
- | |
356 | ; 2. Acquire the global lock. |
- | |
357 | mov ecx, ide_mutex |
- | |
358 | call mutex_lock |
- | |
359 | ; 3. Convert parameters to the form suitable for worker procedures. |
- | |
360 | ; Underlying procedures do not know about 64-bit sectors. |
- | |
361 | ; Worker procedures use global variables and esi for [buffer]. |
- | |
362 | cmp dword [startsector+4], 0 |
- | |
363 | jnz .fail |
- | |
364 | and [hd_error], 0 |
- | |
365 | mov eax, [userdata] |
- | |
366 | mov [hdpos], eax |
- | |
367 | mov esi, [buffer] |
- | |
368 | lea edi, [startsector] |
- | |
369 | mov [cache_chain_ptr], edi |
- | |
370 | ; 4. Worker procedures take max 16 sectors per time, |
- | |
371 | ; loop until all sectors will be processed. |
- | |
372 | .sectors_loop: |
- | |
373 | mov ecx, 16 |
- | |
374 | cmp ecx, [sectors_todo] |
- | |
375 | jbe @f |
- | |
376 | mov ecx, [sectors_todo] |
- | |
377 | @@: |
- | |
378 | mov [cache_chain_size], cl |
- | |
379 | call bd_write_cache_chain |
- | |
380 | cmp [hd_error], 0 |
- | |
381 | jnz .fail |
- | |
382 | movzx ecx, [cache_chain_size] |
- | |
383 | mov eax, [numsectors] |
- | |
384 | add [eax], ecx |
- | |
385 | sub [sectors_todo], ecx |
- | |
386 | jz .done |
- | |
387 | add [edi], ecx |
- | |
388 | jc .fail |
- | |
389 | shl ecx, 9 |
- | |
390 | add esi, ecx |
- | |
391 | jmp .sectors_loop |
- | |
392 | ; 5. Loop is done, either due to error or because everything is done. |
- | |
393 | ; Release the global lock and return the corresponding status. |
- | |
394 | .fail: |
- | |
395 | mov ecx, ide_mutex |
- | |
396 | call mutex_unlock |
- | |
397 | or eax, -1 |
- | |
398 | ret |
- | |
399 | .done: |
- | |
400 | mov ecx, ide_mutex |
- | |
401 | call mutex_unlock |
- | |
402 | xor eax, eax |
- | |
403 | ret |
- | |
404 | endp |
- | |
405 | - | ||
406 | ; This is a stub. |
- | |
407 | proc bd_querymedia stdcall, hd_data, mediainfo |
- | |
408 | mov eax, [mediainfo] |
- | |
409 | mov [eax+DISKMEDIAINFO.Flags], 0 |
- | |
410 | mov [eax+DISKMEDIAINFO.SectorSize], 512 |
- | |
411 | or dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF |
- | |
412 | or dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF |
- | |
413 | xor eax, eax |
- | |
414 | ret |
- | |
415 | endp |
- | |
416 | 273 | ||
417 | ;----------------------------------------------------------------------------- |
274 | ;----------------------------------------------------------------------------- |
418 | align 4 |
275 | align 4 |
419 | ; input: eax = sector, edi -> buffer |
276 | ; input: eax = sector, edi -> buffer |
420 | ; output: edi = edi + 512 |
277 | ; output: edi = edi + 512 |
Line 1324... | Line 1181... | ||
1324 | IDE_BAR1_val dw ? |
1181 | IDE_BAR1_val dw ? |
1325 | IDE_BAR2_val dw ? |
1182 | IDE_BAR2_val dw ? |
1326 | IDE_BAR3_val dw ? |
1183 | IDE_BAR3_val dw ? |
1327 | endg |
1184 | endg |
1328 | ;----------------------------------------------------------------------------- |
1185 | ;----------------------------------------------------------------------------- |
1329 | ; \begin{diamond} |
- | |
1330 | uglobal |
- | |
1331 | bios_hdpos dd 0 ; 0 is invalid value for [hdpos] |
- | |
1332 | bios_cur_sector dd ? |
- | |
1333 | bios_read_len dd ? |
- | |
1334 | endg |
- | |
1335 | ;----------------------------------------------------------------------------- |
- | |
1336 | align 4 |
- | |
1337 | bd_read: |
- | |
1338 | push eax |
- | |
1339 | push edx |
- | |
1340 | mov edx, [bios_hdpos] |
- | |
1341 | cmp edx, [hdpos] |
- | |
1342 | jne .notread |
- | |
1343 | mov edx, [bios_cur_sector] |
- | |
1344 | cmp eax, edx |
- | |
1345 | jb .notread |
- | |
1346 | add edx, [bios_read_len] |
- | |
1347 | dec edx |
- | |
1348 | cmp eax, edx |
- | |
1349 | ja .notread |
- | |
1350 | sub eax, [bios_cur_sector] |
- | |
1351 | shl eax, 9 |
- | |
1352 | add eax, (OS_BASE+0x9A000) |
- | |
1353 | push ecx esi |
- | |
1354 | mov esi, eax |
- | |
1355 | mov ecx, 512/4 |
- | |
1356 | cld |
- | |
1357 | rep movsd |
- | |
1358 | pop esi ecx |
- | |
1359 | pop edx |
- | |
1360 | pop eax |
- | |
1361 | ret |
- | |
1362 | .notread: |
- | |
1363 | push ecx |
- | |
1364 | mov dl, 42h |
- | |
1365 | mov ecx, 16 |
- | |
1366 | call int13_call |
- | |
1367 | pop ecx |
- | |
1368 | test eax, eax |
- | |
1369 | jnz .v86err |
- | |
1370 | test edx, edx |
- | |
1371 | jz .readerr |
- | |
1372 | mov [bios_read_len], edx |
- | |
1373 | mov edx, [hdpos] |
- | |
1374 | mov [bios_hdpos], edx |
- | |
1375 | pop edx |
- | |
1376 | pop eax |
- | |
1377 | mov [bios_cur_sector], eax |
- | |
1378 | jmp bd_read |
- | |
1379 | .readerr: |
- | |
1380 | .v86err: |
- | |
1381 | mov [hd_error], 1 |
- | |
1382 | jmp hd_read_error |
- | |
1383 | ;----------------------------------------------------------------------------- |
- | |
1384 | align 4 |
- | |
1385 | bd_write_cache_chain: |
- | |
1386 | pusha |
- | |
1387 | mov edi, OS_BASE + 0x9A000 |
- | |
1388 | movzx ecx, [cache_chain_size] |
- | |
1389 | push ecx |
- | |
1390 | shl ecx, 9-2 |
- | |
1391 | rep movsd |
- | |
1392 | pop ecx |
- | |
1393 | mov dl, 43h |
- | |
1394 | mov eax, [cache_chain_ptr] |
- | |
1395 | mov eax, [eax] |
- | |
1396 | call int13_call |
- | |
1397 | test eax, eax |
- | |
1398 | jnz .v86err |
- | |
1399 | cmp edx, ecx |
- | |
1400 | jnz .writeerr |
- | |
1401 | popa |
- | |
1402 | ret |
- | |
1403 | .v86err: |
- | |
1404 | .writeerr: |
- | |
1405 | popa |
- | |
1406 | mov [hd_error], 1 |
- | |
1407 | jmp hd_write_error |
- | |
1408 | ;----------------------------------------------------------------------------- |
- | |
1409 | uglobal |
- | |
1410 | int13_regs_in rb sizeof.v86_regs |
- | |
1411 | int13_regs_out rb sizeof.v86_regs |
- | |
1412 | endg |
- | |
1413 | ;----------------------------------------------------------------------------- |
- | |
1414 | align 4 |
- | |
1415 | int13_call: |
- | |
1416 | ; Because this code uses fixed addresses, |
- | |
1417 | ; it can not be run simultaniously by many threads. |
- | |
1418 | ; In current implementation it is protected by common mutex 'ide_status' |
- | |
1419 | mov word [OS_BASE + 510h], 10h ; packet length |
- | |
1420 | mov word [OS_BASE + 512h], cx ; number of sectors |
- | |
1421 | mov dword [OS_BASE + 514h], 9A000000h ; buffer 9A00:0000 |
- | |
1422 | mov dword [OS_BASE + 518h], eax |
- | |
1423 | and dword [OS_BASE + 51Ch], 0 |
- | |
1424 | push ebx ecx esi edi |
- | |
1425 | mov ebx, int13_regs_in |
- | |
1426 | mov edi, ebx |
- | |
1427 | mov ecx, sizeof.v86_regs/4 |
- | |
1428 | xor eax, eax |
- | |
1429 | rep stosd |
- | |
1430 | mov byte [ebx+v86_regs.eax+1], dl |
- | |
1431 | mov eax, [hdpos] |
- | |
1432 | lea eax, [BiosDisksData+(eax-80h)*4] |
- | |
1433 | mov dl, [eax] |
- | |
1434 | mov byte [ebx+v86_regs.edx], dl |
- | |
1435 | movzx edx, byte [eax+1] |
- | |
1436 | ; mov dl, 5 |
- | |
1437 | test edx, edx |
- | |
1438 | jnz .hasirq |
- | |
1439 | dec edx |
- | |
1440 | jmp @f |
- | |
1441 | .hasirq: |
- | |
1442 | pushad |
- | |
1443 | stdcall enable_irq, edx |
- | |
1444 | popad |
- | |
1445 | @@: |
- | |
1446 | mov word [ebx+v86_regs.esi], 510h |
- | |
1447 | mov word [ebx+v86_regs.ss], 9000h |
- | |
1448 | mov word [ebx+v86_regs.esp], 0A000h |
- | |
1449 | mov word [ebx+v86_regs.eip], 500h |
- | |
1450 | mov [ebx+v86_regs.eflags], 20200h |
- | |
1451 | mov esi, [sys_v86_machine] |
- | |
1452 | mov ecx, 0x502 |
- | |
1453 | push fs |
- | |
1454 | call v86_start |
- | |
1455 | pop fs |
- | |
1456 | and [bios_hdpos], 0 |
- | |
1457 | pop edi esi ecx ebx |
- | |
1458 | movzx edx, byte [OS_BASE + 512h] |
- | |
1459 | test byte [int13_regs_out+v86_regs.eflags], 1 |
- | |
1460 | jnz @f |
- | |
1461 | mov edx, ecx |
- | |
1462 | @@: |
- | |
1463 | ret |
- | |
1464 | ; \end{diamond} |
- |