hc
2024-03-22 a0752693d998599af469473b8dc239ef973a012f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
;------------------------------------------------------------------------------
;
; Copyright (c) 2013-2015 Intel Corporation.
;
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
;
;  Flat32.asm
;
; Abstract:
;
;  This is the code that goes from real-mode to protected mode.
;  It consumes the reset vector, configures the stack.
;
;
;------------------------------------------------------------------------------
 
 
;
; Define assembler characteristics
;
.586p
.model flat, c
 
;
; Include processor definitions
;
 
INCLUDE Platform.inc
 
 
;
; CR0 cache control bit definition
;
CR0_CACHE_DISABLE       EQU 040000000h
CR0_NO_WRITE            EQU 020000000h
 
;
; External and public declarations
;  TopOfStack is used by C code
;  SecStartup is the entry point to the C code
; Neither of these names can be modified without
; updating the C code.
;
EXTRN   PlatformSecLibStartup: NEAR
EXTERNDEF   C   PcdGet32 (PcdEsramStage1Base):DWORD
 
;
; Contrary to the name, this file contains 16 bit code as well.
;
_TEXT_REALMODE      SEGMENT PARA PUBLIC USE16 'CODE'
                    ASSUME  CS:_TEXT_REALMODE, DS:_TEXT_REALMODE
 
