]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/BootSector/start.asm
Remove exit from batch file
[mirror_edk2.git] / DuetPkg / BootSector / start.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;* start.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 "FAT12 " ; 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,0ff8h ; ax = ax & 0xff8\r
148 cmp ax,0ff8h ; 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 ; ax = ClusterNumber * 2\r
152 add ax,cx ; ax = ClusterNumber * 2 + ClusterNumber = ClusterNumber * 3\r
153 shr ax,1 ; FatOffset = ClusterNumber*3 / 2\r
154 push si ; Save si\r
155 mov si,ax ; si = FatOffset\r
156 shr ax,BLOCK_SHIFT ; ax = FatOffset >> BLOCK_SHIFT\r
157 add ax,word ptr [bp+ReservedSectors] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)\r
158 and si,BLOCK_MASK ; si = FatOffset & BLOCK_MASK\r
159 cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber\r
160 je SkipFatRead\r
161 mov bx,2 \r
162 push es\r
163 push ds\r
164 pop es\r
165 call ReadBlocks ; Read 2 blocks starting at AX storing at ES:DI\r
166 pop es\r
167 mov dx,ax ; CachedFatSectorNumber = FatSectorNumber\r
168SkipFatRead:\r
169 mov bx,word ptr [si] ; bx = NextClusterNumber\r
170 mov ax,cx ; ax = ClusterNumber\r
171 and ax,1 ; See if this is an odd cluster number\r
172 je EvenFatEntry\r
173 shr bx,4 ; NextClusterNumber = NextClusterNumber >> 4\r
174EvenFatEntry:\r
175 and bx,0fffh ; Strip upper 4 bits of NextClusterNumber\r
176 pop si ; Restore si\r
177 dec bx ; bx = NextClusterNumber - 1\r
178 cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber\r
179 jne ReadClusters\r
180 inc bx ; bx = NextClusterNumber\r
181 inc si ; NumberOfClusters++\r
182 mov cx,bx ; ClusterNumber = NextClusterNumber\r
183 jmp FatChainLoop\r
184ReadClusters:\r
185 inc bx\r
186 pop ax ; ax = StartCluster\r
187 push bx ; StartCluster = NextClusterNumber\r
188 mov cx,bx ; ClusterNumber = NextClusterNumber\r
189 sub ax,2 ; ax = StartCluster - 2\r
190 xor bh,bh \r
191 mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster\r
192 mul bx ; ax = (StartCluster - 2) * SectorsPerCluster\r
193 add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster\r
194 push ax ; save start sector\r
195 mov ax,si ; ax = NumberOfClusters\r
196 mul bx ; ax = NumberOfClusters * SectorsPerCluster\r
197 mov bx,ax ; bx = Number of Sectors\r
198 pop ax ; ax = Start Sector\r
199 call ReadBlocks\r
200 mov si,1 ; NumberOfClusters = 1\r
201 jmp FatChainLoop\r
202FoundLastCluster:\r
203 pop cx\r
204 popa\r
205 ret\r
206\r
207\r
208; ****************************************************************************\r
209; ReadBlocks - Reads a set of blocks from a block device\r
210;\r
211; AX = Start LBA\r
212; BX = Number of Blocks to Read\r
213; ES:DI = Buffer to store sectors read from disk\r
214; ****************************************************************************\r
215\r
216; cx = Blocks\r
217; bx = NumberOfBlocks\r
218; si = StartLBA\r
219\r
220ReadBlocks:\r
221 pusha\r
222 add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA\r
223 add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA\r
224 mov esi,eax ; esi = Start LBA\r
225 mov cx,bx ; cx = Number of blocks to read\r
226ReadCylinderLoop:\r
227 mov bp,07bfch ; bp = 0x7bfc\r
228 mov eax,esi ; eax = Start LBA\r
229 xor edx,edx ; edx = 0\r
230 movzx ebx,word ptr [bp] ; bx = MaxSector\r
231 div ebx ; ax = StartLBA / MaxSector\r
232 inc dx ; dx = (StartLBA % MaxSector) + 1\r
233\r
234 mov bx,word ptr [bp] ; bx = MaxSector\r
235 sub bx,dx ; bx = MaxSector - Sector\r
236 inc bx ; bx = MaxSector - Sector + 1\r
237 cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)\r
238 jg LimitTransfer\r
239 mov bx,cx ; bx = Blocks\r
240LimitTransfer:\r
241 push ax ; save ax\r
242 mov ax,es ; ax = es\r
243 shr ax,(BLOCK_SHIFT-4) ; ax = Number of blocks into mem system\r
244 and ax,07fh ; ax = Number of blocks into current seg\r
245 add ax,bx ; ax = End Block number of transfer\r
246 cmp ax,080h ; See if it crosses a 64K boundry\r
247 jle NotCrossing64KBoundry ; Branch if not crossing 64K boundry\r
248 sub ax,080h ; ax = Number of blocks past 64K boundry\r
249 sub bx,ax ; Decrease transfer size by block overage\r
250NotCrossing64KBoundry:\r
251 pop ax ; restore ax\r
252\r
253 push cx\r
254 mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector\r
255 xor dx,dx ; dx = 0\r
256 div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder \r
257 ; dx = ax % (MaxHead + 1) = Head\r
258\r
259 push bx ; Save number of blocks to transfer\r
260 mov dh,dl ; dh = Head\r
261 mov bp,07c00h ; bp = 0x7c00\r
262 mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number\r
263 mov ch,al ; ch = Cylinder\r
264 mov al,bl ; al = Blocks\r
265 mov ah,2 ; ah = Function 2\r
266 mov bx,di ; es:bx = Buffer address\r
267 int 013h\r
268 jc DiskError\r
269 pop bx\r
270 pop cx\r
271 movzx ebx,bx\r
272 add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks\r
273 sub cx,bx ; Blocks = Blocks - NumberOfBlocks\r
274 mov ax,es\r
275 shl bx,(BLOCK_SHIFT-4)\r
276 add ax,bx\r
277 mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE\r
278 cmp cx,0\r
279 jne ReadCylinderLoop\r
280 popa\r
281 ret\r
282\r
283DiskError:\r
284 push cs\r
285 pop ds\r
286 lea si, [ErrorString]\r
287 mov cx, 7\r
288 jmp PrintStringAndHalt\r
289\r
290PrintStringAndHalt:\r
291 mov ax,0b800h\r
292 mov es,ax\r
293 mov di,160\r
294 rep movsw\r
295Halt:\r
296 jmp Halt\r
297\r
298ErrorString:\r
299 db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch\r
300\r
301 org 01fah\r
302LBAOffsetForBootSector:\r
303 dd 0h\r
304\r
305 org 01feh\r
306 dw 0aa55h\r
307\r
308;******************************************************************************\r
309;******************************************************************************\r
310;******************************************************************************\r
311\r
312DELAY_PORT equ 0edh ; Port to use for 1uS delay\r
313KBD_CONTROL_PORT equ 060h ; 8042 control port \r
314KBD_STATUS_PORT equ 064h ; 8042 status port \r
315WRITE_DATA_PORT_CMD equ 0d1h ; 8042 command to write the data port\r
316ENABLE_A20_CMD equ 0dfh ; 8042 command to enable A20\r
317\r
318 org 200h\r
319 jmp start\r
320Em64String:\r
321 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
322\r
323start: \r
324 mov ax,cs\r
325 mov ds,ax\r
326 mov es,ax\r
327 mov ss,ax\r
328 mov sp,MyStack\r
329\r
330; mov ax,0b800h\r
331; mov es,ax\r
332; mov byte ptr es:[160],'a'\r
333; mov ax,cs\r
334; mov es,ax\r
335\r
336 mov ebx,0\r
337 lea edi,MemoryMap\r
338MemMapLoop:\r
339 mov eax,0e820h\r
340 mov ecx,20\r
341 mov edx,'SMAP'\r
342 int 15h\r
343 jc MemMapDone\r
344 add edi,20\r
345 cmp ebx,0\r
346 je MemMapDone\r
347 jmp MemMapLoop\r
348MemMapDone:\r
349 lea eax,MemoryMap\r
350 sub edi,eax ; Get the address of the memory map\r
351 mov dword ptr [MemoryMapSize],edi ; Save the size of the memory map\r
352\r
353 xor ebx,ebx\r
354 mov bx,cs ; BX=segment\r
355 shl ebx,4 ; BX="linear" address of segment base\r
356 lea eax,[GDT_BASE + ebx] ; EAX=PHYSICAL address of gdt\r
357 mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr\r
358 lea eax,[IDT_BASE + ebx] ; EAX=PHYSICAL address of idt\r
359 mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr\r
360 lea edx,[MemoryMapSize + ebx] ; Physical base address of the memory map\r
361\r
362 add ebx,01000h ; Source of EFI32\r
363 mov dword ptr [JUMP+2],ebx\r
364 add ebx,01000h\r
365 mov esi,ebx ; Source of EFILDR32\r
366\r
367; mov ax,0b800h\r
368; mov es,ax\r
369; mov byte ptr es:[162],'b'\r
370; mov ax,cs\r
371; mov es,ax\r
372\r
373;\r
374; Enable A20 Gate \r
375;\r
376\r
377 mov ax,2401h ; Enable A20 Gate\r
378 int 15h\r
379 jnc A20GateEnabled ; Jump if it suceeded\r
380\r
381;\r
382; If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually.\r
383;\r
384\r
385 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller\r
386 jnz Timeout8042 ; Jump if the 8042 timed out\r
387 out DELAY_PORT,ax ; Delay 1 uS\r
388 mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port\r
389 out KBD_STATUS_PORT,al ; Send command to the 8042\r
390 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller\r
391 jnz Timeout8042 ; Jump if the 8042 timed out\r
392 mov al,ENABLE_A20_CMD ; gate address bit 20 on\r
393 out KBD_CONTROL_PORT,al ; Send command to thre 8042\r
394 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller\r
395 mov cx,25 ; Delay 25 uS for the command to complete on the 8042\r
396Delay25uS:\r
397 out DELAY_PORT,ax ; Delay 1 uS\r
398 loop Delay25uS \r
399Timeout8042:\r
400\r
401\r
402A20GateEnabled:\r
403\r
404;\r
405; DISABLE INTERRUPTS - Entering Protected Mode\r
406;\r
407\r
408 cli \r
409\r
410; mov ax,0b800h\r
411; mov es,ax\r
412; mov byte ptr es:[164],'c'\r
413; mov ax,cs\r
414; mov es,ax\r
415\r
416 db 66h \r
417 lgdt fword ptr [gdtr]\r
418 db 66h \r
419 lidt fword ptr [idtr]\r
420\r
421 mov eax,cr0\r
422 or al,1\r
423 mov cr0,eax\r
424\r
425 mov eax,0008h ; Flat data descriptor\r
426 mov ebp,000400000h ; Destination of EFILDR32\r
427 mov ebx,000070000h ; Length of copy\r
428 \r
429JUMP:\r
430; jmp far 0010:00020000\r
431 db 066h\r
432 db 0eah\r
433 dd 000020000h\r
434 dw 00010h\r
435\r
436Empty8042InputBuffer:\r
437 mov cx,0\r
438Empty8042Loop:\r
439 out DELAY_PORT,ax ; Delay 1us\r
440 in al,KBD_STATUS_PORT ; Read the 8042 Status Port\r
441 and al,02h ; Check the Input Buffer Full Flag\r
442 loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS\r
443 ret\r
444\r
445;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
446; data\r
447;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
448\r
449 align 02h\r
450\r
451gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit\r
452 dd 0 ; (GDT base gets set above)\r
453;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
454; global descriptor table (GDT)\r
455;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
456\r
457 align 02h\r
458\r
459public GDT_BASE\r
460GDT_BASE:\r
461; null descriptor\r
462NULL_SEL equ $-GDT_BASE\r
463 dw 0 ; limit 15:0\r
464 dw 0 ; base 15:0\r
465 db 0 ; base 23:16\r
466 db 0 ; type\r
467 db 0 ; limit 19:16, flags\r
468 db 0 ; base 31:24\r
469\r
470; linear data segment descriptor\r
471LINEAR_SEL equ $-GDT_BASE\r
472 dw 0FFFFh ; limit 0xFFFFF\r
473 dw 0 ; base 0\r
474 db 0\r
475 db 092h ; present, ring 0, data, expand-up, writable\r
476 db 0CFh ; page-granular, 32-bit\r
477 db 0\r
478\r
479; linear code segment descriptor\r
480LINEAR_CODE_SEL equ $-GDT_BASE\r
481 dw 0FFFFh ; limit 0xFFFFF\r
482 dw 0 ; base 0\r
483 db 0\r
484 db 09Ah ; present, ring 0, data, expand-up, writable\r
485 db 0CFh ; page-granular, 32-bit\r
486 db 0\r
487\r
488; system data segment descriptor\r
489SYS_DATA_SEL equ $-GDT_BASE\r
490 dw 0FFFFh ; limit 0xFFFFF\r
491 dw 0 ; base 0\r
492 db 0\r
493 db 092h ; present, ring 0, data, expand-up, writable\r
494 db 0CFh ; page-granular, 32-bit\r
495 db 0\r
496\r
497; system code segment descriptor\r
498SYS_CODE_SEL equ $-GDT_BASE\r
499 dw 0FFFFh ; limit 0xFFFFF\r
500 dw 0 ; base 0\r
501 db 0\r
502 db 09Ah ; present, ring 0, data, expand-up, writable\r
503 db 0CFh ; page-granular, 32-bit\r
504 db 0\r
505\r
506; spare segment descriptor\r
507SPARE3_SEL equ $-GDT_BASE\r
508 dw 0 ; limit 0xFFFFF\r
509 dw 0 ; base 0\r
510 db 0\r
511 db 0 ; present, ring 0, data, expand-up, writable\r
512 db 0 ; page-granular, 32-bit\r
513 db 0\r
514\r
515; spare segment descriptor\r
516SPARE4_SEL equ $-GDT_BASE\r
517 dw 0 ; limit 0xFFFFF\r
518 dw 0 ; base 0\r
519 db 0\r
520 db 0 ; present, ring 0, data, expand-up, writable\r
521 db 0 ; page-granular, 32-bit\r
522 db 0\r
523\r
524; spare segment descriptor\r
525SPARE5_SEL equ $-GDT_BASE\r
526 dw 0 ; limit 0xFFFFF\r
527 dw 0 ; base 0\r
528 db 0\r
529 db 0 ; present, ring 0, data, expand-up, writable\r
530 db 0 ; page-granular, 32-bit\r
531 db 0\r
532\r
533GDT_END:\r
534\r
535 align 02h\r
536\r
537\r
538\r
539idtr dw IDT_END - IDT_BASE - 1 ; IDT limit\r
540 dd 0 ; (IDT base gets set above)\r
541;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
542; interrupt descriptor table (IDT)\r
543;\r
544; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ\r
545; mappings. This implementation only uses the system timer and all other\r
546; IRQs will remain masked. The descriptors for vectors 33+ are provided\r
547; for convenience.\r
548;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
549\r
550;idt_tag db "IDT",0 \r
551 align 02h\r
552\r
553public IDT_BASE\r
554IDT_BASE:\r
555; divide by zero (INT 0)\r
556DIV_ZERO_SEL equ $-IDT_BASE\r
557 dw 0 ; offset 15:0\r
558 dw SYS_CODE_SEL ; selector 15:0\r
559 db 0 ; 0 for interrupt gate\r
560 db 0eh OR 80h ; type = 386 interrupt gate, present\r
561 dw 0 ; offset 31:16\r
562\r
563; debug exception (INT 1)\r
564DEBUG_EXCEPT_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; NMI (INT 2)\r
572NMI_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; soft breakpoint (INT 3)\r
580BREAKPOINT_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; overflow (INT 4)\r
588OVERFLOW_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; bounds check (INT 5)\r
596BOUNDS_CHECK_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; invalid opcode (INT 6)\r
604INVALID_OPCODE_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; device not available (INT 7)\r
612DEV_NOT_AVAIL_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; double fault (INT 8)\r
620DOUBLE_FAULT_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; Coprocessor segment overrun - reserved (INT 9)\r
628RSVD_INTR_SEL1 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; invalid TSS (INT 0ah)\r
636INVALID_TSS_SEL 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; segment not present (INT 0bh)\r
644SEG_NOT_PRESENT_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; stack fault (INT 0ch)\r
652STACK_FAULT_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; general protection (INT 0dh)\r
660GP_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; page fault (INT 0eh)\r
668PAGE_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; Intel reserved - do not use (INT 0fh)\r
676RSVD_INTR_SEL2 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; floating point error (INT 10h)\r
684FLT_POINT_ERR_SEL 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; alignment check (INT 11h)\r
692ALIGNMENT_CHECK_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 ; (10001110)type = 386 interrupt gate, present\r
697 dw 0 ; offset 31:16\r
698\r
699; machine check (INT 12h)\r
700MACHINE_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; SIMD floating-point exception (INT 13h)\r
708SIMD_EXCEPTION_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; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail\r
716 db (85 * 8) dup(0)\r
717 \r
718; IRQ 0 (System timer) - (INT 68h)\r
719IRQ0_SEL equ $-IDT_BASE\r
720 dw 0 ; offset 15:0\r
721 dw SYS_CODE_SEL ; selector 15:0\r
722 db 0 ; 0 for interrupt gate\r
723 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
724 dw 0 ; offset 31:16\r
725\r
726; IRQ 1 (8042 Keyboard controller) - (INT 69h)\r
727IRQ1_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; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)\r
735IRQ2_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; IRQ 3 (COM 2) - (INT 6bh)\r
743IRQ3_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 4 (COM 1) - (INT 6ch)\r
751IRQ4_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 5 (LPT 2) - (INT 6dh)\r
759IRQ5_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 6 (Floppy controller) - (INT 6eh)\r
767IRQ6_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 7 (LPT 1) - (INT 6fh)\r
775IRQ7_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 8 (RTC Alarm) - (INT 70h)\r
783IRQ8_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 9 - (INT 71h)\r
791IRQ9_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 10 - (INT 72h)\r
799IRQ10_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 11 - (INT 73h)\r
807IRQ11_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 12 (PS/2 mouse) - (INT 74h)\r
815IRQ12_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 13 (Floating point error) - (INT 75h)\r
823IRQ13_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 14 (Secondary IDE) - (INT 76h)\r
831IRQ14_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 15 (Primary IDE) - (INT 77h)\r
839IRQ15_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
846IDT_END:\r
847\r
848 align 02h\r
849\r
850MemoryMapSize dd 0\r
851MemoryMap 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 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\r
882 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
883 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
884\r
885 org 0fe0h\r
886MyStack: \r
887 ; below is the pieces of the IVT that is used to redirect INT 68h - 6fh\r
888 ; back to INT 08h - 0fh when in real mode... It is 'org'ed to a\r
889 ; known low address (20f00) so it can be set up by PlMapIrqToVect in\r
890 ; 8259.c\r
891 \r
892 int 8\r
893 iret\r
894 \r
895 int 9\r
896 iret\r
897 \r
898 int 10\r
899 iret\r
900 \r
901 int 11\r
902 iret\r
903 \r
904 int 12\r
905 iret\r
906 \r
907 int 13\r
908 iret\r
909 \r
910 int 14\r
911 iret\r
912 \r
913 int 15\r
914 iret\r
915 \r
916 \r
917 org 0ffeh\r
918BlockSignature:\r
919 dw 0aa55h\r
920\r
921 end \r