3 Copyright 2003-2004 John Coffman.
6 Licensed under the terms contained in the file 'COPYING' in the
14 vtab: .blkw MAX_BIOS_DEVICES_asm*2 ; volume IDs indexed by
15 ; REAL bios device code
17 rtab: .blkw MAX_BIOS_DEVICES_asm*2 ; raid offsets indexed the same
20 devmap: .blkw MAX_BIOS_DEVICES+2 ; device code map
26 .org *+MAX_BIOS_DEVICES_asm*4 ; volume IDs indexed by
27 ; REAL bios device code
30 .org *+MAX_BIOS_DEVICES_asm*4 ; raid offsets indexed the same
34 .org *+MAX_BIOS_DEVICES*2+4 ; device code map
40 rmask: .word 0 ; physical raid mask
42 ; build_vol_tab -- Build the table of volume IDs
43 ; and fill in the device translate table
51 ; Side effects: The volume ID table is built
52 ; The from:to device translate table is filled in
58 xor cx,cx ; depend on this being preserved
60 xchg [devmap],dx ; clear our First Stage mapping
62 call is_prev_mapper ; is there a previous mapper
65 ; have previous mapper active
69 or dx,dx ; any translation?
73 mov ax,(di) ; get previous translation
78 cmp al,dh ; does it affect us?
80 mov [init_dx],ah ; update physical device
86 mov (di),cx ; sterilize it
92 mov di,#KEYTABLE+256+mt_serial_no
93 mov cx,#MAX_BIOS_DEVICES_asm
96 scasd ; scan for any serial nos in table
97 je bvt90 ; if none, skip reading vol_ids
98 ; as there will be no translations
102 xor cx,cx ; start at hard drive 0 (0x80)
103 mov di,#vtab ; place to put IDs
105 call read_vol_id ; get VolumeID in EAX
106 stosd ; store in table
107 or eax,eax ; test for zero
108 jz bvt9 ; end, or no volume ID
110 ; now see if there will be a translation
115 mov cx,di ; 4*table count to CX
118 shr cx,#2 ; table count
120 jz bvt1.5 ; table empty
121 repne ; repeat while no match
125 mov bx,#msg_dupl ; duplicate message
133 mov dword (di-4),#0 ; zero the duplicated volumeID
134 jmp bvt9 ; skip to next on duplication
138 mov si,#KEYTABLE+256+mt_serial_no
139 mov cx,#MAX_BIOS_DEVICES_asm
142 repne ; repeat while not matching
144 jne bvt7 ; jump if no match
146 ; print the raw serial_no match
153 lea dx,(di-4) ; DX is address of match
154 sub dx,si ; DX is 4*index
155 shr dx,#2 ; DX is input device #
156 pop bx ; BX is real device #
160 ;;; je bvt2 ; equal means no translation
161 je bvt7 ; equal means no translation
164 or dx,#0x8080 ; make into HD bios codes
166 ; print the raw TT entry
174 mov bx,#devmap ; scan the device translation table
176 mov si,(bx) ; get from(low):to(high) pair
178 inc bx ; bump pointer by 2
179 cmp si,dx ; duplicate?
182 or si,si ; not duplicate; at end?
185 mov (bx-2),dx ; put at end of table
186 mov (bx),si ; and mark new end
198 cmp cx,#MAX_BIOS_DEVICES_asm
202 ; now build the RAID offset table
204 mov si,#KEYTABLE+256+mt_raid_offset
205 mov dx,[KEYTABLE+256+mt_raid_dev_mask]
206 xor bx,bx ; count thru devices
208 xor eax,eax ; may store 0
209 shr dx,#1 ; is it raid?
210 jnc bvt92 ; not a raid device
212 lodsd ; get raid offset
213 push eax ; save value in stack
215 mov eax,[KEYTABLE+256+mt_serial_no](bx)
216 mov di,#vtab ; physical table address
217 mov cx,#MAX_BIOS_DEVICES_asm
219 scasd ; scan for a match
220 jne bvt_not_found ; the logical volume is not there
221 lea di,(di-4-vtab) ; DI is 4*index into table
223 shr cx,#2 ; make 0..15
225 shl ax,cl ; mask bit in right position
227 pop dword ptr rtab(di) ; store RAID offset
230 pop eax ; clean up the stack
233 cmp bx,#MAX_BIOS_DEVICES_asm*4
241 mov cx,#MAX_BIOS_DEVICES_asm
242 ;;; mov dx,[KEYTABLE+256+mt_raid_dev_mask] ; was logical mask
243 mov dx,[rmask] ; get physical mask value
245 ; truncate all the empty entries from the end of the list
250 cmp dword ptr (bx+si),#0
257 lodsd ; get volume serial number
270 loop bvtX ; loop back
274 ; now the device translate table:
279 bvtB: lodsw ; get from,to pair
294 popa ; restore all the regs
298 .ascii "O\nError: Duplicated Volume ID\n"
303 .ascii "The physical VolumeID / Raid1-reloc table\n"
305 msg_star: .ascii " * "
307 msg_nostar: .ascii " "
309 msg_space = msg_nostar
311 msg_tt: .ascii "The device translate table:\n"
313 msg_arr: .ascii " -> "
315 msg_plus: .ascii " + "
317 msg_rw: .ascii "RAID physical write: "
322 ; ****** 22.6.1 begin
324 ; enable_readahead -- Enable readahead on an EDD drive
327 ; DL = hard disk BIOS code
331 ; Nothing -- enable read-ahead, if possible
336 push dx ; save device code
339 pop dx ; restore device code
341 mov bx,#0x55AA ;magic number
342 mov ah,#0x41 ;function call
345 cmp bx,#0xAA55 ;magic return
347 test cl,#EDD_SUBSET|EDD_PACKET ; some EDD support?
350 cmp ah,#0x21 ; EDD version 1.1 or later?
354 mov ax,#0x4E00 ; enable prefetch
359 test ah,ah ; check return code in AH
376 ; read_vol_id -- Read the volume ID off of a drive
379 ; CX = drive number to read (hard disk 0..15)
383 ; Carry Clear on success
384 ; EAX = volume ID (0 means no ID)
397 push es ; paranoia (floppies touch it)
399 mov ah,#8 ; get number of drives in DL
401 call dsk_do_int13 ; retry 5 times
404 pop cx ; restore device code
417 call enable_readahead
425 mov eax,(bx+PART_TABLE_OFFSET-6) ; fetch return
438 ; map_device -- Take the logical device code in DL and map it
439 ; into the physical device code preserving all flags
440 ; 22.5.6 Any RAID relocated device code maps to the boot device code
443 ; DL containing logical device code & flags
444 ; DS register not guaranteed
447 ; DL containing physical device code & same flags
451 push si ; save working registers
454 mov si,#devmap ; point at translation table
456 and bl,#DEV_MASK_asm ; from device code in BL
460 mov ah,[init_dx] ; get boot device code
461 test dl,#RAID_REL_FLAG
462 jnz bios_tt_match ; it is RAID, go use the boot device code
466 seg cs ; DS may be bad
467 lodsw ; get from/to pair
468 or ax,ax ; end of list?
474 and dl,#0xFF-DEV_MASK_asm ; save flags
475 or dl,ah ; put on the TO device code
485 ; rev_map_device -- Take the physical device code in DL and map it
486 ; into the logical device code preserving all flags
489 ; DL containing physical device code & flags
492 ; DL containing logical device code & same flags
496 push si ; save working registers
499 mov si,#devmap ; point at translation table
501 and bl,#DEV_MASK_asm ; TO device code in BL
503 lodsw ; get from/to pair
504 or ax,ax ; end of list?
509 and dl,#0xFF-DEV_MASK_asm ; save flags
510 or dl,al ; put on the FROM device code
519 ; translate -- test for a raid device, and do the offsetting
522 ; DI:CX LBA32 or LINEAR address
523 ; DL physical device code & flags (RAID_REL_FLAG is set)
525 ; ES:BX buffer pointer for R/W
528 ; DI:CX updated if RAID translation takes place
529 ; All other registers are unchanged
536 cmp word [rmask],#0 ; any translate bits set?
539 ; this special cases the initial Keytable read, when no setup has been done
542 add cx,par1_raid_offset+SSDIFF ; ***** RAID ******
544 adc di,par1_raid_offset+2+SSDIFF ; ***** RAID ******
550 push cx ; form dword (bp-4)
552 mov di,dx ; DI gets full device code
553 and di,#DEV_MASK_asm & 0x7F
556 cmp byte ptr [dsk_wrflag],#0
571 shl di,#2 ; index into array
573 mov cx,[rtab](di) ; get low relocation value
574 mov di,[rtab+2](di) ; get high relocation value
577 cmp byte ptr [dsk_wrflag],#0
590 add (bp-4),cx ; relocate
597 cmp byte ptr [dsk_wrflag],#0
611 #endif /* BSS_DATA */