;----------------------------------------------------------------------------
;
; Procedure:    _ModuleEntryPoint
;
; Input:        None
;
; Output:       None
;
; Destroys:     Assume all registers
;
; Description:
;
;   Transition to non-paged flat-model protected mode from a
;   hard-coded GDT that provides exactly two descriptors.
;   This is a bare bones transition to protected mode only
;   used for a while in PEI and possibly DXE.
;
;   After enabling protected mode, a far jump is executed to
;   transfer to PEI using the newly loaded GDT.
;
; Return:       None
;
;----------------------------------------------------------------------------
align 16
_ModuleEntryPoint      PROC C PUBLIC
 
  ;
  ; Warm Reset (INIT#) check.
  ;
  mov     si, 0F000h
  mov     ds, si
  mov     si, 0FFF0h
  cmp     BYTE PTR [si], 0EAh   ; Is it warm reset ?
  jne     NotWarmReset          ; JIf not.
 
  mov     al, 08
  mov     dx, 0cf9h
  out     dx, al
  mov     al, 055h
  out     080h, al;
  jmp $
NotWarmReset:
 
  ;
  ; Load the GDT table in GdtDesc
  ;
  mov     esi, OFFSET GdtDesc
  db      66h
  lgdt    fword ptr cs:[si]
 
  ;
  ; Transition to 16 bit protected mode
  ;
  mov     eax, cr0                   ; Get control register 0
  or      eax, 00000003h             ; Set PE bit (bit #0) & MP bit (bit #1)
  mov     cr0, eax                   ; Activate protected mode
 
  ;
  ; Now we're in 16 bit protected mode
  ; Set up the selectors for 32 bit protected mode entry
  ;
  mov     ax, SYS_DATA_SEL
  mov     ds, ax
  mov     es, ax
  mov     fs, ax
  mov     gs, ax
  mov     ss, ax
 
  ;
  ; Transition to Flat 32 bit protected mode
  ; The jump to a far pointer causes the transition to 32 bit mode
  ;
  mov esi, offset ProtectedModeEntryLinearAddress
  jmp     fword ptr cs:[si]
 
_ModuleEntryPoint   ENDP
 
_TEXT_REALMODE      ENDS
 
.code
;
; Protected mode portion initializes stack, configures cache, and calls C entry point
;
 
;----------------------------------------------------------------------------
;
; Procedure:    ProtectedModeEntryPoint
;
; Input:        Executing in 32 Bit Protected (flat) mode
;                cs: 0-4GB
;                ds: 0-4GB
;                es: 0-4GB
;                fs: 0-4GB
;                gs: 0-4GB
;                ss: 0-4GB
;
; Output:       This function never returns
;
; Destroys:
;               ecx
;               edi
;                esi
;                esp
;
; Description:
;                Perform any essential early platform initilaisation
;               Setup a stack
;               Call the main EDKII Sec C code
;
;----------------------------------------------------------------------------
 
ProtectedModeEntryPoint PROC NEAR C PUBLIC
 
  JMP32  stackless_EarlyPlatformInit
 
  ;
  ; Set up stack pointer
  ;
  mov     esp, PcdGet32(PcdEsramStage1Base)
  mov     esi, QUARK_ESRAM_MEM_SIZE_BYTES
  add     esp, esi                         ; ESP = top of stack (stack grows downwards).
 
  ;
  ; Store the the BIST value in EBP
  ;
  mov     ebp, 00h        ; No processor BIST on Quark
 
  ;
  ; Push processor count to stack first, then BIST status (AP then BSP)
  ;
  mov     eax, 1
  cpuid
  shr     ebx, 16
  and     ebx, 0000000FFh
  cmp     bl, 1
  jae     PushProcessorCount
 
  ;
  ; Some processors report 0 logical processors.  Effectively 0 = 1.
  ; So we fix up the processor count
  ;
  inc     ebx
 
PushProcessorCount:
  push    ebx
 
  ;
  ; We need to implement a long-term solution for BIST capture.  For now, we just copy BSP BIST
  ; for all processor threads
  ;
  xor     ecx, ecx
  mov     cl, bl
PushBist:
  push    ebp
  loop    PushBist
 
  ;
  ; Pass Control into the PEI Core
  ;
  call PlatformSecLibStartup
 
  ;
  ; PEI Core should never return to here, this is just to capture an invalid return.
  ;
  jmp     $
 
ProtectedModeEntryPoint ENDP
 
;----------------------------------------------------------------------------
;
; Procedure:    stackless_EarlyPlatformInit
;
; Input:        esp - Return address
;
; Output:       None
;
; Destroys:
;                eax
;                ecx
;                dx
;                ebp
;
; Description:
;        Any essential early platform initialisation required:
;        (1) Disable Cache
;        (2) Disable NMI's/SMI's
;        (3) Setup HMBOUND (defines what memory accesses go to MMIO/RAM)
;        (4) Setup eSRAM (provide early memory to the system)
;        (5) Setup PCIEXBAR access mechanism
;        (6) Open up full SPI flash decode
;
;----------------------------------------------------------------------------
stackless_EarlyPlatformInit  PROC NEAR C PUBLIC
 
  ;
  ; Save return address
  ;
  mov  ebp, esp
 
  ;
  ; Ensure cache is disabled.
  ;
  mov     eax, cr0
  or      eax, CR0_CACHE_DISABLE + CR0_NO_WRITE
  invd
  mov     cr0, eax
 
  ;
  ; Disable NMI
  ; Good convention suggests you should read back RTC data port after
  ; accessing the RTC index port.
  ;
  mov  al, NMI_DISABLE
  mov  dx, RTC_INDEX
  out  dx, al
  mov  dx, RTC_DATA
  in  al, dx
 
  ;
  ; Disable SMI (Disables SMI wire, not SMI messages)
  ;
  mov  ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMISC2_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Read
  and  eax, NOT (SMI_EN)
  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMISC2_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Write
 
  ;
  ; Before we get going, check SOC Unit Registers to see if we are required to issue a warm/cold reset
  ;
  mov  ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGNONSTICKY_W1_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Read
  and  eax, FORCE_WARM_RESET
  jz TestForceColdReset    ; Zero means bit clear, we're not requested to warm reset so continue as normal
  jmp IssueWarmReset
 
TestForceColdReset:
  mov  ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_W1_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Read
  and  eax, FORCE_COLD_RESET
  jz TestHmboundLock    ; Zero means bit clear, we're not requested to cold reset so continue as normal
  jmp IssueColdReset
 
  ;
  ; Before setting HMBOUND, check it's not locked
  ;
TestHmboundLock:
  mov  ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMBOUND_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Read
  and  eax, HMBOUND_LOCK
  jz ConfigHmbound  ; Zero means bit clear, we have the config we want so continue as normal
  ;
  ; Failed to config - store sticky bit debug
  ;
  mov  ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Read
  or  eax, RESET_FOR_HMBOUND_LOCK  ; Set the bit we're interested in
  mov  ecx, (OPCODE_SIDEBAND_ALT_REG_WRITE SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Write
  jmp IssueWarmReset
 
  ;
  ; Set up the HMBOUND register
  ;
ConfigHmbound:
  mov  eax, HMBOUND_ADDRESS    ; Data (Set HMBOUND location)
  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMBOUND_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Write
 
  ;
  ; Enable interrupts to Remote Management Unit when a IMR/SMM/HMBOUND violation occurs.
  ;
  mov  eax, ENABLE_IMR_INTERRUPT        ; Data (Set interrupt enable mask)
  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (BIMRVCTL_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Write
 
  ;
  ; Set eSRAM address
  ;
  mov  eax, PcdGet32 (PcdEsramStage1Base)        ; Data (Set eSRAM location)
  shr  eax, 18h        ; Data (Set eSRAM location)
  add eax, BLOCK_ENABLE_PG
  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (ESRAMPGCTRL_BLOCK_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Write
  ;
  ; Check that we're not blocked from setting the config that we want.
  ;
  mov  ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (ESRAMPGCTRL_BLOCK_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Read
  and  eax, BLOCK_ENABLE_PG
  jnz ConfigPci  ; Non-zero means bit set, we have the config we want so continue as normal
  ;
  ; Failed to config - store sticky bit debug
  ;
  mov  ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Read
  or  eax, RESET_FOR_ESRAM_LOCK  ; Set the bit we're interested in
  mov  ecx, (OPCODE_SIDEBAND_ALT_REG_WRITE SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Write
  jmp IssueWarmReset
 
  ;
  ; Enable PCIEXBAR
  ;
ConfigPci:
  mov  eax, (EC_BASE + EC_ENABLE)      ; Data
  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_ARBITER_PORT_ID SHL SB_PORT_FIELD) OR (AEC_CTRL_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Write
 
  mov  eax, (EC_BASE + EC_ENABLE)      ; Data
  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HECREG_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Write
 
  ;
  ;  Open up full 8MB SPI decode
  ;
  mov  ebx, PCI_CFG OR (ILB_PFA SHL 8) OR BDE  ; PCI Configuration address
  mov eax, DECODE_ALL_REGIONS_ENABLE
  JMP32  stackless_PCIConfig_Write
 
  ;
  ; Enable NMI operation
  ; Good convention suggests you should read back RTC data port after
  ; accessing the RTC index port.
  ;
  mov al, NMI_ENABLE
  mov dx, RTC_INDEX
  out dx, al
  mov dx, RTC_DATA
  in  al, dx
 
  ;
  ; Clear Host Bridge SMI, NMI, INTR fields
  ;
  mov  ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HLEGACY_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Read
  and  eax, NOT(NMI + SMI + INTR)  ; Clear NMI, SMI, INTR fields
  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HLEGACY_OFFSET SHL SB_ADDR_FIELD)
  JMP32  stackless_SideBand_Write
 
  ;
  ; Restore return address
  ;
  mov  esp, ebp
  RET32
 
IssueWarmReset:
  ;
  ; Issue Warm Reset request to Remote Management Unit via iLB
  ;
  mov ax, CF9_WARM_RESET
  mov  dx, ILB_RESET_REG
  out  dx, ax
  jmp  $  ; Stay here until we are reset.
 
IssueColdReset:
  ;
  ; Issue Cold Reset request to Remote Management Unit via iLB
  ;
  mov ax, CF9_COLD_RESET
  mov  dx, ILB_RESET_REG
  out  dx, ax
  jmp  $  ; Stay here until we are reset.
 
stackless_EarlyPlatformInit ENDP
 
;----------------------------------------------------------------------------
;
; Procedure:    stackless_SideBand_Read
;
; Input:        esp - return address
;                ecx[15:8] - Register offset
;                ecx[23:16] - Port ID
;                ecx[31:24] - Opcode
;
; Output:       eax - Data read
;
; Destroys:
;                eax
;                ebx
;                cl
;                esi
;
; Description:
;        Perform requested sideband read
;
;----------------------------------------------------------------------------
stackless_SideBand_Read  PROC NEAR C PUBLIC
 
  mov  esi, esp        ; Save the return address
 
  ;
  ; Load the SideBand Packet Register to generate the transaction
  ;
  mov  ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_BUS_CONTROL_REG  ; PCI Configuration address
  mov  cl, (ALL_BYTE_EN SHL SB_BE_FIELD)    ; Set all Byte Enable bits
  xchg  eax, ecx
  JMP32  stackless_PCIConfig_Write
  xchg  eax, ecx
 
  ;
  ; Read the SideBand Data Register
  ;
  mov  ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_DATA_REG    ; PCI Configuration address
  JMP32  stackless_PCIConfig_Read
 
  mov  esp, esi        ; Restore the return address
  RET32
 
stackless_SideBand_Read ENDP
 
;----------------------------------------------------------------------------
;
; Procedure:    stackless_SideBand_Write
;
; Input:        esp - return address
;                eax - Data
;                ecx[15:8] - Register offset
;                ecx[23:16] - Port ID
;                ecx[31:24] - Opcode
;
; Output:       None
;
; Destroys:
;                ebx
;                cl
;                esi
;
; Description:
;        Perform requested sideband write
;
;
;----------------------------------------------------------------------------
stackless_SideBand_Write  PROC NEAR C PUBLIC
 
  mov  esi, esp        ; Save the return address
 
  ;
  ; Load the SideBand Data Register with the data
  ;
  mov  ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_DATA_REG  ; PCI Configuration address
  JMP32  stackless_PCIConfig_Write
 
  ;
  ; Load the SideBand Packet Register to generate the transaction
  ;
  mov  ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_BUS_CONTROL_REG  ; PCI Configuration address
  mov  cl, (ALL_BYTE_EN SHL SB_BE_FIELD)    ; Set all Byte Enable bits
  xchg  eax, ecx
  JMP32  stackless_PCIConfig_Write
  xchg  eax, ecx
 
  mov  esp, esi        ; Restore the return address
  RET32
 
stackless_SideBand_Write ENDP
 
;----------------------------------------------------------------------------
;
; Procedure:    stackless_PCIConfig_Write
;
; Input:        esp - return address
;                eax - Data to write
;                ebx - PCI Config Address
;
; Output:       None
;
; Destroys:
;                dx
;
; Description:
;        Perform a DWORD PCI Configuration write
;
;----------------------------------------------------------------------------
stackless_PCIConfig_Write  PROC NEAR C PUBLIC
 
  ;
  ; Write the PCI Config Address to the address port
  ;
  xchg  eax, ebx
  mov  dx, PCI_ADDRESS_PORT
  out  dx, eax
  xchg  eax, ebx
 
  ;
  ; Write the PCI DWORD Data to the data port
  ;
  mov  dx, PCI_DATA_PORT
  out  dx, eax
 
  RET32
 
stackless_PCIConfig_Write ENDP
 
;----------------------------------------------------------------------------
;
; Procedure:    stackless_PCIConfig_Read
;
; Input:        esp - return address
;                ebx - PCI Config Address
;
; Output:       eax - Data read
;
; Destroys:
;                eax
;                dx
;
; Description:
;        Perform a DWORD PCI Configuration read
;
;----------------------------------------------------------------------------
stackless_PCIConfig_Read  PROC NEAR C PUBLIC
 
  ;
  ; Write the PCI Config Address to the address port
  ;
  xchg  eax, ebx
  mov  dx, PCI_ADDRESS_PORT
  out  dx, eax
  xchg  eax, ebx
 
  ;
  ; Read the PCI DWORD Data from the data port
  ;
  mov  dx, PCI_DATA_PORT
  in  eax, dx
 
  RET32
 
stackless_PCIConfig_Read ENDP
 
;
; ROM-based Global-Descriptor Table for the Tiano PEI Phase
;
align 16
PUBLIC  BootGdtTable
 
;
; GDT[0]: 0x00: Null entry, never used.
;
NULL_SEL        equ     $ - GDT_BASE        ; Selector [0]
GDT_BASE:
BootGdtTable    DD      0
                DD      0
;
; Linear data segment descriptor
;
LINEAR_SEL      equ     $ - GDT_BASE        ; Selector [0x8]
        DW      0FFFFh                      ; limit 0xFFFF
        DW      0                           ; base 0
        DB      0
        DB      092h                        ; present, ring 0, data, expand-up, writable
        DB      0CFh                        ; page-granular, 32-bit
        DB      0
;
; Linear code segment descriptor
;
LINEAR_CODE_SEL equ     $ - GDT_BASE        ; Selector [0x10]
        DW      0FFFFh                      ; limit 0xFFFF
        DW      0                           ; base 0
        DB      0
        DB      09Bh                        ; present, ring 0, data, expand-up, not-writable
        DB      0CFh                        ; page-granular, 32-bit
        DB      0
;
; System data segment descriptor
;
SYS_DATA_SEL    equ     $ - GDT_BASE        ; Selector [0x18]
        DW      0FFFFh                      ; limit 0xFFFF
        DW      0                           ; base 0
        DB      0
        DB      093h                        ; present, ring 0, data, expand-up, not-writable
        DB      0CFh                        ; page-granular, 32-bit
        DB      0
 
;
; System code segment descriptor
;
SYS_CODE_SEL    equ     $ - GDT_BASE        ; Selector [0x20]
        DW      0FFFFh                      ; limit 0xFFFF
        DW      0                           ; base 0
        DB      0
        DB      09Ah                        ; present, ring 0, data, expand-up, writable
        DB      0CFh                        ; page-granular, 32-bit
        DB      0
;
; Spare segment descriptor
;
SYS16_CODE_SEL  equ     $ - GDT_BASE        ; Selector [0x28]
        DW      0FFFFh                      ; limit 0xFFFF
        DW      0                           ; base 0
        DB      0Fh
        DB      09Bh                        ; present, ring 0, code, expand-up, writable
        DB      00h                         ; byte-granular, 16-bit
        DB      0
;
; Spare segment descriptor
;
SYS16_DATA_SEL  equ     $ - GDT_BASE        ; Selector [0x30]
        DW      0FFFFh                      ; limit 0xFFFF
        DW      0                           ; base 0
        DB      0
        DB      093h                        ; present, ring 0, data, expand-up, not-writable
        DB      00h                         ; byte-granular, 16-bit
        DB      0
 
;
; Spare segment descriptor
;
SPARE5_SEL      equ     $ - GDT_BASE        ; Selector [0x38]
        DW      0                           ; limit 0xFFFF
        DW      0                           ; base 0
        DB      0
        DB      0                           ; present, ring 0, data, expand-up, writable
        DB      0                           ; page-granular, 32-bit
        DB      0
GDT_SIZE        EQU     $ - BootGDTtable    ; Size, in bytes
 
;
; GDT Descriptor
;
GdtDesc:                                    ; GDT descriptor
        DW      GDT_SIZE - 1                ; GDT limit
        DD      OFFSET BootGdtTable         ; GDT base address
 
ProtectedModeEntryLinearAddress   LABEL   FWORD
ProtectedModeEntryLinearOffset    LABEL   DWORD
  DD      OFFSET ProtectedModeEntryPoint  ; Offset of our 32 bit code
  DW      LINEAR_CODE_SEL
 
END