]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/BootSector/start32.asm
DuetPkg BootSector:
[mirror_edk2.git] / DuetPkg / BootSector / start32.asm
CommitLineData
c69dd9df 1;------------------------------------------------------------------------------\r
2;*\r
3a4b9eba 3;* Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
b1f700a8 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
3a4b9eba 411 mov bx,0008h ; Flat data descriptor\r
c69dd9df 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
c69dd9df 432JUMP:\r
433; jmp far 0010:00020000\r
434 db 066h\r
435 db 0eah\r
436 dd 000020000h\r
437 dw 00010h\r
438\r
439Empty8042InputBuffer:\r
440 mov cx,0\r
441Empty8042Loop:\r
442 out DELAY_PORT,ax ; Delay 1us\r
443 in al,KBD_STATUS_PORT ; Read the 8042 Status Port\r
444 and al,02h ; Check the Input Buffer Full Flag\r
445 loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS\r
446 ret\r
447\r
448;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
449; data\r
450;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
451\r
452 align 02h\r
453\r
454gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit\r
455 dd 0 ; (GDT base gets set above)\r
456;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
457; global descriptor table (GDT)\r
458;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
459\r
460 align 02h\r
461\r
462public GDT_BASE\r
463GDT_BASE:\r
464; null descriptor\r
465NULL_SEL equ $-GDT_BASE\r
466 dw 0 ; limit 15:0\r
467 dw 0 ; base 15:0\r
468 db 0 ; base 23:16\r
469 db 0 ; type\r
470 db 0 ; limit 19:16, flags\r
471 db 0 ; base 31:24\r
472\r
473; linear data segment descriptor\r
474LINEAR_SEL equ $-GDT_BASE\r
475 dw 0FFFFh ; limit 0xFFFFF\r
476 dw 0 ; base 0\r
477 db 0\r
478 db 092h ; present, ring 0, data, expand-up, writable\r
479 db 0CFh ; page-granular, 32-bit\r
480 db 0\r
481\r
482; linear code segment descriptor\r
483LINEAR_CODE_SEL equ $-GDT_BASE\r
484 dw 0FFFFh ; limit 0xFFFFF\r
485 dw 0 ; base 0\r
486 db 0\r
487 db 09Ah ; present, ring 0, data, expand-up, writable\r
488 db 0CFh ; page-granular, 32-bit\r
489 db 0\r
490\r
491; system data segment descriptor\r
492SYS_DATA_SEL equ $-GDT_BASE\r
493 dw 0FFFFh ; limit 0xFFFFF\r
494 dw 0 ; base 0\r
495 db 0\r
496 db 092h ; present, ring 0, data, expand-up, writable\r
497 db 0CFh ; page-granular, 32-bit\r
498 db 0\r
499\r
500; system code segment descriptor\r
501SYS_CODE_SEL equ $-GDT_BASE\r
502 dw 0FFFFh ; limit 0xFFFFF\r
503 dw 0 ; base 0\r
504 db 0\r
505 db 09Ah ; present, ring 0, data, expand-up, writable\r
506 db 0CFh ; page-granular, 32-bit\r
507 db 0\r
508\r
509; spare segment descriptor\r
510SPARE3_SEL equ $-GDT_BASE\r
511 dw 0 ; limit 0xFFFFF\r
512 dw 0 ; base 0\r
513 db 0\r
514 db 0 ; present, ring 0, data, expand-up, writable\r
515 db 0 ; page-granular, 32-bit\r
516 db 0\r
517\r
518; spare segment descriptor\r
519SPARE4_SEL equ $-GDT_BASE\r
520 dw 0 ; limit 0xFFFFF\r
521 dw 0 ; base 0\r
522 db 0\r
523 db 0 ; present, ring 0, data, expand-up, writable\r
524 db 0 ; page-granular, 32-bit\r
525 db 0\r
526\r
527; spare segment descriptor\r
528SPARE5_SEL equ $-GDT_BASE\r
529 dw 0 ; limit 0xFFFFF\r
530 dw 0 ; base 0\r
531 db 0\r
532 db 0 ; present, ring 0, data, expand-up, writable\r
533 db 0 ; page-granular, 32-bit\r
534 db 0\r
535\r
536GDT_END:\r
537\r
538 align 02h\r
539\r
540\r
541\r
542idtr dw IDT_END - IDT_BASE - 1 ; IDT limit\r
543 dd 0 ; (IDT base gets set above)\r
544;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
545; interrupt descriptor table (IDT)\r
546;\r
547; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ\r
548; mappings. This implementation only uses the system timer and all other\r
549; IRQs will remain masked. The descriptors for vectors 33+ are provided\r
550; for convenience.\r
551;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
552\r
553;idt_tag db "IDT",0 \r
554 align 02h\r
555\r
556public IDT_BASE\r
557IDT_BASE:\r
558; divide by zero (INT 0)\r
559DIV_ZERO_SEL equ $-IDT_BASE\r
560 dw 0 ; offset 15:0\r
561 dw SYS_CODE_SEL ; selector 15:0\r
562 db 0 ; 0 for interrupt gate\r
563 db 0eh OR 80h ; type = 386 interrupt gate, present\r
564 dw 0 ; offset 31:16\r
565\r
566; debug exception (INT 1)\r
567DEBUG_EXCEPT_SEL equ $-IDT_BASE\r
568 dw 0 ; offset 15:0\r
569 dw SYS_CODE_SEL ; selector 15:0\r
570 db 0 ; 0 for interrupt gate\r
571 db 0eh OR 80h ; type = 386 interrupt gate, present\r
572 dw 0 ; offset 31:16\r
573\r
574; NMI (INT 2)\r
575NMI_SEL equ $-IDT_BASE\r
576 dw 0 ; offset 15:0\r
577 dw SYS_CODE_SEL ; selector 15:0\r
578 db 0 ; 0 for interrupt gate\r
579 db 0eh OR 80h ; type = 386 interrupt gate, present\r
580 dw 0 ; offset 31:16\r
581\r
582; soft breakpoint (INT 3)\r
583BREAKPOINT_SEL equ $-IDT_BASE\r
584 dw 0 ; offset 15:0\r
585 dw SYS_CODE_SEL ; selector 15:0\r
586 db 0 ; 0 for interrupt gate\r
587 db 0eh OR 80h ; type = 386 interrupt gate, present\r
588 dw 0 ; offset 31:16\r
589\r
590; overflow (INT 4)\r
591OVERFLOW_SEL equ $-IDT_BASE\r
592 dw 0 ; offset 15:0\r
593 dw SYS_CODE_SEL ; selector 15:0\r
594 db 0 ; 0 for interrupt gate\r
595 db 0eh OR 80h ; type = 386 interrupt gate, present\r
596 dw 0 ; offset 31:16\r
597\r
598; bounds check (INT 5)\r
599BOUNDS_CHECK_SEL equ $-IDT_BASE\r
600 dw 0 ; offset 15:0\r
601 dw SYS_CODE_SEL ; selector 15:0\r
602 db 0 ; 0 for interrupt gate\r
603 db 0eh OR 80h ; type = 386 interrupt gate, present\r
604 dw 0 ; offset 31:16\r
605\r
606; invalid opcode (INT 6)\r
607INVALID_OPCODE_SEL equ $-IDT_BASE\r
608 dw 0 ; offset 15:0\r
609 dw SYS_CODE_SEL ; selector 15:0\r
610 db 0 ; 0 for interrupt gate\r
611 db 0eh OR 80h ; type = 386 interrupt gate, present\r
612 dw 0 ; offset 31:16\r
613\r
614; device not available (INT 7)\r
615DEV_NOT_AVAIL_SEL equ $-IDT_BASE\r
616 dw 0 ; offset 15:0\r
617 dw SYS_CODE_SEL ; selector 15:0\r
618 db 0 ; 0 for interrupt gate\r
619 db 0eh OR 80h ; type = 386 interrupt gate, present\r
620 dw 0 ; offset 31:16\r
621\r
622; double fault (INT 8)\r
623DOUBLE_FAULT_SEL equ $-IDT_BASE\r
624 dw 0 ; offset 15:0\r
625 dw SYS_CODE_SEL ; selector 15:0\r
626 db 0 ; 0 for interrupt gate\r
627 db 0eh OR 80h ; type = 386 interrupt gate, present\r
628 dw 0 ; offset 31:16\r
629\r
630; Coprocessor segment overrun - reserved (INT 9)\r
631RSVD_INTR_SEL1 equ $-IDT_BASE\r
632 dw 0 ; offset 15:0\r
633 dw SYS_CODE_SEL ; selector 15:0\r
634 db 0 ; 0 for interrupt gate\r
635 db 0eh OR 80h ; type = 386 interrupt gate, present\r
636 dw 0 ; offset 31:16\r
637\r
638; invalid TSS (INT 0ah)\r
639INVALID_TSS_SEL equ $-IDT_BASE\r
640 dw 0 ; offset 15:0\r
641 dw SYS_CODE_SEL ; selector 15:0\r
642 db 0 ; 0 for interrupt gate\r
643 db 0eh OR 80h ; type = 386 interrupt gate, present\r
644 dw 0 ; offset 31:16\r
645\r
646; segment not present (INT 0bh)\r
647SEG_NOT_PRESENT_SEL equ $-IDT_BASE\r
648 dw 0 ; offset 15:0\r
649 dw SYS_CODE_SEL ; selector 15:0\r
650 db 0 ; 0 for interrupt gate\r
651 db 0eh OR 80h ; type = 386 interrupt gate, present\r
652 dw 0 ; offset 31:16\r
653\r
654; stack fault (INT 0ch)\r
655STACK_FAULT_SEL equ $-IDT_BASE\r
656 dw 0 ; offset 15:0\r
657 dw SYS_CODE_SEL ; selector 15:0\r
658 db 0 ; 0 for interrupt gate\r
659 db 0eh OR 80h ; type = 386 interrupt gate, present\r
660 dw 0 ; offset 31:16\r
661\r
662; general protection (INT 0dh)\r
663GP_FAULT_SEL equ $-IDT_BASE\r
664 dw 0 ; offset 15:0\r
665 dw SYS_CODE_SEL ; selector 15:0\r
666 db 0 ; 0 for interrupt gate\r
667 db 0eh OR 80h ; type = 386 interrupt gate, present\r
668 dw 0 ; offset 31:16\r
669\r
670; page fault (INT 0eh)\r
671PAGE_FAULT_SEL equ $-IDT_BASE\r
672 dw 0 ; offset 15:0\r
673 dw SYS_CODE_SEL ; selector 15:0\r
674 db 0 ; 0 for interrupt gate\r
675 db 0eh OR 80h ; type = 386 interrupt gate, present\r
676 dw 0 ; offset 31:16\r
677\r
678; Intel reserved - do not use (INT 0fh)\r
679RSVD_INTR_SEL2 equ $-IDT_BASE\r
680 dw 0 ; offset 15:0\r
681 dw SYS_CODE_SEL ; selector 15:0\r
682 db 0 ; 0 for interrupt gate\r
683 db 0eh OR 80h ; type = 386 interrupt gate, present\r
684 dw 0 ; offset 31:16\r
685\r
686; floating point error (INT 10h)\r
687FLT_POINT_ERR_SEL equ $-IDT_BASE\r
688 dw 0 ; offset 15:0\r
689 dw SYS_CODE_SEL ; selector 15:0\r
690 db 0 ; 0 for interrupt gate\r
691 db 0eh OR 80h ; type = 386 interrupt gate, present\r
692 dw 0 ; offset 31:16\r
693\r
694; alignment check (INT 11h)\r
695ALIGNMENT_CHECK_SEL equ $-IDT_BASE\r
696 dw 0 ; offset 15:0\r
697 dw SYS_CODE_SEL ; selector 15:0\r
698 db 0 ; 0 for interrupt gate\r
699 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
700 dw 0 ; offset 31:16\r
701\r
702; machine check (INT 12h)\r
703MACHINE_CHECK_SEL equ $-IDT_BASE\r
704 dw 0 ; offset 15:0\r
705 dw SYS_CODE_SEL ; selector 15:0\r
706 db 0 ; 0 for interrupt gate\r
707 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
708 dw 0 ; offset 31:16\r
709\r
710; SIMD floating-point exception (INT 13h)\r
711SIMD_EXCEPTION_SEL equ $-IDT_BASE\r
712 dw 0 ; offset 15:0\r
713 dw SYS_CODE_SEL ; selector 15:0\r
714 db 0 ; 0 for interrupt gate\r
715 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
716 dw 0 ; offset 31:16\r
717\r
718; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail\r
719 db (85 * 8) dup(0)\r
720 \r
721; IRQ 0 (System timer) - (INT 68h)\r
722IRQ0_SEL equ $-IDT_BASE\r
723 dw 0 ; offset 15:0\r
724 dw SYS_CODE_SEL ; selector 15:0\r
725 db 0 ; 0 for interrupt gate\r
726 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
727 dw 0 ; offset 31:16\r
728\r
729; IRQ 1 (8042 Keyboard controller) - (INT 69h)\r
730IRQ1_SEL equ $-IDT_BASE\r
731 dw 0 ; offset 15:0\r
732 dw SYS_CODE_SEL ; selector 15:0\r
733 db 0 ; 0 for interrupt gate\r
734 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
735 dw 0 ; offset 31:16\r
736\r
737; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)\r
738IRQ2_SEL equ $-IDT_BASE\r
739 dw 0 ; offset 15:0\r
740 dw SYS_CODE_SEL ; selector 15:0\r
741 db 0 ; 0 for interrupt gate\r
742 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
743 dw 0 ; offset 31:16\r
744\r
745; IRQ 3 (COM 2) - (INT 6bh)\r
746IRQ3_SEL equ $-IDT_BASE\r
747 dw 0 ; offset 15:0\r
748 dw SYS_CODE_SEL ; selector 15:0\r
749 db 0 ; 0 for interrupt gate\r
750 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
751 dw 0 ; offset 31:16\r
752\r
753; IRQ 4 (COM 1) - (INT 6ch)\r
754IRQ4_SEL equ $-IDT_BASE\r
755 dw 0 ; offset 15:0\r
756 dw SYS_CODE_SEL ; selector 15:0\r
757 db 0 ; 0 for interrupt gate\r
758 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
759 dw 0 ; offset 31:16\r
760\r
761; IRQ 5 (LPT 2) - (INT 6dh)\r
762IRQ5_SEL equ $-IDT_BASE\r
763 dw 0 ; offset 15:0\r
764 dw SYS_CODE_SEL ; selector 15:0\r
765 db 0 ; 0 for interrupt gate\r
766 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
767 dw 0 ; offset 31:16\r
768\r
769; IRQ 6 (Floppy controller) - (INT 6eh)\r
770IRQ6_SEL equ $-IDT_BASE\r
771 dw 0 ; offset 15:0\r
772 dw SYS_CODE_SEL ; selector 15:0\r
773 db 0 ; 0 for interrupt gate\r
774 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
775 dw 0 ; offset 31:16\r
776\r
777; IRQ 7 (LPT 1) - (INT 6fh)\r
778IRQ7_SEL equ $-IDT_BASE\r
779 dw 0 ; offset 15:0\r
780 dw SYS_CODE_SEL ; selector 15:0\r
781 db 0 ; 0 for interrupt gate\r
782 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
783 dw 0 ; offset 31:16\r
784\r
785; IRQ 8 (RTC Alarm) - (INT 70h)\r
786IRQ8_SEL equ $-IDT_BASE\r
787 dw 0 ; offset 15:0\r
788 dw SYS_CODE_SEL ; selector 15:0\r
789 db 0 ; 0 for interrupt gate\r
790 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
791 dw 0 ; offset 31:16\r
792\r
793; IRQ 9 - (INT 71h)\r
794IRQ9_SEL equ $-IDT_BASE\r
795 dw 0 ; offset 15:0\r
796 dw SYS_CODE_SEL ; selector 15:0\r
797 db 0 ; 0 for interrupt gate\r
798 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
799 dw 0 ; offset 31:16\r
800\r
801; IRQ 10 - (INT 72h)\r
802IRQ10_SEL equ $-IDT_BASE\r
803 dw 0 ; offset 15:0\r
804 dw SYS_CODE_SEL ; selector 15:0\r
805 db 0 ; 0 for interrupt gate\r
806 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
807 dw 0 ; offset 31:16\r
808\r
809; IRQ 11 - (INT 73h)\r
810IRQ11_SEL equ $-IDT_BASE\r
811 dw 0 ; offset 15:0\r
812 dw SYS_CODE_SEL ; selector 15:0\r
813 db 0 ; 0 for interrupt gate\r
814 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
815 dw 0 ; offset 31:16\r
816\r
817; IRQ 12 (PS/2 mouse) - (INT 74h)\r
818IRQ12_SEL equ $-IDT_BASE\r
819 dw 0 ; offset 15:0\r
820 dw SYS_CODE_SEL ; selector 15:0\r
821 db 0 ; 0 for interrupt gate\r
822 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
823 dw 0 ; offset 31:16\r
824\r
825; IRQ 13 (Floating point error) - (INT 75h)\r
826IRQ13_SEL equ $-IDT_BASE\r
827 dw 0 ; offset 15:0\r
828 dw SYS_CODE_SEL ; selector 15:0\r
829 db 0 ; 0 for interrupt gate\r
830 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
831 dw 0 ; offset 31:16\r
832\r
833; IRQ 14 (Secondary IDE) - (INT 76h)\r
834IRQ14_SEL equ $-IDT_BASE\r
835 dw 0 ; offset 15:0\r
836 dw SYS_CODE_SEL ; selector 15:0\r
837 db 0 ; 0 for interrupt gate\r
838 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
839 dw 0 ; offset 31:16\r
840\r
841; IRQ 15 (Primary IDE) - (INT 77h)\r
842IRQ15_SEL equ $-IDT_BASE\r
843 dw 0 ; offset 15:0\r
844 dw SYS_CODE_SEL ; selector 15:0\r
845 db 0 ; 0 for interrupt gate\r
846 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
847 dw 0 ; offset 31:16\r
848\r
849IDT_END:\r
850\r
851 align 02h\r
852\r
853MemoryMapSize dd 0\r
854MemoryMap 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 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\r
885 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
886 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
887\r
888 org 0fe0h\r
889MyStack: \r
890 ; below is the pieces of the IVT that is used to redirect INT 68h - 6fh\r
891 ; back to INT 08h - 0fh when in real mode... It is 'org'ed to a\r
892 ; known low address (20f00) so it can be set up by PlMapIrqToVect in\r
893 ; 8259.c\r
894 \r
895 int 8\r
896 iret\r
897 \r
898 int 9\r
899 iret\r
900 \r
901 int 10\r
902 iret\r
903 \r
904 int 11\r
905 iret\r
906 \r
907 int 12\r
908 iret\r
909 \r
910 int 13\r
911 iret\r
912 \r
913 int 14\r
914 iret\r
915 \r
916 int 15\r
917 iret\r
918 \r
919 \r
920 org 0ffeh\r
921BlockSignature:\r
922 dw 0aa55h\r
923\r
924 end \r