Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset e3e4a2c in mainline for kernel/arch/ia32/src/boot/boot.S


Ignore:
Timestamp:
2011-08-19T20:21:40Z (10 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
a0fc4be
Parents:
58cbf8d5
Message:

resurrect the original PSE page mapping code and use it if PSE is available
(otherwise use the non-PSE variant as a last resort)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia32/src/boot/boot.S

    r58cbf8d5 re3e4a2c  
    9999#include "vesa_prot.inc"
    100100       
    101         /* Map kernel and turn paging on */
    102         call map_kernel
     101#ifndef PROCESSOR_i486
     102       
     103        pm_status $status_prot2
     104       
     105        movl $(INTEL_CPUID_LEVEL), %eax
     106        cpuid
     107        cmp $0x0, %eax  /* any function > 0? */
     108        jbe pse_unsupported
     109       
     110        movl $(INTEL_CPUID_STANDARD), %eax
     111        cpuid
     112        bt $(INTEL_PSE), %edx
     113        jnc pse_unsupported
     114               
     115                /* Map kernel and turn paging on */
     116                pm_status $status_pse
     117                call map_kernel_pse
     118                jmp stack_init
     119       
     120#endif /* PROCESSOR_i486 */
     121       
     122        pse_unsupported:
     123               
     124                /* Map kernel and turn paging on */
     125                pm_status $status_non_pse
     126                call map_kernel
     127       
     128        stack_init:
    103129       
    104130        /* Create the first stack frame */
     
    106132        movl %esp, %ebp
    107133       
    108         pm2_status $status_prot2
     134        pm2_status $status_prot3
    109135       
    110136        /* Call arch_pre_main(grub_eax, grub_ebx) */
     
    124150                jmp hlt0
    125151
    126 /** Calculate unmapped address of the end of the kernel. */
    127 calc_end_of_kernel:
    128         movl $hardcoded_load_address, %edi
    129         andl $0x7fffffff, %edi
    130         movl (%edi), %esi
    131         andl $0x7fffffff, %esi
    132        
    133         movl $hardcoded_ktext_size, %edi
    134         andl $0x7fffffff, %edi
    135         addl (%edi), %esi
    136         andl $0x7fffffff, %esi
    137        
    138         movl $hardcoded_kdata_size, %edi
    139         andl $0x7fffffff, %edi
    140         addl (%edi), %esi
    141         andl $0x7fffffff, %esi
    142         movl %esi, end_of_kernel
     152/** Setup mapping for the kernel (PSE variant)
     153 *
     154 * Setup mapping for both the unmapped and mapped sections
     155 * of the kernel. For simplicity, we map the entire 4G space.
     156 *
     157 */
     158.global map_kernel_pse
     159map_kernel_pse:
     160        /* Paging features */
     161        movl %cr4, %ecx
     162        orl $(1 << 4), %ecx      /* PSE on */
     163        andl $(~(1 << 5)), %ecx  /* PAE off */
     164        movl %ecx, %cr4
     165       
     166        movl $(page_directory + 0), %esi
     167        movl $(page_directory + 2048), %edi
     168        xorl %ecx, %ecx
     169        xorl %ebx, %ebx
     170       
     171        floop_pse:
     172                movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
     173                orl %ebx, %eax
     174                /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
     175                movl %eax, (%esi, %ecx, 4)
     176                /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
     177                movl %eax, (%edi, %ecx, 4)
     178                addl $(4 * 1024 * 1024), %ebx
     179               
     180                incl %ecx
     181                cmpl $512, %ecx
     182                jl floop_pse
     183       
     184        movl %esi, %cr3
     185       
     186        movl %cr0, %ebx
     187        orl $(1 << 31), %ebx  /* paging on */
     188        movl %ebx, %cr0
    143189        ret
    144190
    145 /** Find free 2M (+4k for alignment) region where to store page tables */
    146 find_mem_for_pt:
    147         /* Check if multiboot info is present */
    148         cmpl $0x2BADB002, grub_eax
    149         je check_multiboot_map
    150         ret
    151 check_multiboot_map:
    152         /* Copy address of the multiboot info to ebx */
    153         movl grub_ebx, %ebx
    154         /* Check if memory map flag is present */
    155         movl (%ebx), %edx
    156         andl $(1 << 6), %edx
    157         jnz use_multiboot_map
    158         ret
    159 use_multiboot_map:
    160         /* Copy address of the memory map to edx */
    161         movl 48(%ebx), %edx
    162         movl %edx, %ecx
    163         addl 44(%ebx), %ecx
    164         /* Find a free region at least 2M in size */
    165         check_memmap_loop:
    166                 /* Is this a free region? */
    167                 cmp $1, 20(%edx)
    168                 jnz next_region
    169                 /* Check size */
    170                 cmp $0, 16(%edx)
    171                 jnz next_region
    172                 cmpl $(2 * 1024 * 1024 + 4 * 1024), 12(%edx)
    173                 jbe next_region
    174                 cmp $0, 8(%edx)
    175                 jz found_region
    176         next_region:
    177                 cmp %ecx, %edx
    178                 jbe next_region_do
    179                 ret
    180         next_region_do:
    181                 addl (%edx), %edx
    182                 addl $4, %edx
    183                 jmp check_memmap_loop
    184         found_region:
    185                 /* Use end of the found region */
    186                 mov 4(%edx), %ecx
    187                 add 12(%edx), %ecx
    188                 sub $(2 * 1024 * 1024), %ecx
    189                 mov %ecx, free_area
    190         ret
    191                
    192 
    193 /** Setup mapping for the kernel.
     191/** Setup mapping for the kernel (non-PSE variant).
    194192 *
    195193 * Setup mapping for both the unmapped and mapped sections
     
    204202        movl %ecx, %cr4
    205203       
    206         call calc_end_of_kernel
     204        call calc_kernel_end
    207205        call find_mem_for_pt
    208         mov end_of_kernel, %esi
     206       
     207        mov kernel_end, %esi
    209208        mov free_area, %ecx
     209       
    210210        cmpl %esi, %ecx
    211         jbe use_end_of_kernel
    212         mov %ecx, %esi
    213         /* Align address down to 4k */
    214         andl $(~4095), %esi
    215 use_end_of_kernel:
    216        
    217         /* Align address to 4k */
    218         addl $4095, %esi
    219         andl $(~4095), %esi
    220        
    221         /* Allocate space for page tables*/     
    222         movl %esi, pt_loc
    223         movl $ballocs, %edi
     211        jbe use_kernel_end
     212               
     213                mov %ecx, %esi
     214               
     215                /* Align address down to 4k */
     216                andl $(~4095), %esi
     217               
     218        use_kernel_end:
     219               
     220                /* Align address to 4k */
     221                addl $4095, %esi
     222                andl $(~4095), %esi
     223               
     224                /* Allocate space for page tables */
     225                movl %esi, pt_loc
     226                movl $ballocs, %edi
     227                andl $0x7fffffff, %edi
     228               
     229                movl %esi, (%edi)
     230                addl $4, %edi
     231                movl $(2 * 1024 * 1024), (%edi)
     232               
     233                /* Fill page tables */
     234                xorl %ecx, %ecx
     235                xorl %ebx, %ebx
     236               
     237                floop_pt:
     238                        movl $((1 << 1) | (1 << 0)), %eax
     239                        orl %ebx, %eax
     240                        movl %eax, (%esi, %ecx, 4)
     241                        addl $(4 * 1024), %ebx
     242                       
     243                        incl %ecx
     244                        cmpl $(512 * 1024), %ecx
     245                       
     246                        jl floop_pt
     247               
     248                /* Fill page directory */
     249                movl $(page_directory + 0), %esi
     250                movl $(page_directory + 2048), %edi
     251                xorl %ecx, %ecx
     252                movl pt_loc, %ebx
     253               
     254                floop:
     255                        movl $((1 << 1) | (1 << 0)), %eax
     256                        orl %ebx, %eax
     257                       
     258                        /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
     259                        movl %eax, (%esi, %ecx, 4)
     260                       
     261                        /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
     262                        movl %eax, (%edi, %ecx, 4)
     263                        addl $(4 * 1024), %ebx
     264                       
     265                        incl %ecx
     266                        cmpl $512, %ecx
     267                       
     268                        jl floop
     269               
     270                movl %esi, %cr3
     271               
     272                movl %cr0, %ebx
     273                orl $(1 << 31), %ebx  /* paging on */
     274                movl %ebx, %cr0
     275               
     276                ret
     277
     278/** Calculate unmapped address of the end of the kernel. */
     279calc_kernel_end:
     280        movl $hardcoded_load_address, %edi
    224281        andl $0x7fffffff, %edi
    225         movl %esi, (%edi)
    226         addl $4, %edi
    227         movl $(2*1024*1024), (%edi)
    228        
    229         /* Fill page tables */
    230         xorl %ecx, %ecx
    231         xorl %ebx, %ebx
    232        
    233         floop_pt:
    234                 movl $((1 << 1) | (1 << 0)), %eax
    235                 orl %ebx, %eax
    236                 movl %eax, (%esi, %ecx, 4)
    237                 addl $(4 * 1024), %ebx
    238                
    239                 incl %ecx
    240                 cmpl $(512 * 1024), %ecx
    241                 jl floop_pt
    242        
    243         /* Fill page directory */
    244         movl $(page_directory + 0), %esi
    245         movl $(page_directory + 2048), %edi
    246         xorl %ecx, %ecx
    247         movl pt_loc, %ebx
    248        
    249         floop:
    250                 movl $((1 << 1) | (1 << 0)), %eax
    251                 orl %ebx, %eax
    252                 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
    253                 movl %eax, (%esi, %ecx, 4)
    254                 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
    255                 movl %eax, (%edi, %ecx, 4)
    256                 addl $(4 * 1024), %ebx
    257                
    258                 incl %ecx
    259                 cmpl $512, %ecx
    260                 jl floop
    261        
    262         movl %esi, %cr3
    263        
    264         movl %cr0, %ebx
    265         orl $(1 << 31), %ebx  /* paging on */
    266         movl %ebx, %cr0
     282        movl (%edi), %esi
     283        andl $0x7fffffff, %esi
     284       
     285        movl $hardcoded_ktext_size, %edi
     286        andl $0x7fffffff, %edi
     287        addl (%edi), %esi
     288        andl $0x7fffffff, %esi
     289       
     290        movl $hardcoded_kdata_size, %edi
     291        andl $0x7fffffff, %edi
     292        addl (%edi), %esi
     293        andl $0x7fffffff, %esi
     294        movl %esi, kernel_end
     295       
    267296        ret
     297
     298/** Find free 2M (+4k for alignment) region where to store page tables */
     299find_mem_for_pt:
     300        /* Check if multiboot info is present */
     301        cmpl $MULTIBOOT_LOADER_MAGIC, grub_eax
     302        je check_multiboot_map
     303               
     304                ret
     305       
     306        check_multiboot_map:
     307               
     308                /* Copy address of the multiboot info to ebx */
     309                movl grub_ebx, %ebx
     310               
     311                /* Check if memory map flag is present */
     312                movl (%ebx), %edx
     313                andl $(1 << 6), %edx
     314                jnz use_multiboot_map
     315                       
     316                        ret
     317               
     318        use_multiboot_map:
     319               
     320                /* Copy address of the memory map to edx */
     321                movl 48(%ebx), %edx
     322                movl %edx, %ecx
     323               
     324                addl 44(%ebx), %ecx
     325               
     326                /* Find a free region at least 2M in size */
     327                check_memmap_loop:
     328                       
     329                        /* Is this a free region? */
     330                        cmp $1, 20(%edx)
     331                        jnz next_region
     332                       
     333                        /* Check size */
     334                        cmp $0, 16(%edx)
     335                        jnz next_region
     336                       
     337                        cmpl $(2 * 1024 * 1024 + 4 * 1024), 12(%edx)
     338                        jbe next_region
     339                       
     340                        cmp $0, 8(%edx)
     341                        jz found_region
     342               
     343                next_region:
     344                       
     345                        cmp %ecx, %edx
     346                        jbe next_region_do
     347                       
     348                                ret
     349               
     350                next_region_do:
     351                       
     352                        addl (%edx), %edx
     353                        addl $4, %edx
     354                        jmp check_memmap_loop
     355                       
     356                found_region:
     357                       
     358                        /* Use end of the found region */
     359                        mov 4(%edx), %ecx
     360                        add 12(%edx), %ecx
     361                        sub $(2 * 1024 * 1024), %ecx
     362                        mov %ecx, free_area
     363                       
     364                        ret
    268365
    269366/** Print string to EGA display (in light red) and halt.
     
    610707grub_eax:
    611708        .long 0
    612 
    613709grub_ebx:
    614710        .long 0
     
    616712pt_loc:
    617713        .long 0
    618 end_of_kernel:
     714kernel_end:
    619715        .long 0
    620716free_area:
    621717        .long 0
    622718
    623 err_pse:
    624         .asciz "Page Size Extension not supported. System halted."
    625 
    626719status_prot:
    627720        .asciz "[prot] "
     721status_pse:
     722        .asciz "[pse] "
     723status_non_pse:
     724        .asciz "[non_pse] "
    628725status_vesa_copy:
    629726        .asciz "[vesa_copy] "
     
    634731status_prot2:
    635732        .asciz "[prot2] "
     733status_prot3:
     734        .asciz "[prot3] "
    636735status_main:
    637736        .asciz "[main] "
Note: See TracChangeset for help on using the changeset viewer.