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