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