File indexing completed on 2025-05-11 08:24:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <gdt.h>
0038 #include <smp.h>
0039 #include <rtems/asm.h>
0040 #include <rtems/score/percpu.h>
0041
0042 .set PM_GDT_CODE_OFFSET, 0x08 # Offset of code segment descriptor into GDT
0043 .set PM_GDT_DATA_OFFSET, 0x10 # Offset of data segment descriptor into GDT
0044 .set CR0_PE, 1 # Protected mode flag on CR0 register
0045 .set CR0_PG, 0x80000000 # Paging flag on CR0 register
0046 .set CR0_EM_BITMASK, (~0x4) # Bitmask for disabling x87 FPU Emulation bit
0047 .set CR0_MP, 0x2 # Monitor co-processor flag
0048 .set CR4_PAE, 0x20 # Physical Address Extension flag on CR4 register
0049 .set CR4_OSFXSR, 0x200 # OS support for FXSAVE and FXRSTOR flag
0050 .set CR4_OSXMMEXCPT, 0x400 # OS support for unmasked SIMD FP exceptions flag
0051 .set CR4_SSEFLAGS, (CR4_OSFXSR | CR4_OSXMMEXCPT)
0052 .set EFER_MSR, 0xC0000080 # EFER MSR number
0053 .set EFER_MSR_LME, 0x100 # Long Mode Enable flag on the EFER MSR
0054
0055 BEGIN_CODE
0056
0057 .code16
0058 PUBLIC(_Trampoline_start)
0059 SYM(_Trampoline_start):
0060 cli
0061 cld
0062 jmp .real_mode
0063
0064 .real_mode:
0065 lgdt (gdt_desc - _Trampoline_start) + TRAMPOLINE_ADDR
0066
0067 # Enter protected mode
0068 movl %cr0, %eax
0069 orl $CR0_PE, %eax
0070 movl %eax, %cr0
0071
0072 # Jump to protected mode
0073 ljmpl $PM_GDT_CODE_OFFSET, $((.protected_mode - _Trampoline_start) + TRAMPOLINE_ADDR)
0074
0075 .code32
0076 .protected_mode:
0077 # Load data segment registers
0078 movw $PM_GDT_DATA_OFFSET, %ax
0079 movw %ax, %ds
0080 movw %ax, %es
0081 movw %ax, %ss
0082
0083 # Move PML4 table address to cr3
0084 movl $amd64_pml4, %eax
0085 movl %eax, %cr3
0086
0087 # Flip PAE bit in cr4
0088 movl %cr4, %eax
0089 orl $CR4_PAE, %eax
0090 movl %eax, %cr4
0091
0092 # Set LME on the EFER MSR
0093 movl $EFER_MSR, %ecx
0094 rdmsr
0095 orl $EFER_MSR_LME, %eax
0096 wrmsr
0097
0098 # Enable paging
0099 movl %cr0, %eax
0100 orl $CR0_PG, %eax
0101 movl %eax, %cr0
0102
0103 # Update GDT for long mode
0104 lgdt amd64_gdt_descriptor
0105
0106 # Jump to long mode
0107 ljmp $GDT_CODE_SEG_OFFSET, $((.long_mode - _Trampoline_start) + TRAMPOLINE_ADDR)
0108
0109 .code64
0110 .long_mode:
0111 # Load data segment registers
0112 movw $GDT_DATA_SEG_OFFSET, %ax
0113 movw %ax, %ds
0114 movw %ax, %es
0115 movw %ax, %ss
0116 movw %ax, %fs
0117
0118 # Acquire the processor's stack
0119 GET_SELF_CPU_CONTROL_RAX
0120 movq PER_CPU_INTERRUPT_STACK_HIGH(rax), rsp
0121
0122 # Enable SSE
0123 movq %cr0, rax
0124 andq $CR0_EM_BITMASK, rax
0125 orq $CR0_MP, rax
0126 movq rax, %cr0
0127 movq %cr4, rax
0128 orq $CR4_SSEFLAGS, rax
0129 movq rax, %cr4
0130
0131 # Exit trampoline code
0132 movabsq $smp_init_ap, rax
0133 call *rax
0134
0135
0136 gdt:
0137
0138 .quad 0
0139
0140 .word 0xFFFF, 0
0141 .byte 0, 0x9F, 0xCF, 0
0142
0143 .word 0xFFFF, 0
0144 .byte 0, 0x92, 0xCF, 0
0145 gdt_desc:
0146 .word (gdt_desc - gdt) - 1
0147 .long (gdt - _Trampoline_start) + TRAMPOLINE_ADDR
0148
0149 trampoline_end:
0150 PUBLIC(_Trampoline_size)
0151 SYM(_Trampoline_size):
0152 .quad (trampoline_end - _Trampoline_start)