]> git.proxmox.com Git - mirror_edk2.git/blob - DuetPkg/BootSector/start16.asm
DuetPkg BootSector:
[mirror_edk2.git] / DuetPkg / BootSector / start16.asm
1 ;------------------------------------------------------------------------------
2 ;*
3 ;* Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4 ;* This program and the accompanying materials
5 ;* are licensed and made available under the terms and conditions of the BSD License
6 ;* which accompanies this distribution. The full text of the license may be found at
7 ;* http://opensource.org/licenses/bsd-license.php
8 ;*
9 ;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 ;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 ;*
12 ;* start16.asm
13 ;*
14 ;* Abstract:
15 ;*
16 ;------------------------------------------------------------------------------
17
18 .model small
19 .stack
20 .486p
21 .code
22
23 FAT_DIRECTORY_ENTRY_SIZE EQU 020h
24 FAT_DIRECTORY_ENTRY_SHIFT EQU 5
25 BLOCK_SIZE EQU 0200h
26 BLOCK_MASK EQU 01ffh
27 BLOCK_SHIFT EQU 9
28
29 org 0h
30 Ia32Jump:
31 jmp BootSectorEntryPoint ; JMP inst - 3 bytes
32 nop
33
34 OemId db "INTEL " ; OemId - 8 bytes
35
36 SectorSize dw 0 ; Sector Size - 16 bits
37 SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits
38 ReservedSectors dw 0 ; Reserved Sectors - 16 bits
39 NoFats db 0 ; Number of FATs - 8 bits
40 RootEntries dw 0 ; Root Entries - 16 bits
41 Sectors dw 0 ; Number of Sectors - 16 bits
42 Media db 0 ; Media - 8 bits - ignored
43 SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits
44 SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored
45 Heads dw 0 ; Heads - 16 bits - ignored
46 HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored
47 LargeSectors dd 0 ; Large Sectors - 32 bits
48 PhysicalDrive db 0 ; PhysicalDriveNumber - 8 bits - ignored
49 CurrentHead db 0 ; Current Head - 8 bits
50 Signature db 0 ; Signature - 8 bits - ignored
51 VolId db " " ; Volume Serial Number- 4 bytes
52 FatLabel db " " ; Label - 11 bytes
53 SystemId db "FAT16 " ; SystemId - 8 bytes
54
55 BootSectorEntryPoint:
56 ASSUME ds:@code
57 ASSUME ss:@code
58 ; ds = 1000, es = 2000 + x (size of first cluster >> 4)
59 ; cx = Start Cluster of EfiLdr
60 ; dx = Start Cluster of Efivar.bin
61
62 ; Re use the BPB data stored in Boot Sector
63 mov bp,07c00h
64
65 push cx
66 ; Read Efivar.bin
67 ; 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already
68 mov ax,01900h
69 mov es,ax
70 test dx,dx
71 jnz CheckVarStoreSize
72
73 mov al,1
74 NoVarStore:
75 push es
76 ; Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl
77 mov byte ptr es:[4],al
78 jmp SaveVolumeId
79
80 CheckVarStoreSize:
81 mov di,dx
82 cmp dword ptr ds:[di+2], 04000h
83 mov al,2
84 jne NoVarStore
85
86 LoadVarStore:
87 mov al,0
88 mov byte ptr es:[4],al
89 mov cx,word ptr[di]
90 ; ES:DI = 1500:0
91 xor di,di
92 push es
93 mov ax,01500h
94 mov es,ax
95 call ReadFile
96 SaveVolumeId:
97 pop es
98 mov ax,word ptr [bp+VolId]
99 mov word ptr es:[0],ax ; Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId
100 mov ax,word ptr [bp+VolId+2]
101 mov word ptr es:[2],ax
102
103 ; Read Efildr
104 pop cx
105 ; cx = Start Cluster of Efildr -> BS.com has filled already
106 ; ES:DI = 2000:0, first cluster will be read again
107 xor di,di ; di = 0
108 mov ax,02000h
109 mov es,ax
110 call ReadFile
111 mov ax,cs
112 mov word ptr cs:[JumpSegment],ax
113
114 JumpFarInstruction:
115 db 0eah
116 JumpOffset:
117 dw 0200h
118 JumpSegment:
119 dw 2000h
120
121
122
123 ; ****************************************************************************
124 ; ReadFile
125 ;
126 ; Arguments:
127 ; CX = Start Cluster of File
128 ; ES:DI = Buffer to store file content read from disk
129 ;
130 ; Return:
131 ; (ES << 4 + DI) = end of file content Buffer
132 ;
133 ; ****************************************************************************
134 ReadFile:
135 ; si = NumberOfClusters
136 ; cx = ClusterNumber
137 ; dx = CachedFatSectorNumber
138 ; ds:0000 = CacheFatSectorBuffer
139 ; es:di = Buffer to load file
140 ; bx = NextClusterNumber
141 pusha
142 mov si,1 ; NumberOfClusters = 1
143 push cx ; Push Start Cluster onto stack
144 mov dx,0fffh ; CachedFatSectorNumber = 0xfff
145 FatChainLoop:
146 mov ax,cx ; ax = ClusterNumber
147 and ax,0fff8h ; ax = ax & 0xfff8
148 cmp ax,0fff8h ; See if this is the last cluster
149 je FoundLastCluster ; Jump if last cluster found
150 mov ax,cx ; ax = ClusterNumber
151 shl ax,1 ; FatOffset = ClusterNumber * 2
152 push si ; Save si
153 mov si,ax ; si = FatOffset
154 shr ax,BLOCK_SHIFT ; ax = FatOffset >> BLOCK_SHIFT
155 add ax,word ptr [bp+ReservedSectors] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
156 and si,BLOCK_MASK ; si = FatOffset & BLOCK_MASK
157 cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber
158 je SkipFatRead
159 mov bx,2
160 push es
161 push ds
162 pop es
163 call ReadBlocks ; Read 2 blocks starting at AX storing at ES:DI
164 pop es
165 mov dx,ax ; CachedFatSectorNumber = FatSectorNumber
166 SkipFatRead:
167 mov bx,word ptr [si] ; bx = NextClusterNumber
168 mov ax,cx ; ax = ClusterNumber
169 pop si ; Restore si
170 dec bx ; bx = NextClusterNumber - 1
171 cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber
172 jne ReadClusters
173 inc bx ; bx = NextClusterNumber
174 inc si ; NumberOfClusters++
175 mov cx,bx ; ClusterNumber = NextClusterNumber
176 jmp FatChainLoop
177 ReadClusters:
178 inc bx
179 pop ax ; ax = StartCluster
180 push bx ; StartCluster = NextClusterNumber
181 mov cx,bx ; ClusterNumber = NextClusterNumber
182 sub ax,2 ; ax = StartCluster - 2
183 xor bh,bh
184 mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
185 mul bx ; ax = (StartCluster - 2) * SectorsPerCluster
186 add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
187 push ax ; save start sector
188 mov ax,si ; ax = NumberOfClusters
189 mul bx ; ax = NumberOfClusters * SectorsPerCluster
190 mov bx,ax ; bx = Number of Sectors
191 pop ax ; ax = Start Sector
192 call ReadBlocks
193 mov si,1 ; NumberOfClusters = 1
194 jmp FatChainLoop
195 FoundLastCluster:
196 pop cx
197 popa
198 ret
199
200
201 ; ****************************************************************************
202 ; ReadBlocks - Reads a set of blocks from a block device
203 ;
204 ; AX = Start LBA
205 ; BX = Number of Blocks to Read
206 ; ES:DI = Buffer to store sectors read from disk
207 ; ****************************************************************************
208
209 ; cx = Blocks
210 ; bx = NumberOfBlocks
211 ; si = StartLBA
212
213 ReadBlocks:
214 pusha
215 add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
216 add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
217 mov esi,eax ; esi = Start LBA
218 mov cx,bx ; cx = Number of blocks to read
219 ReadCylinderLoop:
220 mov bp,07bfch ; bp = 0x7bfc
221 mov eax,esi ; eax = Start LBA
222 xor edx,edx ; edx = 0
223 movzx ebx,word ptr [bp] ; bx = MaxSector
224 div ebx ; ax = StartLBA / MaxSector
225 inc dx ; dx = (StartLBA % MaxSector) + 1
226
227 mov bx,word ptr [bp] ; bx = MaxSector
228 sub bx,dx ; bx = MaxSector - Sector
229 inc bx ; bx = MaxSector - Sector + 1
230 cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
231 jg LimitTransfer
232 mov bx,cx ; bx = Blocks
233 LimitTransfer:
234 push ax ; save ax
235 mov ax,es ; ax = es
236 shr ax,(BLOCK_SHIFT-4) ; ax = Number of blocks into mem system
237 and ax,07fh ; ax = Number of blocks into current seg
238 add ax,bx ; ax = End Block number of transfer
239 cmp ax,080h ; See if it crosses a 64K boundry
240 jle NotCrossing64KBoundry ; Branch if not crossing 64K boundry
241 sub ax,080h ; ax = Number of blocks past 64K boundry
242 sub bx,ax ; Decrease transfer size by block overage
243 NotCrossing64KBoundry:
244 pop ax ; restore ax
245
246 push cx
247 mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
248 xor dx,dx ; dx = 0
249 div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
250 ; dx = ax % (MaxHead + 1) = Head
251
252 push bx ; Save number of blocks to transfer
253 mov dh,dl ; dh = Head
254 mov bp,07c00h ; bp = 0x7c00
255 mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
256 mov ch,al ; ch = Cylinder
257 mov al,bl ; al = Blocks
258 mov ah,2 ; ah = Function 2
259 mov bx,di ; es:bx = Buffer address
260 int 013h
261 jc DiskError
262 pop bx
263 pop cx
264 movzx ebx,bx
265 add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
266 sub cx,bx ; Blocks = Blocks - NumberOfBlocks
267 mov ax,es
268 shl bx,(BLOCK_SHIFT-4)
269 add ax,bx
270 mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
271 cmp cx,0
272 jne ReadCylinderLoop
273 popa
274 ret
275
276 DiskError:
277 push cs
278 pop ds
279 lea si, [ErrorString]
280 mov cx, 7
281 jmp PrintStringAndHalt
282
283 PrintStringAndHalt:
284 mov ax,0b800h
285 mov es,ax
286 mov di,160
287 rep movsw
288 Halt:
289 jmp Halt
290
291 ErrorString:
292 db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
293
294 org 01fah
295 LBAOffsetForBootSector:
296 dd 0h
297
298 org 01feh
299 dw 0aa55h
300
301 ;******************************************************************************
302 ;******************************************************************************
303 ;******************************************************************************
304
305 DELAY_PORT equ 0edh ; Port to use for 1uS delay
306 KBD_CONTROL_PORT equ 060h ; 8042 control port
307 KBD_STATUS_PORT equ 064h ; 8042 status port
308 WRITE_DATA_PORT_CMD equ 0d1h ; 8042 command to write the data port
309 ENABLE_A20_CMD equ 0dfh ; 8042 command to enable A20
310
311 org 200h
312 jmp start
313 Em64String:
314 db 'E', 0ch, 'm', 0ch, '6', 0ch, '4', 0ch, 'T', 0ch, ' ', 0ch, 'U', 0ch, 'n', 0ch, 's', 0ch, 'u', 0ch, 'p', 0ch, 'p', 0ch, 'o', 0ch, 'r', 0ch, 't', 0ch, 'e', 0ch, 'd', 0ch, '!', 0ch
315
316 start:
317 mov ax,cs
318 mov ds,ax
319 mov es,ax
320 mov ss,ax
321 mov sp,MyStack
322
323 ; mov ax,0b800h
324 ; mov es,ax
325 ; mov byte ptr es:[160],'a'
326 ; mov ax,cs
327 ; mov es,ax
328
329 mov ebx,0
330 lea edi,MemoryMap
331 MemMapLoop:
332 mov eax,0e820h
333 mov ecx,20
334 mov edx,'SMAP'
335 int 15h
336 jc MemMapDone
337 add edi,20
338 cmp ebx,0
339 je MemMapDone
340 jmp MemMapLoop
341 MemMapDone:
342 lea eax,MemoryMap
343 sub edi,eax ; Get the address of the memory map
344 mov dword ptr [MemoryMapSize],edi ; Save the size of the memory map
345
346 xor ebx,ebx
347 mov bx,cs ; BX=segment
348 shl ebx,4 ; BX="linear" address of segment base
349 lea eax,[GDT_BASE + ebx] ; EAX=PHYSICAL address of gdt
350 mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr
351 lea eax,[IDT_BASE + ebx] ; EAX=PHYSICAL address of idt
352 mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr
353 lea edx,[MemoryMapSize + ebx] ; Physical base address of the memory map
354
355 add ebx,01000h ; Source of EFI32
356 mov dword ptr [JUMP+2],ebx
357 add ebx,01000h
358 mov esi,ebx ; Source of EFILDR32
359
360 ; mov ax,0b800h
361 ; mov es,ax
362 ; mov byte ptr es:[162],'b'
363 ; mov ax,cs
364 ; mov es,ax
365
366 ;
367 ; Enable A20 Gate
368 ;
369
370 mov ax,2401h ; Enable A20 Gate
371 int 15h
372 jnc A20GateEnabled ; Jump if it suceeded
373
374 ;
375 ; If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually.
376 ;
377
378 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
379 jnz Timeout8042 ; Jump if the 8042 timed out
380 out DELAY_PORT,ax ; Delay 1 uS
381 mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port
382 out KBD_STATUS_PORT,al ; Send command to the 8042
383 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
384 jnz Timeout8042 ; Jump if the 8042 timed out
385 mov al,ENABLE_A20_CMD ; gate address bit 20 on
386 out KBD_CONTROL_PORT,al ; Send command to thre 8042
387 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
388 mov cx,25 ; Delay 25 uS for the command to complete on the 8042
389 Delay25uS:
390 out DELAY_PORT,ax ; Delay 1 uS
391 loop Delay25uS
392 Timeout8042:
393
394
395 A20GateEnabled:
396 mov bx,0008h ; Flat data descriptor
397 ;
398 ; DISABLE INTERRUPTS - Entering Protected Mode
399 ;
400
401 cli
402
403 ; mov ax,0b800h
404 ; mov es,ax
405 ; mov byte ptr es:[164],'c'
406 ; mov ax,cs
407 ; mov es,ax
408
409 db 66h
410 lgdt fword ptr [gdtr]
411 db 66h
412 lidt fword ptr [idtr]
413
414 mov eax,cr0
415 or al,1
416 mov cr0,eax
417 JUMP:
418 ; jmp far 0010:00020000
419 db 066h
420 db 0eah
421 dd 000020000h
422 dw 00010h
423
424 Empty8042InputBuffer:
425 mov cx,0
426 Empty8042Loop:
427 out DELAY_PORT,ax ; Delay 1us
428 in al,KBD_STATUS_PORT ; Read the 8042 Status Port
429 and al,02h ; Check the Input Buffer Full Flag
430 loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS
431 ret
432
433 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
434 ; data
435 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
436
437 align 02h
438
439 gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit
440 dd 0 ; (GDT base gets set above)
441 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
442 ; global descriptor table (GDT)
443 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
444
445 align 02h
446
447 public GDT_BASE
448 GDT_BASE:
449 ; null descriptor
450 NULL_SEL equ $-GDT_BASE
451 dw 0 ; limit 15:0
452 dw 0 ; base 15:0
453 db 0 ; base 23:16
454 db 0 ; type
455 db 0 ; limit 19:16, flags
456 db 0 ; base 31:24
457
458 ; linear data segment descriptor
459 LINEAR_SEL equ $-GDT_BASE
460 dw 0FFFFh ; limit 0xFFFFF
461 dw 0 ; base 0
462 db 0
463 db 092h ; present, ring 0, data, expand-up, writable
464 db 0CFh ; page-granular, 32-bit
465 db 0
466
467 ; linear code segment descriptor
468 LINEAR_CODE_SEL equ $-GDT_BASE
469 dw 0FFFFh ; limit 0xFFFFF
470 dw 0 ; base 0
471 db 0
472 db 09Ah ; present, ring 0, data, expand-up, writable
473 db 0CFh ; page-granular, 32-bit
474 db 0
475
476 ; system data segment descriptor
477 SYS_DATA_SEL equ $-GDT_BASE
478 dw 0FFFFh ; limit 0xFFFFF
479 dw 0 ; base 0
480 db 0
481 db 092h ; present, ring 0, data, expand-up, writable
482 db 0CFh ; page-granular, 32-bit
483 db 0
484
485 ; system code segment descriptor
486 SYS_CODE_SEL equ $-GDT_BASE
487 dw 0FFFFh ; limit 0xFFFFF
488 dw 0 ; base 0
489 db 0
490 db 09Ah ; present, ring 0, data, expand-up, writable
491 db 0CFh ; page-granular, 32-bit
492 db 0
493
494 ; spare segment descriptor
495 SPARE3_SEL equ $-GDT_BASE
496 dw 0 ; limit 0xFFFFF
497 dw 0 ; base 0
498 db 0
499 db 0 ; present, ring 0, data, expand-up, writable
500 db 0 ; page-granular, 32-bit
501 db 0
502
503 ; spare segment descriptor
504 SPARE4_SEL equ $-GDT_BASE
505 dw 0 ; limit 0xFFFFF
506 dw 0 ; base 0
507 db 0
508 db 0 ; present, ring 0, data, expand-up, writable
509 db 0 ; page-granular, 32-bit
510 db 0
511
512 ; spare segment descriptor
513 SPARE5_SEL equ $-GDT_BASE
514 dw 0 ; limit 0xFFFFF
515 dw 0 ; base 0
516 db 0
517 db 0 ; present, ring 0, data, expand-up, writable
518 db 0 ; page-granular, 32-bit
519 db 0
520
521 GDT_END:
522
523 align 02h
524
525
526
527 idtr dw IDT_END - IDT_BASE - 1 ; IDT limit
528 dd 0 ; (IDT base gets set above)
529 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
530 ; interrupt descriptor table (IDT)
531 ;
532 ; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
533 ; mappings. This implementation only uses the system timer and all other
534 ; IRQs will remain masked. The descriptors for vectors 33+ are provided
535 ; for convenience.
536 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
537
538 ;idt_tag db "IDT",0
539 align 02h
540
541 public IDT_BASE
542 IDT_BASE:
543 ; divide by zero (INT 0)
544 DIV_ZERO_SEL equ $-IDT_BASE
545 dw 0 ; offset 15:0
546 dw SYS_CODE_SEL ; selector 15:0
547 db 0 ; 0 for interrupt gate
548 db 0eh OR 80h ; type = 386 interrupt gate, present
549 dw 0 ; offset 31:16
550
551 ; debug exception (INT 1)
552 DEBUG_EXCEPT_SEL equ $-IDT_BASE
553 dw 0 ; offset 15:0
554 dw SYS_CODE_SEL ; selector 15:0
555 db 0 ; 0 for interrupt gate
556 db 0eh OR 80h ; type = 386 interrupt gate, present
557 dw 0 ; offset 31:16
558
559 ; NMI (INT 2)
560 NMI_SEL equ $-IDT_BASE
561 dw 0 ; offset 15:0
562 dw SYS_CODE_SEL ; selector 15:0
563 db 0 ; 0 for interrupt gate
564 db 0eh OR 80h ; type = 386 interrupt gate, present
565 dw 0 ; offset 31:16
566
567 ; soft breakpoint (INT 3)
568 BREAKPOINT_SEL equ $-IDT_BASE
569 dw 0 ; offset 15:0
570 dw SYS_CODE_SEL ; selector 15:0
571 db 0 ; 0 for interrupt gate
572 db 0eh OR 80h ; type = 386 interrupt gate, present
573 dw 0 ; offset 31:16
574
575 ; overflow (INT 4)
576 OVERFLOW_SEL equ $-IDT_BASE
577 dw 0 ; offset 15:0
578 dw SYS_CODE_SEL ; selector 15:0
579 db 0 ; 0 for interrupt gate
580 db 0eh OR 80h ; type = 386 interrupt gate, present
581 dw 0 ; offset 31:16
582
583 ; bounds check (INT 5)
584 BOUNDS_CHECK_SEL equ $-IDT_BASE
585 dw 0 ; offset 15:0
586 dw SYS_CODE_SEL ; selector 15:0
587 db 0 ; 0 for interrupt gate
588 db 0eh OR 80h ; type = 386 interrupt gate, present
589 dw 0 ; offset 31:16
590
591 ; invalid opcode (INT 6)
592 INVALID_OPCODE_SEL equ $-IDT_BASE
593 dw 0 ; offset 15:0
594 dw SYS_CODE_SEL ; selector 15:0
595 db 0 ; 0 for interrupt gate
596 db 0eh OR 80h ; type = 386 interrupt gate, present
597 dw 0 ; offset 31:16
598
599 ; device not available (INT 7)
600 DEV_NOT_AVAIL_SEL equ $-IDT_BASE
601 dw 0 ; offset 15:0
602 dw SYS_CODE_SEL ; selector 15:0
603 db 0 ; 0 for interrupt gate
604 db 0eh OR 80h ; type = 386 interrupt gate, present
605 dw 0 ; offset 31:16
606
607 ; double fault (INT 8)
608 DOUBLE_FAULT_SEL equ $-IDT_BASE
609 dw 0 ; offset 15:0
610 dw SYS_CODE_SEL ; selector 15:0
611 db 0 ; 0 for interrupt gate
612 db 0eh OR 80h ; type = 386 interrupt gate, present
613 dw 0 ; offset 31:16
614
615 ; Coprocessor segment overrun - reserved (INT 9)
616 RSVD_INTR_SEL1 equ $-IDT_BASE
617 dw 0 ; offset 15:0
618 dw SYS_CODE_SEL ; selector 15:0
619 db 0 ; 0 for interrupt gate
620 db 0eh OR 80h ; type = 386 interrupt gate, present
621 dw 0 ; offset 31:16
622
623 ; invalid TSS (INT 0ah)
624 INVALID_TSS_SEL equ $-IDT_BASE
625 dw 0 ; offset 15:0
626 dw SYS_CODE_SEL ; selector 15:0
627 db 0 ; 0 for interrupt gate
628 db 0eh OR 80h ; type = 386 interrupt gate, present
629 dw 0 ; offset 31:16
630
631 ; segment not present (INT 0bh)
632 SEG_NOT_PRESENT_SEL equ $-IDT_BASE
633 dw 0 ; offset 15:0
634 dw SYS_CODE_SEL ; selector 15:0
635 db 0 ; 0 for interrupt gate
636 db 0eh OR 80h ; type = 386 interrupt gate, present
637 dw 0 ; offset 31:16
638
639 ; stack fault (INT 0ch)
640 STACK_FAULT_SEL equ $-IDT_BASE
641 dw 0 ; offset 15:0
642 dw SYS_CODE_SEL ; selector 15:0
643 db 0 ; 0 for interrupt gate
644 db 0eh OR 80h ; type = 386 interrupt gate, present
645 dw 0 ; offset 31:16
646
647 ; general protection (INT 0dh)
648 GP_FAULT_SEL equ $-IDT_BASE
649 dw 0 ; offset 15:0
650 dw SYS_CODE_SEL ; selector 15:0
651 db 0 ; 0 for interrupt gate
652 db 0eh OR 80h ; type = 386 interrupt gate, present
653 dw 0 ; offset 31:16
654
655 ; page fault (INT 0eh)
656 PAGE_FAULT_SEL equ $-IDT_BASE
657 dw 0 ; offset 15:0
658 dw SYS_CODE_SEL ; selector 15:0
659 db 0 ; 0 for interrupt gate
660 db 0eh OR 80h ; type = 386 interrupt gate, present
661 dw 0 ; offset 31:16
662
663 ; Intel reserved - do not use (INT 0fh)
664 RSVD_INTR_SEL2 equ $-IDT_BASE
665 dw 0 ; offset 15:0
666 dw SYS_CODE_SEL ; selector 15:0
667 db 0 ; 0 for interrupt gate
668 db 0eh OR 80h ; type = 386 interrupt gate, present
669 dw 0 ; offset 31:16
670
671 ; floating point error (INT 10h)
672 FLT_POINT_ERR_SEL equ $-IDT_BASE
673 dw 0 ; offset 15:0
674 dw SYS_CODE_SEL ; selector 15:0
675 db 0 ; 0 for interrupt gate
676 db 0eh OR 80h ; type = 386 interrupt gate, present
677 dw 0 ; offset 31:16
678
679 ; alignment check (INT 11h)
680 ALIGNMENT_CHECK_SEL equ $-IDT_BASE
681 dw 0 ; offset 15:0
682 dw SYS_CODE_SEL ; selector 15:0
683 db 0 ; 0 for interrupt gate
684 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
685 dw 0 ; offset 31:16
686
687 ; machine check (INT 12h)
688 MACHINE_CHECK_SEL equ $-IDT_BASE
689 dw 0 ; offset 15:0
690 dw SYS_CODE_SEL ; selector 15:0
691 db 0 ; 0 for interrupt gate
692 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
693 dw 0 ; offset 31:16
694
695 ; SIMD floating-point exception (INT 13h)
696 SIMD_EXCEPTION_SEL equ $-IDT_BASE
697 dw 0 ; offset 15:0
698 dw SYS_CODE_SEL ; selector 15:0
699 db 0 ; 0 for interrupt gate
700 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
701 dw 0 ; offset 31:16
702
703 ; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
704 db (85 * 8) dup(0)
705
706 ; IRQ 0 (System timer) - (INT 68h)
707 IRQ0_SEL equ $-IDT_BASE
708 dw 0 ; offset 15:0
709 dw SYS_CODE_SEL ; selector 15:0
710 db 0 ; 0 for interrupt gate
711 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
712 dw 0 ; offset 31:16
713
714 ; IRQ 1 (8042 Keyboard controller) - (INT 69h)
715 IRQ1_SEL equ $-IDT_BASE
716 dw 0 ; offset 15:0
717 dw SYS_CODE_SEL ; selector 15:0
718 db 0 ; 0 for interrupt gate
719 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
720 dw 0 ; offset 31:16
721
722 ; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
723 IRQ2_SEL equ $-IDT_BASE
724 dw 0 ; offset 15:0
725 dw SYS_CODE_SEL ; selector 15:0
726 db 0 ; 0 for interrupt gate
727 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
728 dw 0 ; offset 31:16
729
730 ; IRQ 3 (COM 2) - (INT 6bh)
731 IRQ3_SEL equ $-IDT_BASE
732 dw 0 ; offset 15:0
733 dw SYS_CODE_SEL ; selector 15:0
734 db 0 ; 0 for interrupt gate
735 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
736 dw 0 ; offset 31:16
737
738 ; IRQ 4 (COM 1) - (INT 6ch)
739 IRQ4_SEL equ $-IDT_BASE
740 dw 0 ; offset 15:0
741 dw SYS_CODE_SEL ; selector 15:0
742 db 0 ; 0 for interrupt gate
743 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
744 dw 0 ; offset 31:16
745
746 ; IRQ 5 (LPT 2) - (INT 6dh)
747 IRQ5_SEL equ $-IDT_BASE
748 dw 0 ; offset 15:0
749 dw SYS_CODE_SEL ; selector 15:0
750 db 0 ; 0 for interrupt gate
751 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
752 dw 0 ; offset 31:16
753
754 ; IRQ 6 (Floppy controller) - (INT 6eh)
755 IRQ6_SEL equ $-IDT_BASE
756 dw 0 ; offset 15:0
757 dw SYS_CODE_SEL ; selector 15:0
758 db 0 ; 0 for interrupt gate
759 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
760 dw 0 ; offset 31:16
761
762 ; IRQ 7 (LPT 1) - (INT 6fh)
763 IRQ7_SEL equ $-IDT_BASE
764 dw 0 ; offset 15:0
765 dw SYS_CODE_SEL ; selector 15:0
766 db 0 ; 0 for interrupt gate
767 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
768 dw 0 ; offset 31:16
769
770 ; IRQ 8 (RTC Alarm) - (INT 70h)
771 IRQ8_SEL equ $-IDT_BASE
772 dw 0 ; offset 15:0
773 dw SYS_CODE_SEL ; selector 15:0
774 db 0 ; 0 for interrupt gate
775 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
776 dw 0 ; offset 31:16
777
778 ; IRQ 9 - (INT 71h)
779 IRQ9_SEL equ $-IDT_BASE
780 dw 0 ; offset 15:0
781 dw SYS_CODE_SEL ; selector 15:0
782 db 0 ; 0 for interrupt gate
783 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
784 dw 0 ; offset 31:16
785
786 ; IRQ 10 - (INT 72h)
787 IRQ10_SEL equ $-IDT_BASE
788 dw 0 ; offset 15:0
789 dw SYS_CODE_SEL ; selector 15:0
790 db 0 ; 0 for interrupt gate
791 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
792 dw 0 ; offset 31:16
793
794 ; IRQ 11 - (INT 73h)
795 IRQ11_SEL equ $-IDT_BASE
796 dw 0 ; offset 15:0
797 dw SYS_CODE_SEL ; selector 15:0
798 db 0 ; 0 for interrupt gate
799 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
800 dw 0 ; offset 31:16
801
802 ; IRQ 12 (PS/2 mouse) - (INT 74h)
803 IRQ12_SEL equ $-IDT_BASE
804 dw 0 ; offset 15:0
805 dw SYS_CODE_SEL ; selector 15:0
806 db 0 ; 0 for interrupt gate
807 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
808 dw 0 ; offset 31:16
809
810 ; IRQ 13 (Floating point error) - (INT 75h)
811 IRQ13_SEL equ $-IDT_BASE
812 dw 0 ; offset 15:0
813 dw SYS_CODE_SEL ; selector 15:0
814 db 0 ; 0 for interrupt gate
815 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
816 dw 0 ; offset 31:16
817
818 ; IRQ 14 (Secondary IDE) - (INT 76h)
819 IRQ14_SEL equ $-IDT_BASE
820 dw 0 ; offset 15:0
821 dw SYS_CODE_SEL ; selector 15:0
822 db 0 ; 0 for interrupt gate
823 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
824 dw 0 ; offset 31:16
825
826 ; IRQ 15 (Primary IDE) - (INT 77h)
827 IRQ15_SEL equ $-IDT_BASE
828 dw 0 ; offset 15:0
829 dw SYS_CODE_SEL ; selector 15:0
830 db 0 ; 0 for interrupt gate
831 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
832 dw 0 ; offset 31:16
833
834 IDT_END:
835
836 align 02h
837
838 MemoryMapSize dd 0
839 MemoryMap dd 0,0,0,0,0,0,0,0
840 dd 0,0,0,0,0,0,0,0
841 dd 0,0,0,0,0,0,0,0
842 dd 0,0,0,0,0,0,0,0
843 dd 0,0,0,0,0,0,0,0
844 dd 0,0,0,0,0,0,0,0
845 dd 0,0,0,0,0,0,0,0
846 dd 0,0,0,0,0,0,0,0
847 dd 0,0,0,0,0,0,0,0
848 dd 0,0,0,0,0,0,0,0
849 dd 0,0,0,0,0,0,0,0
850 dd 0,0,0,0,0,0,0,0
851 dd 0,0,0,0,0,0,0,0
852 dd 0,0,0,0,0,0,0,0
853 dd 0,0,0,0,0,0,0,0
854 dd 0,0,0,0,0,0,0,0
855 dd 0,0,0,0,0,0,0,0
856 dd 0,0,0,0,0,0,0,0
857 dd 0,0,0,0,0,0,0,0
858 dd 0,0,0,0,0,0,0,0
859 dd 0,0,0,0,0,0,0,0
860 dd 0,0,0,0,0,0,0,0
861 dd 0,0,0,0,0,0,0,0
862 dd 0,0,0,0,0,0,0,0
863 dd 0,0,0,0,0,0,0,0
864 dd 0,0,0,0,0,0,0,0
865 dd 0,0,0,0,0,0,0,0
866 dd 0,0,0,0,0,0,0,0
867 dd 0,0,0,0,0,0,0,0
868 dd 0,0,0,0,0,0,0,0
869
870 dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
871 dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
872
873 org 0fe0h
874 MyStack:
875 ; below is the pieces of the IVT that is used to redirect INT 68h - 6fh
876 ; back to INT 08h - 0fh when in real mode... It is 'org'ed to a
877 ; known low address (20f00) so it can be set up by PlMapIrqToVect in
878 ; 8259.c
879
880 int 8
881 iret
882
883 int 9
884 iret
885
886 int 10
887 iret
888
889 int 11
890 iret
891
892 int 12
893 iret
894
895 int 13
896 iret
897
898 int 14
899 iret
900
901 int 15
902 iret
903
904
905 org 0ffeh
906 BlockSignature:
907 dw 0aa55h
908
909 end