Changes in / [eee047c:90ed058] in mainline


Ignore:
Files:
1 added
18 edited

Legend:

Unmodified
Added
Removed
  • kernel/Makefile

    reee047c r90ed058  
    160160        CFLAGS = $(GCC_CFLAGS)
    161161        DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
     162        INSTRUMENTATION = -finstrument-functions
    162163endif
    163164
     
    165166        CFLAGS = $(GCC_CFLAGS)
    166167        DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
     168        INSTRUMENTATION = -finstrument-functions
    167169endif
    168170
     
    170172        CFLAGS = $(ICC_CFLAGS)
    171173        DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
     174        INSTRUMENTATION =
    172175endif
    173176
     
    176179        DEFS += $(CONFIG_DEFS)
    177180        DEPEND_DEFS = $(DEFS)
     181        INSTRUMENTATION =
    178182endif
    179183
     
    181185        CFLAGS = $(CLANG_CFLAGS)
    182186        DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
     187        INSTRUMENTATION =
    183188endif
    184189
     
    202207        generic/src/debug/stacktrace.c \
    203208        generic/src/debug/panic.c \
     209        generic/src/debug/debug.c \
    204210        generic/src/interrupt/interrupt.c \
    205211        generic/src/main/main.c \
     
    355361endif
    356362
     363## Sources where instrumentation is enabled
     364#
     365
     366ifeq ($(CONFIG_LOG),y)
     367INSTRUMENTED_SOURCES = \
     368        generic/src/cpu/cpu.c \
     369        generic/src/main/kinit.c
     370endif
     371
    357372GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
    358373ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
     
    414429
    415430%.o: %.c $(DEPEND)
    416         $(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) -c -o $@ $<
     431        $(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) $(if $(findstring $<,$(INSTRUMENTED_SOURCES)),$(INSTRUMENTATION)) -c -o $@ $<
    417432ifeq ($(PRECHECK),y)
    418433        $(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS)
  • kernel/arch/amd64/src/boot/boot.S

    reee047c r90ed058  
    1 #
    2 # Copyright (c) 2005 Ondrej Palkovsky
    3 # Copyright (c) 2006 Martin Decky
    4 # Copyright (c) 2008 Jakub Jermar
    5 # All rights reserved.
    6 #
    7 # Redistribution and use in source and binary forms, with or without
    8 # modification, are permitted provided that the following conditions
    9 # are met:
    10 #
    11 # - Redistributions of source code must retain the above copyright
    12 #   notice, this list of conditions and the following disclaimer.
    13 # - Redistributions in binary form must reproduce the above copyright
    14 #   notice, this list of conditions and the following disclaimer in the
    15 #   documentation and/or other materials provided with the distribution.
    16 # - The name of the author may not be used to endorse or promote products
    17 #   derived from this software without specific prior written permission.
    18 #
    19 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    20 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    21 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    22 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    23 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    24 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    28 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    29 #
     1/*
     2 * Copyright (c) 2005 Ondrej Palkovsky
     3 * Copyright (c) 2006 Martin Decky
     4 * Copyright (c) 2008 Jakub Jermar
     5 * All rights reserved.
     6 *
     7 * Redistribution and use in source and binary forms, with or without
     8 * modification, are permitted provided that the following conditions
     9 * are met:
     10 *
     11 * - Redistributions of source code must retain the above copyright
     12 *   notice, this list of conditions and the following disclaimer.
     13 * - Redistributions in binary form must reproduce the above copyright
     14 *   notice, this list of conditions and the following disclaimer in the
     15 *   documentation and/or other materials provided with the distribution.
     16 * - The name of the author may not be used to endorse or promote products
     17 *   derived from this software without specific prior written permission.
     18 *
     19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 */
    3030
    3131#include <arch/boot/boot.h>
     
    3737#include <arch/cpuid.h>
    3838
    39 #define START_STACK     (BOOT_OFFSET - BOOT_STACK_SIZE)
     39#define START_STACK  (BOOT_OFFSET - BOOT_STACK_SIZE)
    4040
    4141.section K_TEXT_START, "ax"
    4242
    4343.code32
     44
     45.macro pm_error msg
     46        movl \msg, %esi
     47        jmp pm_error_halt
     48.endm
     49
     50.macro pm_status msg
     51#ifdef CONFIG_EGA
     52        pushl %esi
     53        movl \msg, %esi
     54        call pm_early_puts
     55        popl %esi
     56#endif
     57.endm
     58
     59.macro pm2_status msg
     60#ifndef CONFIG_FB
     61        pm_status \msg
     62#endif
     63.endm
     64
    4465.align 4
    4566.global multiboot_image_start
     
    4768        .long MULTIBOOT_HEADER_MAGIC
    4869        .long MULTIBOOT_HEADER_FLAGS
    49         .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)  # checksum
     70        .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)  /* checksum */
    5071        .long multiboot_header
    5172        .long unmapped_ktext_start
     
    5677multiboot_image_start:
    5778        cld
    58         movl $START_STACK, %esp             # initialize stack pointer
    59         lgdtl bootstrap_gdtr                # initialize Global Descriptor Table register
    60        
     79       
     80        /* Initialize stack pointer */
     81        movl $START_STACK, %esp
     82       
     83        /* Initialize Global Descriptor Table register */
     84        lgdtl bootstrap_gdtr
     85       
     86        /* Kernel data + stack */
    6187        movw $gdtselector(KDATA_DES), %cx
    6288        movw %cx, %es
    63         movw %cx, %ds                       # kernel data + stack
     89        movw %cx, %ds
    6490        movw %cx, %ss
    6591       
    66         #
    67         # Simics seems to remove hidden part of GS on entering user mode
    68         # when _visible_ part of GS does not point to user-mode segment.
    69         #
    70        
     92        /*
     93         * Simics seems to remove hidden part of GS on entering user mode
     94         * when _visible_ part of GS does not point to user-mode segment.
     95         */
    7196        movw $gdtselector(UDATA_DES), %cx
    7297        movw %cx, %fs
     
    76101        multiboot_meeting_point:
    77102       
    78         movl %eax, grub_eax                 # save parameters from GRUB
     103        /* Save GRUB arguments */
     104        movl %eax, grub_eax
    79105        movl %ebx, grub_ebx
    80106       
    81         #
    82         # Protected 32-bit. We want to reuse the code-seg descriptor,
    83         # the Default operand size must not be 1 when entering long mode.
    84         #
     107        pm_status $status_prot
    85108       
    86109        movl $(INTEL_CPUID_EXTENDED), %eax
     
    89112        ja extended_cpuid_supported
    90113       
    91                 movl $extended_cpuid_msg, %esi
    92                 jmp error_halt
     114                pm_error $err_extended_cpuid
    93115       
    94116        extended_cpuid_supported:
     
    99121        jc long_mode_supported
    100122       
    101                 movl $long_mode_msg, %esi
    102                 jmp error_halt
     123                pm_error $err_long_mode
    103124       
    104125        long_mode_supported:
     
    107128        jc noexecute_supported
    108129       
    109                 movl $noexecute_msg, %esi
    110                 jmp error_halt
     130                pm_error $err_noexecute
    111131       
    112132        noexecute_supported:
     
    117137        jc fx_supported
    118138       
    119                 movl $fx_msg, %esi
    120                 jmp error_halt
     139                pm_error $err_fx
    121140       
    122141        fx_supported:
     
    125144        jc sse2_supported
    126145       
    127                 movl $sse2_msg, %esi
    128                 jmp error_halt
     146                pm_error $err_sse2
    129147       
    130148        sse2_supported:
    131 
     149       
    132150#include "vesa_prot.inc"
    133 
    134         #
    135         # Enable 64-bit page translation entries - CR4.PAE = 1.
    136         # Paging is not enabled until after long mode is enabled.
    137         #
     151       
     152        /*
     153         * Protected 32-bit. We want to reuse the code-seg descriptor,
     154         * the Default operand size must not be 1 when entering long mode.
     155         */
     156       
     157        pm2_status $status_prot2
     158       
     159        /*
     160         * Enable 64-bit page translation entries - CR4.PAE = 1.
     161         * Paging is not enabled until after long mode is enabled.
     162         */
    138163       
    139164        movl %cr4, %eax
     
    141166        movl %eax, %cr4
    142167       
    143         # set up paging tables
    144        
     168        /* Set up paging tables */
    145169        leal ptl_0, %eax
    146170        movl %eax, %cr3
    147171       
    148         # enable long mode
    149        
    150         movl $EFER_MSR_NUM, %ecx            # EFER MSR number
    151         rdmsr                               # read EFER
    152         btsl $AMD_LME_FLAG, %eax            # set LME = 1
    153         wrmsr                               # write EFER
    154        
    155         # enable paging to activate long mode (set CR0.PG = 1)
    156        
     172        /* Enable long mode */
     173        movl $EFER_MSR_NUM, %ecx
     174        rdmsr                     /* read EFER */
     175        btsl $AMD_LME_FLAG, %eax  /* set LME = 1 */
     176        wrmsr
     177       
     178        /* Enable paging to activate long mode (set CR0.PG = 1) */
    157179        movl %cr0, %eax
    158180        btsl $31, %eax
    159181        movl %eax, %cr0
    160182       
    161         # at this point we are in compatibility mode
    162        
     183        /* At this point we are in compatibility mode */
    163184        jmpl $gdtselector(KTEXT_DES), $start64
    164185
     186/** Print string to EGA display (in light red) and halt.
     187 *
     188 * Should be executed from 32 bit protected mode with paging
     189 * turned off. Stack is not required. This routine is used even
     190 * if CONFIG_EGA is not enabled. Since we are going to halt the
     191 * CPU anyway, it is always better to at least try to print
     192 * some hints.
     193 *
     194 * @param %esi NULL-terminated string to print.
     195 *
     196 */
     197pm_error_halt:
     198        movl $0xb8000, %edi  /* base of EGA text mode memory */
     199        xorl %eax, %eax
     200       
     201        /* Read bits 8 - 15 of the cursor address */
     202        movw $0x3d4, %dx
     203        movb $0xe, %al
     204        outb %al, %dx
     205       
     206        movw $0x3d5, %dx
     207        inb %dx, %al
     208        shl $8, %ax
     209       
     210        /* Read bits 0 - 7 of the cursor address */
     211        movw $0x3d4, %dx
     212        movb $0xf, %al
     213        outb %al, %dx
     214       
     215        movw $0x3d5, %dx
     216        inb %dx, %al
     217       
     218        /* Sanity check for the cursor on screen */
     219        cmp $2000, %ax
     220        jb err_cursor_ok
     221       
     222                movw $1998, %ax
     223       
     224        err_cursor_ok:
     225       
     226        movw %ax, %bx
     227        shl $1, %eax
     228        addl %eax, %edi
     229       
     230        err_ploop:
     231                lodsb
     232               
     233                cmp $0, %al
     234                je err_ploop_end
     235               
     236                movb $0x0c, %ah  /* black background, light red foreground */
     237                stosw
     238               
     239                /* Sanity check for the cursor on the last line */
     240                inc %bx
     241                cmp $2000, %bx
     242                jb err_ploop
     243               
     244                /* Scroll the screen (24 rows) */
     245                movl %esi, %edx
     246                movl $0xb80a0, %esi
     247                movl $0xb8000, %edi
     248                movl $1920, %ecx
     249                rep movsw
     250               
     251                /* Clear the 24th row */
     252                xorl %eax, %eax
     253                movl $80, %ecx
     254                rep stosw
     255               
     256                /* Go to row 24 */
     257                movl %edx, %esi
     258                movl $0xb8f00, %edi
     259                movw $1920, %bx
     260               
     261                jmp err_ploop
     262        err_ploop_end:
     263       
     264        /* Write bits 8 - 15 of the cursor address */
     265        movw $0x3d4, %dx
     266        movb $0xe, %al
     267        outb %al, %dx
     268       
     269        movw $0x3d5, %dx
     270        movb %bh, %al
     271        outb %al, %dx
     272       
     273        /* Write bits 0 - 7 of the cursor address */
     274        movw $0x3d4, %dx
     275        movb $0xf, %al
     276        outb %al, %dx
     277       
     278        movw $0x3d5, %dx
     279        movb %bl, %al
     280        outb %al, %dx
     281       
     282        cli
     283        hlt1:
     284                hlt
     285                jmp hlt1
     286
     287/** Print string to EGA display (in light green).
     288 *
     289 * Should be called from 32 bit protected mode with paging
     290 * turned off. A stack space of at least 24 bytes is required,
     291 * but the function does not establish a stack frame.
     292 *
     293 * Macros such as pm_status and pm2_status take care that
     294 * this function is used only when CONFIG_EGA is enabled
     295 * and CONFIG_FB is disabled.
     296 *
     297 * @param %esi NULL-terminated string to print.
     298 *
     299 */
     300pm_early_puts:
     301        pushl %eax
     302        pushl %ebx
     303        pushl %ecx
     304        pushl %edx
     305        pushl %edi
     306       
     307        movl $0xb8000, %edi  /* base of EGA text mode memory */
     308        xorl %eax, %eax
     309       
     310        /* Read bits 8 - 15 of the cursor address */
     311        movw $0x3d4, %dx
     312        movb $0xe, %al
     313        outb %al, %dx
     314       
     315        movw $0x3d5, %dx
     316        inb %dx, %al
     317        shl $8, %ax
     318       
     319        /* Read bits 0 - 7 of the cursor address */
     320        movw $0x3d4, %dx
     321        movb $0xf, %al
     322        outb %al, %dx
     323       
     324        movw $0x3d5, %dx
     325        inb %dx, %al
     326       
     327        /* Sanity check for the cursor on screen */
     328        cmp $2000, %ax
     329        jb pm_puts_cursor_ok
     330       
     331                movw $1998, %ax
     332       
     333        pm_puts_cursor_ok:
     334       
     335        movw %ax, %bx
     336        shl $1, %eax
     337        addl %eax, %edi
     338       
     339        pm_puts_ploop:
     340                lodsb
     341               
     342                cmp $0, %al
     343                je pm_puts_ploop_end
     344               
     345                movb $0x0a, %ah  /* black background, light green foreground */
     346                stosw
     347               
     348                /* Sanity check for the cursor on the last line */
     349                inc %bx
     350                cmp $2000, %bx
     351                jb pm_puts_ploop
     352               
     353                /* Scroll the screen (24 rows) */
     354                movl %esi, %edx
     355                movl $0xb80a0, %esi
     356                movl $0xb8000, %edi
     357                movl $1920, %ecx
     358                rep movsw
     359               
     360                /* Clear the 24th row */
     361                xorl %eax, %eax
     362                movl $80, %ecx
     363                rep stosw
     364               
     365                /* Go to row 24 */
     366                movl %edx, %esi
     367                movl $0xb8f00, %edi
     368                movw $1920, %bx
     369               
     370                jmp pm_puts_ploop
     371        pm_puts_ploop_end:
     372       
     373        /* Write bits 8 - 15 of the cursor address */
     374        movw $0x3d4, %dx
     375        movb $0xe, %al
     376        outb %al, %dx
     377       
     378        movw $0x3d5, %dx
     379        movb %bh, %al
     380        outb %al, %dx
     381       
     382        /* Write bits 0 - 7 of the cursor address */
     383        movw $0x3d4, %dx
     384        movb $0xf, %al
     385        outb %al, %dx
     386       
     387        movw $0x3d5, %dx
     388        movb %bl, %al
     389        outb %al, %dx
     390       
     391        popl %edi
     392        popl %edx
     393        popl %ecx
     394        popl %ebx
     395        popl %eax
     396       
     397        ret
     398
    165399.code64
     400
     401.macro long_status msg
     402        pushq %rdi
     403        movq \msg, %rdi
     404        call early_puts
     405        popq %rdi
     406.endm
     407
    166408start64:
     409       
     410        /*
     411         * Long mode.
     412         */
     413       
    167414        movq $(PA2KA(START_STACK)), %rsp
    168415       
    169         # call arch_pre_main(grub_eax, grub_ebx)
     416        /* Create the first stack frame */
     417        pushq $0
     418        movq %rsp, %rbp
     419       
     420        long_status $status_long
     421       
     422        /* Call arch_pre_main(grub_eax, grub_ebx) */
    170423        xorq %rdi, %rdi
    171424        movl grub_eax, %edi
     
    176429        callq *%rax
    177430       
    178         # create the first stack frame
    179         pushq $0
    180         movq %rsp, %rbp
    181        
     431        long_status $status_main
     432       
     433        /* Call main_bsp() */
    182434        movabsq $main_bsp, %rax
    183435        call *%rax
    184436       
    185         # not reached
    186        
     437        /* Not reached */
    187438        cli
    188439        hlt0:
     
    190441                jmp hlt0
    191442
    192 # Print string from %esi to EGA display (in red) and halt
    193 error_halt:
    194         movl $0xb8000, %edi       # base of EGA text mode memory
    195         xorl %eax, %eax
    196        
    197         movw $0x3d4, %dx          # read bits 8 - 15 of the cursor address
     443/** Print string to EGA display.
     444 *
     445 * Should be called from long mode (with paging enabled
     446 * and stack established). This function is ABI compliant
     447 * (without red-zone).
     448 *
     449 * If CONFIG_EGA is undefined or CONFIG_FB is defined
     450 * then this function does nothing.
     451 *
     452 * @param %rdi NULL-terminated string to print.
     453 *
     454 */
     455early_puts:
     456       
     457#if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
     458       
     459        /* Prologue, save preserved registers */
     460        pushq %rbp
     461        movq %rsp, %rbp
     462        pushq %rbx
     463       
     464        movq %rdi, %rsi
     465        movq $(PA2KA(0xb8000)), %rdi  /* base of EGA text mode memory */
     466        xorq %rax, %rax
     467       
     468        /* Read bits 8 - 15 of the cursor address */
     469        movw $0x3d4, %dx
    198470        movb $0xe, %al
    199471        outb %al, %dx
     
    203475        shl $8, %ax
    204476       
    205         movw $0x3d4, %dx          # read bits 0 - 7 of the cursor address
     477        /* Read bits 0 - 7 of the cursor address */
     478        movw $0x3d4, %dx
    206479        movb $0xf, %al
    207480        outb %al, %dx
     
    210483        inb %dx, %al
    211484       
    212         cmp $1920, %ax
    213         jbe cursor_ok
    214        
    215                 movw $1920, %ax       # sanity check for the cursor on the last line
    216        
    217         cursor_ok:
     485        /* Sanity check for the cursor on screen */
     486        cmp $2000, %ax
     487        jb early_puts_cursor_ok
     488       
     489                movw $1998, %ax
     490       
     491        early_puts_cursor_ok:
    218492       
    219493        movw %ax, %bx
    220         shl $1, %eax
    221         addl %eax, %edi
    222        
    223         movw $0x0c00, %ax         # black background, light red foreground
    224        
    225         ploop:
     494        shl $1, %rax
     495        addq %rax, %rdi
     496       
     497        early_puts_ploop:
    226498                lodsb
     499               
    227500                cmp $0, %al
    228                 je ploop_end
     501                je early_puts_ploop_end
     502               
     503                movb $0x0e, %ah  /* black background, yellow foreground */
    229504                stosw
     505               
     506                /* Sanity check for the cursor on the last line */
    230507                inc %bx
    231                 jmp ploop
    232         ploop_end:
    233        
    234         movw $0x3d4, %dx          # write bits 8 - 15 of the cursor address
     508                cmp $2000, %bx
     509                jb early_puts_ploop
     510               
     511                /* Scroll the screen (24 rows) */
     512                movq %rsi, %rdx
     513                movq $(PA2KA(0xb80a0)), %rsi
     514                movq $(PA2KA(0xb8000)), %rdi
     515                movq $1920, %rcx
     516                rep movsw
     517               
     518                /* Clear the 24th row */
     519                xorq %rax, %rax
     520                movq $80, %rcx
     521                rep stosw
     522               
     523                /* Go to row 24 */
     524                movq %rdx, %rsi
     525                movq $(PA2KA(0xb8f00)), %rdi
     526                movw $1920, %bx
     527               
     528                jmp early_puts_ploop
     529        early_puts_ploop_end:
     530       
     531        /* Write bits 8 - 15 of the cursor address */
     532        movw $0x3d4, %dx
    235533        movb $0xe, %al
    236534        outb %al, %dx
     
    240538        outb %al, %dx
    241539       
    242         movw $0x3d4, %dx          # write bits 0 - 7 of the cursor address
     540        /* Write bits 0 - 7 of the cursor address */
     541        movw $0x3d4, %dx
    243542        movb $0xf, %al
    244543        outb %al, %dx
     
    248547        outb %al, %dx
    249548       
    250         cli
    251         hlt1:
    252                 hlt
    253                 jmp hlt1
     549        /* Epilogue, restore preserved registers */
     550        popq %rbx
     551        leave
     552       
     553#endif
     554       
     555        ret
    254556
    255557#include "vesa_real.inc"
     
    257559.section K_INI_PTLS, "aw", @progbits
    258560
    259 #
    260 # Macro for generating initial page table contents.
    261 # @param cnt Number of entries to generate. Must be multiple of 8.
    262 # @param g   Number of GB that will be added to the mapping.
    263 #
     561/** Generate initial page table contents.
     562 *
     563 * @param cnt Number of entries to generate. Must be multiple of 8.
     564 * @param g   Number of GB that will be added to the mapping.
     565 *
     566 */
    264567.macro ptl2gen cnt g
    265568        .if \cnt
     
    276579.endm
    277580
    278 # Page table for pages in the 1st gigabyte.
     581/* Page table for pages in the 1st gigabyte. */
    279582.align 4096
    280583ptl_2_0g:
    281584        ptl2gen 512 0
    282585
    283 # Page table for pages in the 2nd gigabyte.
     586/* Page table for pages in the 2nd gigabyte. */
    284587.align 4096
    285588ptl_2_1g:
    286589        ptl2gen 512 1
    287590
    288 # Page table for pages in the 3rd gigabyte.
     591/* Page table for pages in the 3rd gigabyte. */
    289592.align 4096
    290593ptl_2_2g:
    291594        ptl2gen 512 2
    292595
    293 # Page table for pages in the 4th gigabyte.
     596/* Page table for pages in the 4th gigabyte. */
    294597.align 4096
    295598ptl_2_3g:
    296599        ptl2gen 512 3
    297600
    298 # Page table for pages in the 5th gigabyte.
     601/* Page table for pages in the 5th gigabyte. */
    299602.align 4096
    300603ptl_2_4g:
    301604        ptl2gen 512 3
    302605
    303 # Page table for pages in the 6th gigabyte.
     606/* Page table for pages in the 6th gigabyte. */
    304607.align 4096
    305608ptl_2_5g:
    306609        ptl2gen 512 3
    307610
    308 # Page table for pages in the 7th gigabyte.
     611/* Page table for pages in the 7th gigabyte. */
    309612.align 4096
    310613ptl_2_6g:
    311614        ptl2gen 512 3
    312615
    313 # Page table for pages in the 8th gigabyte.
     616/* Page table for pages in the 8th gigabyte. */
    314617.align 4096
    315618ptl_2_7g:
     
    318621.align 4096
    319622ptl_1:
    320         # Identity mapping for [0; 8G)
     623        /* Identity mapping for [0; 8G) */
    321624        .quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
    322625        .quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT)
     
    350653        .long 0
    351654
    352 extended_cpuid_msg:
     655err_extended_cpuid:
    353656        .asciz "Error: Extended CPUID not supported -- CPU is not 64-bit. System halted."
    354 long_mode_msg:
     657err_long_mode:
    355658        .asciz "Error: 64-bit long mode not supported. System halted."
    356 noexecute_msg:
     659err_noexecute:
    357660        .asciz "Error: No-execute pages not supported. System halted."
    358 fx_msg:
     661err_fx:
    359662        .asciz "Error: FXSAVE/FXRESTORE instructions not supported. System halted."
    360 sse2_msg:
     663err_sse2:
    361664        .asciz "Error: SSE2 instructions not supported. System halted."
     665
     666status_prot:
     667        .asciz "[prot] "
     668status_vesa_copy:
     669        .asciz "[vesa_copy] "
     670status_grub_cmdline:
     671        .asciz "[grub_cmdline] "
     672status_vesa_real:
     673        .asciz "[vesa_real] "
     674status_prot2:
     675        .asciz "[prot2] "
     676status_long:
     677        .asciz "[long] "
     678status_main:
     679        .asciz "[main] "
  • kernel/arch/amd64/src/boot/vesa_ret.inc

    reee047c r90ed058  
    11.code32
    22vesa_init_protected:
     3        cld
     4       
     5        /* Initialize stack pointer */
     6        movl $START_STACK, %esp
     7       
     8        /* Kernel data + stack */
    39        movw $gdtselector(KDATA_DES), %cx
    410        movw %cx, %es
    5         movw %cx, %ds                       # kernel data + stack
     11        movw %cx, %ds
    612        movw %cx, %ss
    713       
    8         #
    9         # Simics seems to remove hidden part of GS on entering user mode
    10         # when _visible_ part of GS does not point to user-mode segment.
    11         #
     14        /*
     15         * Simics seems to remove hidden part of GS on entering user mode
     16         * when _visible_ part of GS does not point to user-mode segment.
     17         */
    1218       
    1319        movw $gdtselector(UDATA_DES), %cx
     
    1521        movw %cx, %gs
    1622       
    17         movl $START_STACK, %esp             # initialize stack pointer
    18        
    1923        jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point
  • kernel/arch/ia32/include/smp/apic.h

    reee047c r90ed058  
    347347
    348348extern uint32_t apic_id_mask;
     349extern uint8_t bsp_l_apic;
    349350
    350351extern void apic_init(void);
     
    355356extern int l_apic_send_init_ipi(uint8_t);
    356357extern void l_apic_debug(void);
    357 extern uint8_t l_apic_id(void);
    358358
    359359extern uint32_t io_apic_read(uint8_t);
  • kernel/arch/ia32/src/boot/boot.S

    reee047c r90ed058  
    1 #
    2 # Copyright (c) 2001-2004 Jakub Jermar
    3 # Copyright (c) 2005-2006 Martin Decky
    4 # All rights reserved.
    5 #
    6 # Redistribution and use in source and binary forms, with or without
    7 # modification, are permitted provided that the following conditions
    8 # are met:
    9 #
    10 # - Redistributions of source code must retain the above copyright
    11 #   notice, this list of conditions and the following disclaimer.
    12 # - Redistributions in binary form must reproduce the above copyright
    13 #   notice, this list of conditions and the following disclaimer in the
    14 #   documentation and/or other materials provided with the distribution.
    15 # - The name of the author may not be used to endorse or promote products
    16 #   derived from this software without specific prior written permission.
    17 #
    18 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    19 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    20 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    21 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    22 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    23 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    27 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    28 #
     1/*
     2 * Copyright (c) 2001 Jakub Jermar
     3 * Copyright (c) 2005 Martin Decky
     4 * All rights reserved.
     5 *
     6 * Redistribution and use in source and binary forms, with or without
     7 * modification, are permitted provided that the following conditions
     8 * are met:
     9 *
     10 * - Redistributions of source code must retain the above copyright
     11 *   notice, this list of conditions and the following disclaimer.
     12 * - Redistributions in binary form must reproduce the above copyright
     13 *   notice, this list of conditions and the following disclaimer in the
     14 *   documentation and/or other materials provided with the distribution.
     15 * - The name of the author may not be used to endorse or promote products
     16 *   derived from this software without specific prior written permission.
     17 *
     18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 */
    2929
    3030#include <arch/boot/boot.h>
     
    3434#include <arch/cpuid.h>
    3535
    36 #define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
     36#define START_STACK  (BOOT_OFFSET - BOOT_STACK_SIZE)
    3737
    3838.section K_TEXT_START, "ax"
    3939
    4040.code32
     41
     42.macro pm_error msg
     43        movl \msg, %esi
     44        jmp pm_error_halt
     45.endm
     46
     47.macro pm_status msg
     48#ifdef CONFIG_EGA
     49        pushl %esi
     50        movl \msg, %esi
     51        call pm_early_puts
     52        popl %esi
     53#endif
     54.endm
     55
     56.macro pm2_status msg
     57        pushl \msg
     58        call early_puts
     59.endm
     60
    4161.align 4
    4262.global multiboot_image_start
     
    4464        .long MULTIBOOT_HEADER_MAGIC
    4565        .long MULTIBOOT_HEADER_FLAGS
    46         .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)  # checksum
     66        .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)  /* checksum */
    4767        .long multiboot_header
    4868        .long unmapped_ktext_start
     
    5373multiboot_image_start:
    5474        cld
    55         movl $START_STACK, %esp     # initialize stack pointer
    56         lgdt KA2PA(bootstrap_gdtr)  # initialize Global Descriptor Table register
    57        
     75       
     76        /* Initialize stack pointer */
     77        movl $START_STACK, %esp
     78       
     79        /* Initialize Global Descriptor Table register */
     80        lgdtl KA2PA(bootstrap_gdtr)
     81       
     82        /* Kernel data + stack */
    5883        movw $gdtselector(KDATA_DES), %cx
    5984        movw %cx, %es
    6085        movw %cx, %fs
    6186        movw %cx, %gs
    62         movw %cx, %ds               # kernel data + stack
     87        movw %cx, %ds
    6388        movw %cx, %ss
    6489       
     
    6691        multiboot_meeting_point:
    6792       
    68         movl %eax, grub_eax         # save parameters from GRUB
     93        /* Save GRUB arguments */
     94        movl %eax, grub_eax
    6995        movl %ebx, grub_ebx
     96       
     97        pm_status $status_prot
    7098       
    7199        movl $(INTEL_CPUID_LEVEL), %eax
    72100        cpuid
    73         cmp $0x0, %eax              # any function > 0?
     101        cmp $0x0, %eax  /* any function > 0? */
    74102        jbe pse_unsupported
    75103       
     
    80108       
    81109        pse_unsupported:
    82                 movl $pse_msg, %esi
    83                 jmp error_halt
     110               
     111                pm_error $err_pse
    84112       
    85113        pse_supported:
    86114       
    87115#include "vesa_prot.inc"
    88 
    89         # map kernel and turn paging on
     116       
     117        /* Map kernel and turn paging on */
    90118        call map_kernel
    91119       
    92         # call arch_pre_main(grub_eax, grub_ebx)
     120        /* Create the first stack frame */
     121        pushl $0
     122        movl %esp, %ebp
     123       
     124        pm2_status $status_prot2
     125       
     126        /* Call arch_pre_main(grub_eax, grub_ebx) */
    93127        pushl grub_ebx
    94128        pushl grub_eax
    95129        call arch_pre_main
    96 
    97         # Create the first stack frame
    98         pushl $0
    99         movl %esp, %ebp
    100        
     130       
     131        pm2_status $status_main
     132       
     133        /* Call main_bsp() */
    101134        call main_bsp
    102135       
    103         # not reached
     136        /* Not reached */
    104137        cli
    105138        hlt0:
     
    107140                jmp hlt0
    108141
     142/** Setup mapping for the kernel.
     143 *
     144 * Setup mapping for both the unmapped and mapped sections
     145 * of the kernel. For simplicity, we map the entire 4G space.
     146 *
     147 */
    109148.global map_kernel
    110149map_kernel:
    111         #
    112         # Here we setup mapping for both the unmapped and mapped sections of the kernel.
    113         # For simplicity, we map the entire 4G space.
    114         #
    115150        movl %cr4, %ecx
    116         orl $(1 << 4), %ecx                 # turn PSE on
    117         andl $(~(1 << 5)), %ecx             # turn PAE off
     151        orl $(1 << 4), %ecx      /* PSE on */
     152        andl $(~(1 << 5)), %ecx  /* PAE off */
    118153        movl %ecx, %cr4
    119154       
     
    126161                movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
    127162                orl %ebx, %eax
    128                 movl %eax, (%esi, %ecx, 4)      # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
    129                 movl %eax, (%edi, %ecx, 4)      # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
     163                /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
     164                movl %eax, (%esi, %ecx, 4)
     165                /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
     166                movl %eax, (%edi, %ecx, 4)
    130167                addl $(4 * 1024 * 1024), %ebx
    131168               
     
    137174       
    138175        movl %cr0, %ebx
    139         orl $(1 << 31), %ebx                # turn paging on
     176        orl $(1 << 31), %ebx  /* paging on */
    140177        movl %ebx, %cr0
    141178        ret
    142179
    143 # Print string from %esi to EGA display (in red) and halt
    144 error_halt:
    145         movl $0xb8000, %edi         # base of EGA text mode memory
     180/** Print string to EGA display (in light red) and halt.
     181 *
     182 * Should be executed from 32 bit protected mode with paging
     183 * turned off. Stack is not required. This routine is used even
     184 * if CONFIG_EGA is not enabled. Since we are going to halt the
     185 * CPU anyway, it is always better to at least try to print
     186 * some hints.
     187 *
     188 * @param %esi NULL-terminated string to print.
     189 *
     190 */
     191pm_error_halt:
     192        movl $0xb8000, %edi  /* base of EGA text mode memory */
    146193        xorl %eax, %eax
    147194       
    148         movw $0x3d4, %dx            # read bits 8 - 15 of the cursor address
     195        /* Read bits 8 - 15 of the cursor address */
     196        movw $0x3d4, %dx
    149197        movb $0xe, %al
    150198        outb %al, %dx
     
    154202        shl $8, %ax
    155203       
    156         movw $0x3d4, %dx            # read bits 0 - 7 of the cursor address
     204        /* Read bits 0 - 7 of the cursor address */
     205        movw $0x3d4, %dx
    157206        movb $0xf, %al
    158207        outb %al, %dx
     
    161210        inb %dx, %al
    162211       
    163         cmp $1920, %ax
    164         jbe cursor_ok
    165        
    166                 movw $1920, %ax         # sanity check for the cursor on the last line
    167        
    168         cursor_ok:
     212        /* Sanity check for the cursor on screen */
     213        cmp $2000, %ax
     214        jb err_cursor_ok
     215       
     216                movw $1998, %ax
     217       
     218        err_cursor_ok:
    169219       
    170220        movw %ax, %bx
     
    172222        addl %eax, %edi
    173223       
    174         movw $0x0c00, %ax           # black background, light red foreground
    175        
    176         ploop:
     224        err_ploop:
    177225                lodsb
     226               
    178227                cmp $0, %al
    179                 je ploop_end
     228                je err_ploop_end
     229               
     230                movb $0x0c, %ah  /* black background, light red foreground */
    180231                stosw
     232               
     233                /* Sanity check for the cursor on the last line */
    181234                inc %bx
    182                 jmp ploop
    183         ploop_end:
    184        
    185         movw $0x3d4, %dx            # write bits 8 - 15 of the cursor address
     235                cmp $2000, %bx
     236                jb err_ploop
     237               
     238                /* Scroll the screen (24 rows) */
     239                movl %esi, %edx
     240                movl $0xb80a0, %esi
     241                movl $0xb8000, %edi
     242                movl $1920, %ecx
     243                rep movsw
     244               
     245                /* Clear the 24th row */
     246                xorl %eax, %eax
     247                movl $80, %ecx
     248                rep stosw
     249               
     250                /* Go to row 24 */
     251                movl %edx, %esi
     252                movl $0xb8f00, %edi
     253                movw $1920, %bx
     254               
     255                jmp err_ploop
     256        err_ploop_end:
     257       
     258        /* Write bits 8 - 15 of the cursor address */
     259        movw $0x3d4, %dx
    186260        movb $0xe, %al
    187261        outb %al, %dx
     
    191265        outb %al, %dx
    192266       
    193         movw $0x3d4, %dx            # write bits 0 - 7 of the cursor address
     267        /* Write bits 0 - 7 of the cursor address */
     268        movw $0x3d4, %dx
    194269        movb $0xf, %al
    195270        outb %al, %dx
     
    204279                jmp hlt1
    205280
     281/** Print string to EGA display (in light green).
     282 *
     283 * Should be called from 32 bit protected mode with paging
     284 * turned off. A stack space of at least 24 bytes is required,
     285 * but the function does not establish a stack frame.
     286 *
     287 * Macros such as pm_status take care that this function
     288 * is used only when CONFIG_EGA is enabled.
     289 *
     290 * @param %esi NULL-terminated string to print.
     291 *
     292 */
     293pm_early_puts:
     294        pushl %eax
     295        pushl %ebx
     296        pushl %ecx
     297        pushl %edx
     298        pushl %edi
     299       
     300        movl $0xb8000, %edi  /* base of EGA text mode memory */
     301        xorl %eax, %eax
     302       
     303        /* Read bits 8 - 15 of the cursor address */
     304        movw $0x3d4, %dx
     305        movb $0xe, %al
     306        outb %al, %dx
     307       
     308        movw $0x3d5, %dx
     309        inb %dx, %al
     310        shl $8, %ax
     311       
     312        /* Read bits 0 - 7 of the cursor address */
     313        movw $0x3d4, %dx
     314        movb $0xf, %al
     315        outb %al, %dx
     316       
     317        movw $0x3d5, %dx
     318        inb %dx, %al
     319       
     320        /* Sanity check for the cursor on screen */
     321        cmp $2000, %ax
     322        jb pm_puts_cursor_ok
     323       
     324                movw $1998, %ax
     325       
     326        pm_puts_cursor_ok:
     327       
     328        movw %ax, %bx
     329        shl $1, %eax
     330        addl %eax, %edi
     331       
     332        pm_puts_ploop:
     333                lodsb
     334               
     335                cmp $0, %al
     336                je pm_puts_ploop_end
     337               
     338                movb $0x0a, %ah  /* black background, light green foreground */
     339                stosw
     340               
     341                /* Sanity check for the cursor on the last line */
     342                inc %bx
     343                cmp $2000, %bx
     344                jb pm_puts_ploop
     345               
     346                /* Scroll the screen (24 rows) */
     347                movl %esi, %edx
     348                movl $0xb80a0, %esi
     349                movl $0xb8000, %edi
     350                movl $1920, %ecx
     351                rep movsw
     352               
     353                /* Clear the 24th row */
     354                xorl %eax, %eax
     355                movl $80, %ecx
     356                rep stosw
     357               
     358                /* Go to row 24 */
     359                movl %edx, %esi
     360                movl $0xb8f00, %edi
     361                movw $1920, %bx
     362               
     363                jmp pm_puts_ploop
     364        pm_puts_ploop_end:
     365       
     366        /* Write bits 8 - 15 of the cursor address */
     367        movw $0x3d4, %dx
     368        movb $0xe, %al
     369        outb %al, %dx
     370       
     371        movw $0x3d5, %dx
     372        movb %bh, %al
     373        outb %al, %dx
     374       
     375        /* Write bits 0 - 7 of the cursor address */
     376        movw $0x3d4, %dx
     377        movb $0xf, %al
     378        outb %al, %dx
     379       
     380        movw $0x3d5, %dx
     381        movb %bl, %al
     382        outb %al, %dx
     383       
     384        popl %edi
     385        popl %edx
     386        popl %ecx
     387        popl %ebx
     388        popl %eax
     389       
     390        ret
     391
     392/** Print string to EGA display.
     393 *
     394 * Should be called from 32 bit protected mode (with paging
     395 * enabled and stack established). This function is ABI compliant.
     396 *
     397 * If CONFIG_EGA is undefined or CONFIG_FB is defined
     398 * then this function does nothing.
     399 *
     400 * @param %ebp+0x08 NULL-terminated string to print.
     401 *
     402 */
     403early_puts:
     404       
     405#if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
     406       
     407        /* Prologue, save preserved registers */
     408        pushl %ebp
     409        movl %esp, %ebp
     410        pushl %ebx
     411        pushl %esi
     412        pushl %edi
     413       
     414        movl 0x08(%ebp), %esi
     415        movl $(PA2KA(0xb8000)), %edi  /* base of EGA text mode memory */
     416        xorl %eax, %eax
     417       
     418        /* Read bits 8 - 15 of the cursor address */
     419        movw $0x3d4, %dx
     420        movb $0xe, %al
     421        outb %al, %dx
     422       
     423        movw $0x3d5, %dx
     424        inb %dx, %al
     425        shl $8, %ax
     426       
     427        /* Read bits 0 - 7 of the cursor address */
     428        movw $0x3d4, %dx
     429        movb $0xf, %al
     430        outb %al, %dx
     431       
     432        movw $0x3d5, %dx
     433        inb %dx, %al
     434       
     435        /* Sanity check for the cursor on screen */
     436        cmp $2000, %ax
     437        jb early_puts_cursor_ok
     438       
     439                movw $1998, %ax
     440       
     441        early_puts_cursor_ok:
     442       
     443        movw %ax, %bx
     444        shl $1, %eax
     445        addl %eax, %edi
     446       
     447        early_puts_ploop:
     448                lodsb
     449               
     450                cmp $0, %al
     451                je early_puts_ploop_end
     452               
     453                movb $0x0e, %ah  /* black background, yellow foreground */
     454                stosw
     455               
     456                /* Sanity check for the cursor on the last line */
     457                inc %bx
     458                cmp $2000, %bx
     459                jb early_puts_ploop
     460               
     461                /* Scroll the screen (24 rows) */
     462                movl %esi, %edx
     463                movl $(PA2KA(0xb80a0)), %esi
     464                movl $(PA2KA(0xb8000)), %edi
     465                movl $1920, %ecx
     466                rep movsw
     467               
     468                /* Clear the 24th row */
     469                xorl %eax, %eax
     470                movl $80, %ecx
     471                rep stosw
     472               
     473                /* Go to row 24 */
     474                movl %edx, %esi
     475                movl $(PA2KA(0xb8f00)), %edi
     476                movw $1920, %bx
     477               
     478                jmp early_puts_ploop
     479        early_puts_ploop_end:
     480       
     481        /* Write bits 8 - 15 of the cursor address */
     482        movw $0x3d4, %dx
     483        movb $0xe, %al
     484        outb %al, %dx
     485       
     486        movw $0x3d5, %dx
     487        movb %bh, %al
     488        outb %al, %dx
     489       
     490        /* Write bits 0 - 7 of the cursor address */
     491        movw $0x3d4, %dx
     492        movb $0xf, %al
     493        outb %al, %dx
     494       
     495        movw $0x3d5, %dx
     496        movb %bl, %al
     497        outb %al, %dx
     498       
     499        /* Epilogue, restore preserved registers */
     500        popl %edi
     501        popl %esi
     502        popl %ebx
     503        leave
     504       
     505#endif
     506       
     507        ret
     508
    206509#include "vesa_real.inc"
    207510
     
    218521        .long 0
    219522
    220 pse_msg:
     523err_pse:
    221524        .asciz "Page Size Extension not supported. System halted."
    222525
     526status_prot:
     527        .asciz "[prot] "
     528status_vesa_copy:
     529        .asciz "[vesa_copy] "
     530status_grub_cmdline:
     531        .asciz "[grub_cmdline] "
     532status_vesa_real:
     533        .asciz "[vesa_real] "
     534status_prot2:
     535        .asciz "[prot2] "
     536status_main:
     537        .asciz "[main] "
  • kernel/arch/ia32/src/boot/vesa_prot.inc

    reee047c r90ed058  
    55#define MBINFO_OFFSET_CMDLINE   16
    66
    7         # copy real mode VESA initialization code
     7        /* Copy real mode VESA initialization code */
     8       
     9        pm_status $status_vesa_copy
    810       
    911        mov $vesa_init, %esi
     
    1214        rep movsb
    1315       
    14         # check for GRUB command line
     16        /* Check for GRUB command line */
     17       
     18        pm_status $status_grub_cmdline
    1519       
    1620        mov grub_eax, %eax
     
    2327        jnc no_cmdline
    2428       
    25         # skip the kernel path in command line
     29        /* Skip the kernel path in command line */
    2630       
    2731        mov MBINFO_OFFSET_CMDLINE(%ebx), %esi
     
    5256        space_loop_done:
    5357       
    54         # copy at most 23 characters from command line
     58        /* Copy at most 23 characters from command line */
    5559       
    5660        mov $VESA_INIT_SEGMENT << 4, %edi
     
    6872        cmd_loop_done:
    6973       
    70         # zero termination
     74        /* Zero termination */
    7175       
    7276        xor %eax, %eax
     
    7579        no_cmdline:
    7680       
    77         # jump to the real mode
     81        /* Jump to the real mode */
     82       
     83        pm_status $status_vesa_real
    7884       
    7985        mov $VESA_INIT_SEGMENT << 4, %edi
     
    8187       
    8288        vesa_meeting_point:
    83                 # returned back to protected mode
     89                /* Returned back to protected mode */
    8490               
    8591                mov %ax, KA2PA(vesa_scanline)
  • kernel/arch/ia32/src/boot/vesa_real.inc

    reee047c r90ed058  
    3131vesa_init:
    3232        jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init
    33        
     33
    3434.code16
    3535vesa_init_real:
     
    5555        pushl %eax
    5656       
    57         # parse default mode string
     57        /* Parse default mode string */
    5858       
    5959        mov $default_mode - vesa_init, %di
     
    6565                mov (%di), %al
    6666               
    67                 # check for digit
     67                /* Check for digit */
    6868               
    6969                cmp $'0', %al
     
    7575                sub $'0', %al
    7676               
    77                 # multiply default_width by 10 and add digit
     77                /* Multiply default_width by 10 and add digit */
    7878               
    7979                mov default_width - vesa_init, %bx
     
    9696                mov (%di), %al
    9797               
    98                 # check for digit
     98                /* Check for digit */
    9999               
    100100                cmp $'0', %al
     
    106106                sub $'0', %al
    107107               
    108                 # multiply default_height by 10 and add digit
     108                /* Multiply default_height by 10 and add digit */
    109109               
    110110                mov default_height - vesa_init, %bx
     
    127127                mov (%di), %al
    128128               
    129                 # check for digit
     129                /* Check for digit */
    130130               
    131131                cmp $'0', %al
     
    137137                sub $'0', %al
    138138               
    139                 # multiply default_bpp by 10 and add digit
     139                /* Multiply default_bpp by 10 and add digit */
    140140               
    141141                mov default_bpp - vesa_init, %bx
     
    167167       
    168168        next_mode:
    169                 # try next mode
     169                /* Try next mode */
     170               
    170171                mov %gs:(%si), %cx
    171172                cmp $VESA_END_OF_MODES, %cx
     
    186187                jne no_mode
    187188               
    188                 # check for proper attributes (supported, color, graphics, linear framebuffer)
     189                /*
     190                 * Check for proper attributes (supported,
     191                 * color, graphics, linear framebuffer).
     192                 */
    189193               
    190194                mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
     
    193197                jne next_mode
    194198               
    195                 # check for proper resolution
     199                /* Check for proper resolution */
    196200               
    197201                mov default_width - vesa_init, %ax
     
    203207                jne next_mode
    204208               
    205                 # check for proper bpp
     209                /* Check for proper bpp */
    206210               
    207211                mov default_bpp - vesa_init, %al
     
    213217                jne next_mode
    214218               
    215                 # for 24 bpp modes accept also 32 bit bpp
     219                /* For 24 bpp modes accept also 32 bit bpp */
    216220               
    217221                mov $32, %al
     
    230234                jnz no_mode
    231235               
    232                 # set 3:2:3 VGA palette
     236                /* Set 3:2:3 VGA palette */
    233237               
    234238                mov VESA_MODE_BPP_OFFSET(%di), %al
     
    241245                mov $0x100, %ecx
    242246               
    243                 bt $5, %ax              # test if VGA compatible registers are present
     247                /* Test if VGA compatible registers are present */
     248                bt $5, %ax
    244249                jnc vga_compat
    245250               
    246                         # try VESA routine to set palette
     251                        /* Use VESA routine to set the palette */
     252                       
    247253                        mov $VESA_SET_PALETTE, %ax
    248254                        xor %bl, %bl
     
    254260               
    255261                vga_compat:
    256                         # try VGA registers to set palette
    257                         movw $0x3c6, %dx    # set palette mask
     262                       
     263                        /* Use VGA registers to set the palette */
     264                       
     265                        movw $0x3c6, %dx  /* set palette mask */
    258266                        movb $0xff, %al
    259267                        outb %al, %dx
    260268                       
    261                         movw $0x3c8, %dx    # first index to set
     269                        movw $0x3c8, %dx  /* first index to set */
    262270                        xor %al, %al
    263271                        outb %al, %dx
    264272                       
    265                         movw $0x3c9, %dx    # data port
     273                        movw $0x3c9, %dx  /* data port */
    266274                       
    267275                        vga_loop:
     
    284292                vga_not_set:
    285293               
    286                 # store mode parameters
    287                 #  eax = bpp[8] scanline[16]
    288                 #  ebx = width[16]  height[16]
    289                 #  edx = red_mask[8] red_pos[8] green_mask[8] green_pos[8]
    290                 #  esi = blue_mask[8] blue_pos[8]
    291                 #  edi = linear frame buffer
     294                /*
     295                 * Store mode parameters:
     296                 *  eax = bpp[8] scanline[16]
     297                 *  ebx = width[16]  height[16]
     298                 *  edx = red_mask[8] red_pos[8] green_mask[8] green_pos[8]
     299                 *  esi = blue_mask[8] blue_pos[8]
     300                 *  edi = linear frame buffer
     301                 */
    292302               
    293303                mov VESA_MODE_BPP_OFFSET(%di), %al
     
    328338       
    329339        no_mode:
    330                 # no prefered mode found
     340               
     341                /* No prefered mode found */
     342               
    331343                mov $0x111, %cx
    332344                push %di
     
    339351                cmp $VESA_OK, %al
    340352                jnz text_mode
    341                 jz set_mode             # force relative jump
     353                jz set_mode  /* force relative jump */
    342354       
    343355        text_mode:
    344                 # reset to EGA text mode (because of problems with VESA)
     356               
     357                /* Reset to EGA text mode (because of problems with VESA) */
     358               
    345359                mov $0x0003, %ax
    346360                int $0x10
    347361                mov $0xffffffff, %edi
    348362                xor %ax, %ax
    349                 jz vesa_leave_real      # force relative jump
     363                jz vesa_leave_real  /* force relative jump */
    350364
    351365vga323:
  • kernel/arch/ia32/src/boot/vesa_ret.inc

    reee047c r90ed058  
    11.code32
    22vesa_init_protected:
     3        cld
     4       
     5        /* Initialize stack pointer */
     6        movl $START_STACK, %esp
     7       
     8        /* Kernel data + stack */
    39        movw $gdtselector(KDATA_DES), %cx
    410        movw %cx, %es
    511        movw %cx, %fs
    612        movw %cx, %gs
    7         movw %cx, %ds               # kernel data + stack
     13        movw %cx, %ds
    814        movw %cx, %ss
    915       
    10         movl $START_STACK, %esp     # initialize stack pointer
    11        
    1216        jmpl $gdtselector(KTEXT_DES), $vesa_meeting_point
  • kernel/arch/ia32/src/smp/apic.c

    reee047c r90ed058  
    7676
    7777uint32_t apic_id_mask = 0;
     78uint8_t bsp_l_apic = 0;
     79
    7880static irq_t l_apic_timer_irq;
    7981
     
    154156}
    155157
     158/** Get Local APIC ID.
     159 *
     160 * @return Local APIC ID.
     161 *
     162 */
     163static uint8_t l_apic_id(void)
     164{
     165        l_apic_id_t idreg;
     166       
     167        idreg.value = l_apic[L_APIC_ID];
     168        return idreg.apic_id;
     169}
     170
    156171/** Initialize APIC on BSP. */
    157172void apic_init(void)
     
    208223        l_apic_init();
    209224        l_apic_debug();
     225       
     226        bsp_l_apic = l_apic_id();
    210227}
    211228
     
    460477{
    461478#ifdef LAPIC_VERBOSE
    462         printf("LVT on cpu%" PRIs ", LAPIC ID: %" PRIu8 "\n", CPU->id, l_apic_id());
     479        printf("LVT on cpu%" PRIs ", LAPIC ID: %" PRIu8 "\n",
     480            CPU->id, l_apic_id());
    463481       
    464482        lvt_tm_t tm;
    465483        tm.value = l_apic[LVT_Tm];
    466         printf("LVT Tm: vector=%hhd, %s, %s, %s\n", tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], tm_mode_str[tm.mode]);
     484        printf("LVT Tm: vector=%" PRIu8 ", %s, %s, %s\n",
     485            tm.vector, delivs_str[tm.delivs], mask_str[tm.masked],
     486            tm_mode_str[tm.mode]);
    467487       
    468488        lvt_lint_t lint;
    469489        lint.value = l_apic[LVT_LINT0];
    470         printf("LVT LINT0: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]);
    471         lint.value = l_apic[LVT_LINT1];
    472         printf("LVT LINT1: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]); 
     490        printf("LVT LINT0: vector=%" PRIu8 ", %s, %s, %s, irr=%u, %s, %s\n",
     491            tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs],
     492            intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode],
     493            mask_str[lint.masked]);
     494       
     495        lint.value = l_apic[LVT_LINT1];
     496        printf("LVT LINT1: vector=%" PRIu8 ", %s, %s, %s, irr=%u, %s, %s\n",
     497            tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs],
     498            intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode],
     499            mask_str[lint.masked]);
    473500       
    474501        lvt_error_t error;
    475502        error.value = l_apic[LVT_Err];
    476         printf("LVT Err: vector=%hhd, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]);
     503        printf("LVT Err: vector=%" PRIu8 ", %s, %s\n", error.vector,
     504            delivs_str[error.delivs], mask_str[error.masked]);
    477505#endif
    478 }
    479 
    480 /** Get Local APIC ID.
    481  *
    482  * @return Local APIC ID.
    483  *
    484  */
    485 uint8_t l_apic_id(void)
    486 {
    487         l_apic_id_t idreg;
    488        
    489         idreg.value = l_apic[L_APIC_ID];
    490         return idreg.apic_id;
    491506}
    492507
  • kernel/arch/ia32/src/smp/mps.c

    reee047c r90ed058  
    7272static size_t l_intr_entry_cnt = 0;
    7373
    74 static uint8_t get_cpu_apic_id(size_t i)
     74static uint8_t mps_cpu_apic_id(size_t i)
    7575{
    7676        ASSERT(i < processor_entry_cnt);
     
    7979}
    8080
    81 static bool is_cpu_enabled(size_t i)
     81static bool mps_cpu_enabled(size_t i)
    8282{
    8383        ASSERT(i < processor_entry_cnt);
     
    8585        /*
    8686         * FIXME: The current local APIC driver limits usable
    87          * APIC IDs to 8.
     87         * CPU IDs to 8.
    8888         *
    8989         */
    90         if (get_cpu_apic_id(i) > 7)
     90        if (i > 7)
    9191                return false;
    9292       
     
    9494}
    9595
    96 static bool is_bsp(size_t i)
     96static bool mps_cpu_bootstrap(size_t i)
    9797{
    9898        ASSERT(i < processor_entry_cnt);
     
    118118 */
    119119struct smp_config_operations mps_config_operations = {
    120         .cpu_enabled = is_cpu_enabled,
    121         .cpu_bootstrap = is_bsp,
    122         .cpu_apic_id = get_cpu_apic_id,
     120        .cpu_enabled = mps_cpu_enabled,
     121        .cpu_bootstrap = mps_cpu_bootstrap,
     122        .cpu_apic_id = mps_cpu_apic_id,
    123123        .irq_to_pin = mps_irq_to_pin
    124124};
  • kernel/arch/ia32/src/smp/smp.c

    reee047c r90ed058  
    6262void smp_init(void)
    6363{
    64         uintptr_t l_apic_address;
    65         uintptr_t io_apic_address;
    66        
    6764        if (acpi_madt) {
    6865                acpi_madt_parse();
     
    7572        }
    7673       
    77         l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME,
    78             FRAME_ATOMIC | FRAME_KA);
    79         if (!l_apic_address)
    80                 panic("Cannot allocate address for l_apic.");
    81        
    82         io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME,
    83             FRAME_ATOMIC | FRAME_KA);
    84         if (!io_apic_address)
    85                 panic("Cannot allocate address for io_apic.");
    86        
    8774        if (config.cpu_count > 1) {
    88                 page_table_lock(AS_KERNEL, true);
    89                 page_mapping_insert(AS_KERNEL, l_apic_address,
    90                     (uintptr_t) l_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE);
    91                 page_mapping_insert(AS_KERNEL, io_apic_address,
    92                     (uintptr_t) io_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE);
    93                 page_table_unlock(AS_KERNEL, true);
    94                
    95                 l_apic = (uint32_t *) l_apic_address;
    96                 io_apic = (uint32_t *) io_apic_address;
     75                l_apic = (uint32_t *) hw_map((uintptr_t) l_apic, PAGE_SIZE);
     76                io_apic = (uint32_t *) hw_map((uintptr_t) io_apic, PAGE_SIZE);
    9777        }
    9878}
     
    133113        apic_init();
    134114       
    135         uint8_t apic = l_apic_id();
    136        
    137115        for (i = 0; i < config.cpu_count; i++) {
    138116                /*
     
    148126                        continue;
    149127               
    150                 if (ops->cpu_apic_id(i) == apic) {
    151                         printf("%s: bad processor entry #%u, will not send IPI "
    152                             "to myself\n", __FUNCTION__, i);
     128                if (ops->cpu_apic_id(i) == bsp_l_apic) {
     129                        printf("kmp: bad processor entry #%u, will not send IPI "
     130                            "to myself\n", i);
    153131                        continue;
    154132                }
  • kernel/genarch/src/acpi/madt.c

    reee047c r90ed058  
    9595        /*
    9696         * FIXME: The current local APIC driver limits usable
    97          * APIC IDs to 8.
     97         * CPU IDs to 8.
    9898         *
    9999         */
    100         if (madt_cpu_apic_id(i) > 7)
     100        if (i > 7)
    101101                return false;
    102102       
     
    111111        return ((struct madt_l_apic *)
    112112            madt_entries_index[madt_l_apic_entry_index + i])->apic_id ==
    113             l_apic_id();
     113            bsp_l_apic;
    114114}
    115115
     
    131131};
    132132
    133 static int madt_cmp(void *a, void *b)
    134 {
    135         uint8_t typea = ((struct madt_apic_header *) a)->type;
    136         uint8_t typeb = ((struct madt_apic_header *) b)->type;
     133static int madt_cmp(void *a, void *b, void *arg)
     134{
     135        uint8_t typea = (*((struct madt_apic_header **) a))->type;
     136        uint8_t typeb = (*((struct madt_apic_header **) b))->type;
    137137       
    138138        if (typea > typeb)
     
    147147static void madt_l_apic_entry(struct madt_l_apic *la, size_t i)
    148148{
    149         if (!madt_l_apic_entry_cnt++)
     149        if (madt_l_apic_entry_cnt == 0)
    150150                madt_l_apic_entry_index = i;
     151       
     152        madt_l_apic_entry_cnt++;
    151153       
    152154        if (!(la->flags & 0x1)) {
     
    160162static void madt_io_apic_entry(struct madt_io_apic *ioa, size_t i)
    161163{
    162         if (!madt_io_apic_entry_cnt++) {
     164        if (madt_io_apic_entry_cnt == 0) {
    163165                /* Remember index of the first io apic entry */
    164166                madt_io_apic_entry_index = i;
     
    167169                /* Currently not supported */
    168170        }
     171       
     172        madt_io_apic_entry_cnt++;
    169173}
    170174
     
    190194        /* Count MADT entries */
    191195        unsigned int madt_entries_index_cnt = 0;
    192         for (hdr = &acpi_madt->apic_header[0]; hdr < end;
     196        for (hdr = acpi_madt->apic_header; hdr < end;
    193197            hdr = (struct madt_apic_header *) (((uint8_t *) hdr) + hdr->length))
    194198                madt_entries_index_cnt++;
     
    196200        /* Create MADT APIC entries index array */
    197201        madt_entries_index = (struct madt_apic_header **)
    198             malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header **),
     202            malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header *),
    199203            FRAME_ATOMIC);
    200204        if (!madt_entries_index)
     
    203207        size_t i = 0;
    204208       
    205         for (hdr = &acpi_madt->apic_header[0]; hdr < end;
    206             hdr = (struct madt_apic_header *) (((uint8_t *) hdr) + hdr->length))
    207                 madt_entries_index[i++] = hdr;
     209        for (hdr = acpi_madt->apic_header; hdr < end;
     210            hdr = (struct madt_apic_header *) (((uint8_t *) hdr) + hdr->length)) {
     211                madt_entries_index[i] = hdr;
     212                i++;
     213        }
    208214       
    209215        /* Sort MADT index structure */
    210         qsort(madt_entries_index, madt_entries_index_cnt, sizeof(uintptr_t),
    211             &madt_cmp);
     216        if (!gsort(madt_entries_index, madt_entries_index_cnt,
     217            sizeof(struct madt_apic_header *), madt_cmp, NULL))
     218                panic("Sorting error.");
    212219       
    213220        /* Parse MADT entries */
  • kernel/generic/include/debug.h

    reee047c r90ed058  
    9393#define LOG(format, ...) \
    9494        do { \
    95                 printf("%s->%s() at %s:%u: " format "\n", symtab_fmt_name_lookup(CALLER), \
    96                     __func__, __FILE__, __LINE__, ##__VA_ARGS__); \
     95                printf("%s() from %s at %s:%u: " format "\n", __func__, \
     96                    symtab_fmt_name_lookup(CALLER), __FILE__, __LINE__, \
     97                    ##__VA_ARGS__); \
    9798        } while (0)
    9899
    99 /** Extensive logging execute macro
    100  *
    101  * If CONFIG_LOG is set, the LOG_EXEC() macro
    102  * will print an information about calling a given
    103  * function and call it.
    104  *
    105  */
    106 #define LOG_EXEC(fnc) \
    107         do { \
    108                 printf("%s->%s() at %s:%u: " #fnc "\n", symtab_fmt_name_lookup(CALLER), \
    109                     __func__, __FILE__, __LINE__); \
    110                 fnc; \
    111         } while (0)
     100extern void __cyg_profile_func_enter(void *, void *);
     101extern void __cyg_profile_func_exit(void *, void *);
    112102
    113103#else /* CONFIG_LOG */
    114104
    115105#define LOG(format, ...)
    116 #define LOG_EXEC(fnc)     fnc
    117106
    118 #endif /* CONFOG_LOG */
     107#endif /* CONFIG_LOG */
    119108
    120109#endif
  • kernel/generic/include/sort.h

    reee047c r90ed058  
    3838#include <typedefs.h>
    3939
    40 /*
    41  * sorting routines
    42  */
    43 extern void bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b));
    44 extern void qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b));
     40typedef int (* sort_cmp_t)(void *, void *, void *);
    4541
    46 /*
    47  * default sorting comparators
    48  */
    49 extern int int_cmp(void * a, void * b);
    50 extern int uint32_t_cmp(void * a, void * b);
    51 extern int uint16_t_cmp(void * a, void * b);
    52 extern int uint8_t_cmp(void * a, void * b);
     42extern bool gsort(void *, size_t, size_t, sort_cmp_t, void *);
     43extern bool qsort(void *, size_t, size_t, sort_cmp_t, void *);
    5344
    5445#endif
  • kernel/generic/src/lib/sort.c

    reee047c r90ed058  
    2727 */
    2828
    29 /** @addtogroup generic 
     29/** @addtogroup generic
    3030 * @{
    3131 */
     
    3333/**
    3434 * @file
    35  * @brief       Sorting functions.
     35 * @brief Sorting functions.
    3636 *
    3737 * This files contains functions implementing several sorting
    38  * algorithms (e.g. quick sort and bubble sort).
    39  */
    40  
     38 * algorithms (e.g. quick sort and gnome sort).
     39 *
     40 */
     41
    4142#include <mm/slab.h>
    4243#include <memstr.h>
    4344#include <sort.h>
    44 #include <panic.h>
    45 
    46 #define EBUFSIZE        32
    47 
    48 void _qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot);
    49 void _bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot);
    50 
    51 /** Quicksort wrapper
    52  *
    53  * This is only a wrapper that takes care of memory allocations for storing
    54  * the pivot and temporary elements for generic quicksort algorithm.
    55  *
    56  * This function _can_ sleep
    57  *
    58  * @param data Pointer to data to be sorted.
    59  * @param n Number of elements to be sorted.
    60  * @param e_size Size of one element.
    61  * @param cmp Comparator function.
    62  *
    63  */
    64 void qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b))
    65 {
    66         uint8_t buf_tmp[EBUFSIZE];
    67         uint8_t buf_pivot[EBUFSIZE];
    68         void * tmp = buf_tmp;
    69         void * pivot = buf_pivot;
    70 
    71         if (e_size > EBUFSIZE) {
    72                 pivot = (void *) malloc(e_size, 0);
    73                 tmp = (void *) malloc(e_size, 0);
     45
     46/** Immediate buffer size.
     47 *
     48 * For small buffer sizes avoid doing malloc()
     49 * and use the stack.
     50 *
     51 */
     52#define IBUF_SIZE  32
     53
     54/** Array accessor.
     55 *
     56 */
     57#define INDEX(buf, i, elem_size)  ((buf) + (i) * (elem_size))
     58
     59/** Gnome sort
     60 *
     61 * Apply generic gnome sort algorithm on supplied data,
     62 * using pre-allocated buffer.
     63 *
     64 * @param data      Pointer to data to be sorted.
     65 * @param cnt       Number of elements to be sorted.
     66 * @param elem_size Size of one element.
     67 * @param cmp       Comparator function.
     68 * @param arg       3rd argument passed to cmp.
     69 * @param slot      Pointer to scratch memory buffer
     70 *                  elem_size bytes long.
     71 *
     72 */
     73static void _gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
     74    void *arg, void *slot)
     75{
     76        size_t i = 0;
     77       
     78        while (i < cnt) {
     79                if ((i > 0) &&
     80                    (cmp(INDEX(data, i, elem_size),
     81                    INDEX(data, i - 1, elem_size), arg) == -1)) {
     82                        memcpy(slot, INDEX(data, i, elem_size), elem_size);
     83                        memcpy(INDEX(data, i, elem_size), INDEX(data, i - 1, elem_size),
     84                            elem_size);
     85                        memcpy(INDEX(data, i - 1, elem_size), slot, elem_size);
     86                        printf("exch: %u %u\n", i - 1, i);
     87                        i--;
     88                } else
     89                        i++;
    7490        }
    75 
    76         _qsort(data, n, e_size, cmp, tmp, pivot);
    77        
    78         if (e_size > EBUFSIZE) {
    79                 free(tmp);
    80                 free(pivot);
    81         }
    8291}
    8392
    8493/** Quicksort
    8594 *
    86  * Apply generic quicksort algorithm on supplied data, using pre-allocated buffers.
    87  *
    88  * @param data Pointer to data to be sorted.
    89  * @param n Number of elements to be sorted.
    90  * @param e_size Size of one element.
    91  * @param cmp Comparator function.
    92  * @param tmp Pointer to scratch memory buffer e_size bytes long.
    93  * @param pivot Pointer to scratch memory buffer e_size bytes long.
    94  *
    95  */
    96 void _qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot)
    97 {
    98         if (n > 4) {
    99                 unsigned int i = 0, j = n - 1;
    100 
    101                 memcpy(pivot, data, e_size);
    102 
    103                 while (1) {
    104                         while ((cmp(data + i * e_size, pivot) < 0) && (i < n))
     95 * Apply generic quicksort algorithm on supplied data,
     96 * using pre-allocated buffers.
     97 *
     98 * @param data      Pointer to data to be sorted.
     99 * @param cnt       Number of elements to be sorted.
     100 * @param elem_size Size of one element.
     101 * @param cmp       Comparator function.
     102 * @param arg       3rd argument passed to cmp.
     103 * @param slot      Pointer to scratch memory buffer
     104 *                  elem_size bytes long.
     105 * @param pivot     Pointer to scratch memory buffer
     106 *                  elem_size bytes long.
     107 *
     108 */
     109static void _qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
     110    void *arg, void *slot, void *pivot)
     111{
     112        if (cnt > 4) {
     113                size_t i = 0;
     114                size_t j = cnt - 1;
     115               
     116                memcpy(pivot, data, elem_size);
     117               
     118                while (true) {
     119                        while ((cmp(INDEX(data, i, elem_size), pivot, arg) < 0) && (i < cnt))
    105120                                i++;
    106                         while ((cmp(data + j * e_size, pivot) >= 0) && (j > 0))
     121                       
     122                        while ((cmp(INDEX(data, j, elem_size), pivot, arg) >= 0) && (j > 0))
    107123                                j--;
    108124                       
    109125                        if (i < j) {
    110                                 memcpy(tmp, data + i * e_size, e_size);
    111                                 memcpy(data + i * e_size, data + j * e_size, e_size);
    112                                 memcpy(data + j * e_size, tmp, e_size);
    113                         } else {
     126                                memcpy(slot, INDEX(data, i, elem_size), elem_size);
     127                                memcpy(INDEX(data, i, elem_size), INDEX(data, j, elem_size),
     128                                    elem_size);
     129                                memcpy(INDEX(data, j, elem_size), slot, elem_size);
     130                        } else
    114131                                break;
    115                         }
    116132                }
    117 
    118                 _qsort(data, j + 1, e_size, cmp, tmp, pivot);
    119                 _qsort(data + (j + 1) * e_size, n - j - 1, e_size, cmp, tmp, pivot);
     133               
     134                _qsort(data, j + 1, elem_size, cmp, arg, slot, pivot);
     135                _qsort(INDEX(data, j + 1, elem_size), cnt - j - 1, elem_size,
     136                    cmp, arg, slot, pivot);
     137        } else
     138                _gsort(data, cnt, elem_size, cmp, arg, slot);
     139}
     140
     141/** Gnome sort wrapper
     142 *
     143 * This is only a wrapper that takes care of memory
     144 * allocations for storing the slot element for generic
     145 * gnome sort algorithm.
     146 *
     147 * This function can sleep.
     148 *
     149 * @param data      Pointer to data to be sorted.
     150 * @param cnt       Number of elements to be sorted.
     151 * @param elem_size Size of one element.
     152 * @param cmp       Comparator function.
     153 * @param arg       3rd argument passed to cmp.
     154 *
     155 * @return True if sorting succeeded.
     156 *
     157 */
     158bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
     159{
     160        uint8_t ibuf_slot[IBUF_SIZE];
     161        void *slot;
     162       
     163        if (elem_size > IBUF_SIZE) {
     164                slot = (void *) malloc(elem_size, 0);
     165                if (!slot)
     166                        return false;
     167        } else
     168                slot = (void *) ibuf_slot;
     169       
     170        _gsort(data, cnt, elem_size, cmp, arg, slot);
     171       
     172        if (elem_size > IBUF_SIZE)
     173                free(slot);
     174       
     175        return true;
     176}
     177
     178/** Quicksort wrapper
     179 *
     180 * This is only a wrapper that takes care of memory
     181 * allocations for storing the pivot and temporary elements
     182 * for generic quicksort algorithm.
     183 *
     184 * This function can sleep.
     185 *
     186 * @param data      Pointer to data to be sorted.
     187 * @param cnt       Number of elements to be sorted.
     188 * @param elem_size Size of one element.
     189 * @param cmp       Comparator function.
     190 * @param arg       3rd argument passed to cmp.
     191 *
     192 * @return True if sorting succeeded.
     193 *
     194 */
     195bool qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
     196{
     197        uint8_t ibuf_slot[IBUF_SIZE];
     198        uint8_t ibuf_pivot[IBUF_SIZE];
     199        void *slot;
     200        void *pivot;
     201       
     202        if (elem_size > IBUF_SIZE) {
     203                slot = (void *) malloc(elem_size, 0);
     204                if (!slot)
     205                        return false;
     206               
     207                pivot = (void *) malloc(elem_size, 0);
     208                if (!pivot) {
     209                        free(slot);
     210                        return false;
     211                }
    120212        } else {
    121                 _bubblesort(data, n, e_size, cmp, tmp);
     213                slot = (void *) ibuf_slot;
     214                pivot = (void *) ibuf_pivot;
    122215        }
    123 }
    124 
    125 /** Bubblesort wrapper
    126  *
    127  * This is only a wrapper that takes care of memory allocation for storing
    128  * the slot element for generic bubblesort algorithm.
    129  *
    130  * @param data Pointer to data to be sorted.
    131  * @param n Number of elements to be sorted.
    132  * @param e_size Size of one element.
    133  * @param cmp Comparator function.
    134  *
    135  */
    136 void bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b))
    137 {
    138         uint8_t buf_slot[EBUFSIZE];
    139         void * slot = buf_slot;
    140        
    141         if (e_size > EBUFSIZE) {
    142                 slot = (void *) malloc(e_size, 0);
    143         }
    144 
    145         _bubblesort(data, n, e_size, cmp, slot);
    146        
    147         if (e_size > EBUFSIZE) {
     216       
     217        _qsort(data, cnt, elem_size, cmp, arg, slot, pivot);
     218       
     219        if (elem_size > IBUF_SIZE) {
     220                free(pivot);
    148221                free(slot);
    149222        }
    150 }
    151 
    152 /** Bubblesort
    153  *
    154  * Apply generic bubblesort algorithm on supplied data, using pre-allocated buffer.
    155  *
    156  * @param data Pointer to data to be sorted.
    157  * @param n Number of elements to be sorted.
    158  * @param e_size Size of one element.
    159  * @param cmp Comparator function.
    160  * @param slot Pointer to scratch memory buffer e_size bytes long.
    161  *
    162  */
    163 void _bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot)
    164 {
    165         bool done = false;
    166         void * p;
    167 
    168         while (!done) {
    169                 done = true;
    170                 for (p = data; p < data + e_size * (n - 1); p = p + e_size) {
    171                         if (cmp(p, p + e_size) == 1) {
    172                                 memcpy(slot, p, e_size);
    173                                 memcpy(p, p + e_size, e_size);
    174                                 memcpy(p + e_size, slot, e_size);
    175                                 done = false;
    176                         }
    177                 }
    178         }
    179 
    180 }
    181 
    182 /*
    183  * Comparator returns 1 if a > b, 0 if a == b, -1 if a < b
    184  */
    185 int int_cmp(void * a, void * b)
    186 {
    187         return (* (int *) a > * (int*)b) ? 1 : (*(int *)a < * (int *)b) ? -1 : 0;
    188 }
    189 
    190 int uint8_t_cmp(void * a, void * b)
    191 {
    192         return (* (uint8_t *) a > * (uint8_t *)b) ? 1 : (*(uint8_t *)a < * (uint8_t *)b) ? -1 : 0;
    193 }
    194 
    195 int uint16_t_cmp(void * a, void * b)
    196 {
    197         return (* (uint16_t *) a > * (uint16_t *)b) ? 1 : (*(uint16_t *)a < * (uint16_t *)b) ? -1 : 0;
    198 }
    199 
    200 int uint32_t_cmp(void * a, void * b)
    201 {
    202         return (* (uint32_t *) a > * (uint32_t *)b) ? 1 : (*(uint32_t *)a < * (uint32_t *)b) ? -1 : 0;
     223       
     224        return true;
    203225}
    204226
  • kernel/generic/src/main/main.c

    reee047c r90ed058  
    104104
    105105/** Lowest safe stack virtual address. */
    106 uintptr_t stack_safe = 0;               
     106uintptr_t stack_safe = 0;
    107107
    108108/*
     
    113113 */
    114114static void main_bsp_separated_stack(void);
     115
    115116#ifdef CONFIG_SMP
    116117static void main_ap_separated_stack(void);
    117118#endif
    118119
    119 #define CONFIG_STACK_SIZE       ((1 << STACK_FRAMES) * STACK_SIZE)
     120#define CONFIG_STACK_SIZE  ((1 << STACK_FRAMES) * STACK_SIZE)
    120121
    121122/** Main kernel routine for bootstrap CPU.
     
    151152                            init.tasks[i].size, config.stack_size);
    152153        }
    153 
     154       
    154155        /* Avoid placing stack on top of boot allocations. */
    155156        if (ballocs.size) {
     
    170171}
    171172
    172 
    173173/** Main kernel routine for bootstrap CPU using new stack.
    174174 *
     
    176176 *
    177177 */
    178 void main_bsp_separated_stack(void) 
     178void main_bsp_separated_stack(void)
    179179{
    180180        /* Keep this the first thing. */
     
    194194         * commands.
    195195         */
    196         LOG_EXEC(kconsole_init());
     196        kconsole_init();
    197197#endif
    198198       
     
    201201         * starts adding its own handlers
    202202         */
    203         LOG_EXEC(exc_init());
     203        exc_init();
    204204       
    205205        /*
    206206         * Memory management subsystems initialization.
    207207         */
    208         LOG_EXEC(arch_pre_mm_init());
    209         LOG_EXEC(frame_init());
     208        arch_pre_mm_init();
     209        frame_init();
    210210       
    211211        /* Initialize at least 1 memory segment big enough for slab to work. */
    212         LOG_EXEC(slab_cache_init());
    213         LOG_EXEC(sysinfo_init());
    214         LOG_EXEC(btree_init());
    215         LOG_EXEC(as_init());
    216         LOG_EXEC(page_init());
    217         LOG_EXEC(tlb_init());
    218         LOG_EXEC(ddi_init());
    219         LOG_EXEC(tasklet_init());
    220         LOG_EXEC(arch_post_mm_init());
    221         LOG_EXEC(arch_pre_smp_init());
    222         LOG_EXEC(smp_init());
     212        slab_cache_init();
     213        sysinfo_init();
     214        btree_init();
     215        as_init();
     216        page_init();
     217        tlb_init();
     218        ddi_init();
     219        tasklet_init();
     220        arch_post_mm_init();
     221        arch_pre_smp_init();
     222        smp_init();
    223223       
    224224        /* Slab must be initialized after we know the number of processors. */
    225         LOG_EXEC(slab_enable_cpucache());
     225        slab_enable_cpucache();
    226226       
    227227        printf("Detected %" PRIs " CPU(s), %" PRIu64" MiB free memory\n",
    228228            config.cpu_count, SIZE2MB(zones_total_size()));
    229 
    230         LOG_EXEC(cpu_init());
    231        
    232         LOG_EXEC(calibrate_delay_loop());
    233         LOG_EXEC(clock_counter_init());
    234         LOG_EXEC(timeout_init());
    235         LOG_EXEC(scheduler_init());
    236         LOG_EXEC(task_init());
    237         LOG_EXEC(thread_init());
    238         LOG_EXEC(futex_init());
     229       
     230        cpu_init();
     231       
     232        calibrate_delay_loop();
     233        clock_counter_init();
     234        timeout_init();
     235        scheduler_init();
     236        task_init();
     237        thread_init();
     238        futex_init();
    239239       
    240240        if (init.cnt > 0) {
     
    247247                printf("No init binaries found.\n");
    248248       
    249         LOG_EXEC(ipc_init());
    250         LOG_EXEC(event_init());
    251         LOG_EXEC(klog_init());
    252         LOG_EXEC(stats_init());
     249        ipc_init();
     250        event_init();
     251        klog_init();
     252        stats_init();
    253253       
    254254        /*
     
    266266        if (!kinit_thread)
    267267                panic("Cannot create kinit thread.");
    268         LOG_EXEC(thread_ready(kinit_thread));
     268        thread_ready(kinit_thread);
    269269       
    270270        /*
     
    276276}
    277277
    278 
    279278#ifdef CONFIG_SMP
     279
    280280/** Main kernel routine for application CPUs.
    281281 *
     
    296296         */
    297297        config.cpu_active++;
    298 
     298       
    299299        /*
    300300         * The THE structure is well defined because ctx.sp is used as stack.
     
    311311        calibrate_delay_loop();
    312312        arch_post_cpu_init();
    313 
     313       
    314314        the_copy(THE, (the_t *) CPU->stack);
    315 
     315       
    316316        /*
    317317         * If we woke kmp up before we left the kernel stack, we could
     
    326326}
    327327
    328 
    329328/** Main kernel routine for application CPUs using new stack.
    330329 *
     
    338337         */
    339338        timeout_init();
    340 
     339       
    341340        waitq_wakeup(&ap_completion_wq, WAKEUP_FIRST);
    342341        scheduler();
    343342        /* not reached */
    344343}
     344
    345345#endif /* CONFIG_SMP */
    346346
  • uspace/lib/c/generic/sort.c

    reee047c r90ed058  
    3636 *
    3737 * This files contains functions implementing several sorting
    38  * algorithms (e.g. quick sort and bubble sort).
     38 * algorithms (e.g. quick sort and gnome sort).
    3939 *
    4040 */
     
    4444#include <malloc.h>
    4545
    46 /** Bubble sort
    47  *
    48  * Apply generic bubble sort algorithm on supplied data,
     46/** Immediate buffer size.
     47 *
     48 * For small buffer sizes avoid doing malloc()
     49 * and use the stack.
     50 *
     51 */
     52#define IBUF_SIZE  32
     53
     54/** Array accessor.
     55 *
     56 */
     57#define INDEX(buf, i, elem_size)  ((buf) + (i) * (elem_size))
     58
     59/** Gnome sort
     60 *
     61 * Apply generic gnome sort algorithm on supplied data,
    4962 * using pre-allocated buffer.
    5063 *
     
    5871 *
    5972 */
    60 static void _bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
     73static void _gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
    6174    void *arg, void *slot)
    6275{
    63         bool done = false;
    64         void *tmp;
    65        
    66         while (!done) {
    67                 done = true;
    68                
    69                 for (tmp = data; tmp < data + elem_size * (cnt - 1);
    70                     tmp = tmp + elem_size) {
    71                         if (cmp(tmp, tmp + elem_size, arg) == 1) {
    72                                 memcpy(slot, tmp, elem_size);
    73                                 memcpy(tmp, tmp + elem_size, elem_size);
    74                                 memcpy(tmp + elem_size, slot, elem_size);
    75                                 done = false;
    76                         }
    77                 }
     76        size_t i = 0;
     77       
     78        while (i < cnt) {
     79                if ((i != 0) &&
     80                    (cmp(INDEX(data, i, elem_size),
     81                    INDEX(data, i - 1, elem_size), arg) == -1)) {
     82                        memcpy(slot, INDEX(data, i, elem_size), elem_size);
     83                        memcpy(INDEX(data, i, elem_size), INDEX(data, i - 1, elem_size),
     84                            elem_size);
     85                        memcpy(INDEX(data, i - 1, elem_size), slot, elem_size);
     86                        i--;
     87                } else
     88                        i++;
    7889        }
    7990}
     
    89100 * @param cmp       Comparator function.
    90101 * @param arg       3rd argument passed to cmp.
    91  * @param tmp       Pointer to scratch memory buffer
     102 * @param slot      Pointer to scratch memory buffer
    92103 *                  elem_size bytes long.
    93104 * @param pivot     Pointer to scratch memory buffer
     
    96107 */
    97108static void _qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
    98     void *arg, void *tmp, void *pivot)
     109    void *arg, void *slot, void *pivot)
    99110{
    100111        if (cnt > 4) {
     
    105116               
    106117                while (true) {
    107                         while ((cmp(data + i * elem_size, pivot, arg) < 0) && (i < cnt))
     118                        while ((cmp(INDEX(data, i, elem_size), pivot, arg) < 0) && (i < cnt))
    108119                                i++;
    109120                       
    110                         while ((cmp(data + j * elem_size, pivot, arg) >= 0) && (j > 0))
     121                        while ((cmp(INDEX(data, j, elem_size), pivot, arg) >= 0) && (j > 0))
    111122                                j--;
    112123                       
    113124                        if (i < j) {
    114                                 memcpy(tmp, data + i * elem_size, elem_size);
    115                                 memcpy(data + i * elem_size, data + j * elem_size,
     125                                memcpy(slot, INDEX(data, i, elem_size), elem_size);
     126                                memcpy(INDEX(data, i, elem_size), INDEX(data, j, elem_size),
    116127                                    elem_size);
    117                                 memcpy(data + j * elem_size, tmp, elem_size);
     128                                memcpy(INDEX(data, j, elem_size), slot, elem_size);
    118129                        } else
    119130                                break;
    120131                }
    121132               
    122                 _qsort(data, j + 1, elem_size, cmp, arg, tmp, pivot);
    123                 _qsort(data + (j + 1) * elem_size, cnt - j - 1, elem_size,
    124                     cmp, arg, tmp, pivot);
     133                _qsort(data, j + 1, elem_size, cmp, arg, slot, pivot);
     134                _qsort(INDEX(data, j + 1, elem_size), cnt - j - 1, elem_size,
     135                    cmp, arg, slot, pivot);
    125136        } else
    126                 _bsort(data, cnt, elem_size, cmp, arg, tmp);
    127 }
    128 
    129 /** Bubble sort wrapper
     137                _gsort(data, cnt, elem_size, cmp, arg, slot);
     138}
     139
     140/** Gnome sort wrapper
    130141 *
    131142 * This is only a wrapper that takes care of memory
    132143 * allocations for storing the slot element for generic
    133  * bubble sort algorithm.
     144 * gnome sort algorithm.
    134145 *
    135146 * @param data      Pointer to data to be sorted.
     
    142153 *
    143154 */
    144 bool bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
    145 {
    146         void *slot = (void *) malloc(elem_size);
    147         if (!slot)
    148                 return false;
    149        
    150         _bsort(data, cnt, elem_size, cmp, arg, slot);
    151        
    152         free(slot);
     155bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
     156{
     157        uint8_t ibuf_slot[IBUF_SIZE];
     158        void *slot;
     159       
     160        if (elem_size > IBUF_SIZE) {
     161                slot = (void *) malloc(elem_size);
     162                if (!slot)
     163                        return false;
     164        } else
     165                slot = (void *) ibuf_slot;
     166       
     167        _gsort(data, cnt, elem_size, cmp, arg, slot);
     168       
     169        if (elem_size > IBUF_SIZE)
     170                free(slot);
    153171       
    154172        return true;
     
    172190bool qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
    173191{
    174         void *tmp = (void *) malloc(elem_size);
    175         if (!tmp)
    176                 return false;
    177        
    178         void *pivot = (void *) malloc(elem_size);
    179         if (!pivot) {
    180                 free(tmp);
    181                 return false;
     192        uint8_t ibuf_slot[IBUF_SIZE];
     193        uint8_t ibuf_pivot[IBUF_SIZE];
     194        void *slot;
     195        void *pivot;
     196       
     197        if (elem_size > IBUF_SIZE) {
     198                slot = (void *) malloc(elem_size);
     199                if (!slot)
     200                        return false;
     201               
     202                pivot = (void *) malloc(elem_size);
     203                if (!pivot) {
     204                        free(slot);
     205                        return false;
     206                }
     207        } else {
     208                slot = (void *) ibuf_slot;
     209                pivot = (void *) ibuf_pivot;
    182210        }
    183211       
    184         _qsort(data, cnt, elem_size, cmp, arg, tmp, pivot);
    185        
    186         free(pivot);
    187         free(tmp);
     212        _qsort(data, cnt, elem_size, cmp, arg, slot, pivot);
     213       
     214        if (elem_size > IBUF_SIZE) {
     215                free(pivot);
     216                free(slot);
     217        }
    188218       
    189219        return true;
  • uspace/lib/c/include/sort.h

    reee047c r90ed058  
    4141typedef int (* sort_cmp_t)(void *, void *, void *);
    4242
    43 extern bool bsort(void *, size_t, size_t, sort_cmp_t, void *);
     43extern bool gsort(void *, size_t, size_t, sort_cmp_t, void *);
    4444extern bool qsort(void *, size_t, size_t, sort_cmp_t, void *);
    4545
Note: See TracChangeset for help on using the changeset viewer.