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