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