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