Changes in / [e2ea4ab1:4d1be48] in mainline


Ignore:
Files:
1 added
2 deleted
52 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    re2ea4ab1 r4d1be48  
    359359! CONFIG_LOG (n/y)
    360360
    361 % Kernel function tracing
    362 ! CONFIG_TRACE (n/y)
    363 
    364361% Compile kernel tests
    365362! CONFIG_TEST (y/n)
  • boot/arch/ia64/src/asm.S

    re2ea4ab1 r4d1be48  
    113113jump_to_kernel:
    114114        alloc loc0 = ar.pfs, 1, 1, 0, 0
    115         mov r2 = in0 ;;                 # Pass bootinfo address
     115        mov r1 = in0 ;;                 # Pass bootinfo address
    116116        movl r8 = KERNEL_ADDRESS;;
    117117        mov b1 = r8 ;;
  • defaults/amd64/Makefile.config

    re2ea4ab1 r4d1be48  
    3232CONFIG_LOG = n
    3333
    34 # Kernel function tracing
    35 CONFIG_TRACE = n
    36 
    3734# Compile kernel tests
    3835CONFIG_TEST = y
  • defaults/arm32/Makefile.config

    re2ea4ab1 r4d1be48  
    2323CONFIG_LOG = n
    2424
    25 # Kernel function tracing
    26 CONFIG_TRACE = n
    27 
    2825# Compile kernel tests
    2926CONFIG_TEST = y
  • defaults/ia32/Makefile.config

    re2ea4ab1 r4d1be48  
    3838CONFIG_LOG = n
    3939
    40 # Kernel function tracing
    41 CONFIG_TRACE = n
    42 
    4340# Compile kernel tests
    4441CONFIG_TEST = y
  • defaults/ia64/Makefile.config

    re2ea4ab1 r4d1be48  
    3535CONFIG_LOG = n
    3636
    37 # Kernel function tracing
    38 CONFIG_TRACE = n
    39 
    4037# Compile kernel tests
    4138CONFIG_TEST = y
  • defaults/mips32/Makefile.config

    re2ea4ab1 r4d1be48  
    2929CONFIG_LOG = n
    3030
    31 # Kernel function tracing
    32 CONFIG_TRACE = n
    33 
    3431# Compile kernel tests
    3532CONFIG_TEST = y
  • defaults/ppc32/Makefile.config

    re2ea4ab1 r4d1be48  
    2323CONFIG_LOG = n
    2424
    25 # Kernel function tracing
    26 CONFIG_TRACE = n
    27 
    2825# Compile kernel tests
    2926CONFIG_TEST = y
  • defaults/sparc64/Makefile.config

    re2ea4ab1 r4d1be48  
    3838CONFIG_LOG = n
    3939
    40 # Kernel function tracing
    41 CONFIG_TRACE = n
    42 
    4340# Compile kernel tests
    4441CONFIG_TEST = y
  • defaults/special/Makefile.config

    re2ea4ab1 r4d1be48  
    2323CONFIG_LOG = n
    2424
    25 # Kernel function tracing
    26 CONFIG_TRACE = n
    27 
    2825# Compile kernel tests
    2926CONFIG_TEST = y
  • kernel/Makefile

    re2ea4ab1 r4d1be48  
    160160        CFLAGS = $(GCC_CFLAGS)
    161161        DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
    162         INSTRUMENTATION = -finstrument-functions
    163162endif
    164163
     
    166165        CFLAGS = $(GCC_CFLAGS)
    167166        DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
    168         INSTRUMENTATION = -finstrument-functions
    169167endif
    170168
     
    172170        CFLAGS = $(ICC_CFLAGS)
    173171        DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
    174         INSTRUMENTATION =
    175172endif
    176173
     
    179176        DEFS += $(CONFIG_DEFS)
    180177        DEPEND_DEFS = $(DEFS)
    181         INSTRUMENTATION =
    182178endif
    183179
     
    185181        CFLAGS = $(CLANG_CFLAGS)
    186182        DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
    187         INSTRUMENTATION =
    188183endif
    189184
     
    207202        generic/src/debug/stacktrace.c \
    208203        generic/src/debug/panic.c \
    209         generic/src/debug/debug.c \
    210204        generic/src/interrupt/interrupt.c \
    211205        generic/src/main/main.c \
     
    361355endif
    362356
    363 ## Sources where instrumentation is enabled
    364 #
    365 
    366 ifeq ($(CONFIG_TRACE),y)
    367 INSTRUMENTED_SOURCES = \
    368         generic/src/cpu/cpu.c \
    369         generic/src/main/main.c \
    370         generic/src/main/kinit.c \
    371         generic/src/proc/the.c
    372 endif
    373 
    374357GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
    375358ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
     
    431414
    432415%.o: %.c $(DEPEND)
    433         $(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) $(if $(findstring $<,$(INSTRUMENTED_SOURCES)),$(INSTRUMENTATION)) -c -o $@ $<
     416        $(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) -c -o $@ $<
    434417ifeq ($(PRECHECK),y)
    435418        $(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS)
  • kernel/arch/abs32le/include/interrupt.h

    re2ea4ab1 r4d1be48  
    3737
    3838#include <typedefs.h>
    39 #include <verify.h>
    4039
    4140#define IVT_ITEMS  0
  • kernel/arch/abs32le/src/abs32le.c

    re2ea4ab1 r4d1be48  
    151151}
    152152
    153 void early_putchar(wchar_t ch)
    154 {
    155 }
    156 
    157153/** @}
    158154 */
  • kernel/arch/amd64/Makefile.inc

    re2ea4ab1 r4d1be48  
    7171        arch/$(KARCH)/src/mm/page.c \
    7272        arch/$(KARCH)/src/mm/tlb.c \
    73         arch/$(KARCH)/src/asm.S \
     73        arch/$(KARCH)/src/asm_utils.S \
    7474        arch/$(KARCH)/src/cpu/cpu.c \
    7575        arch/$(KARCH)/src/proc/scheduler.c \
  • kernel/arch/amd64/src/boot/boot.S

    re2ea4ab1 r4d1be48  
    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 
    6544.align 4
    6645.global multiboot_image_start
     
    6847        .long MULTIBOOT_HEADER_MAGIC
    6948        .long MULTIBOOT_HEADER_FLAGS
    70         .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)  /* checksum */
     49        .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)  # checksum
    7150        .long multiboot_header
    7251        .long unmapped_ktext_start
     
    7756multiboot_image_start:
    7857        cld
    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 */
     58        movl $START_STACK, %esp             # initialize stack pointer
     59        lgdtl bootstrap_gdtr                # initialize Global Descriptor Table register
     60       
    8761        movw $gdtselector(KDATA_DES), %cx
    8862        movw %cx, %es
    89         movw %cx, %ds
     63        movw %cx, %ds                       # kernel data + stack
    9064        movw %cx, %ss
    9165       
    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          */
     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       
    9671        movw $gdtselector(UDATA_DES), %cx
    9772        movw %cx, %fs
     
    10176        multiboot_meeting_point:
    10277       
    103         /* Save GRUB arguments */
    104         movl %eax, grub_eax
     78        movl %eax, grub_eax                 # save parameters from GRUB
    10579        movl %ebx, grub_ebx
    10680       
    107         pm_status $status_prot
     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        #
    10885       
    10986        movl $(INTEL_CPUID_EXTENDED), %eax
     
    11289        ja extended_cpuid_supported
    11390       
    114                 pm_error $err_extended_cpuid
     91                movl $extended_cpuid_msg, %esi
     92                jmp error_halt
    11593       
    11694        extended_cpuid_supported:
     
    12199        jc long_mode_supported
    122100       
    123                 pm_error $err_long_mode
     101                movl $long_mode_msg, %esi
     102                jmp error_halt
    124103       
    125104        long_mode_supported:
     
    128107        jc noexecute_supported
    129108       
    130                 pm_error $err_noexecute
     109                movl $noexecute_msg, %esi
     110                jmp error_halt
    131111       
    132112        noexecute_supported:
     
    137117        jc fx_supported
    138118       
    139                 pm_error $err_fx
     119                movl $fx_msg, %esi
     120                jmp error_halt
    140121       
    141122        fx_supported:
     
    144125        jc sse2_supported
    145126       
    146                 pm_error $err_sse2
     127                movl $sse2_msg, %esi
     128                jmp error_halt
    147129       
    148130        sse2_supported:
    149        
     131
    150132#include "vesa_prot.inc"
    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          */
     133
     134        #
     135        # Enable 64-bit page translation entries - CR4.PAE = 1.
     136        # Paging is not enabled until after long mode is enabled.
     137        #
    163138       
    164139        movl %cr4, %eax
     
    166141        movl %eax, %cr4
    167142       
    168         /* Set up paging tables */
     143        # set up paging tables
     144       
    169145        leal ptl_0, %eax
    170146        movl %eax, %cr3
    171147       
    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) */
     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       
    179157        movl %cr0, %eax
    180158        btsl $31, %eax
    181159        movl %eax, %cr0
    182160       
    183         /* At this point we are in compatibility mode */
     161        # at this point we are in compatibility mode
     162       
    184163        jmpl $gdtselector(KTEXT_DES), $start64
    185164
    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 Pointer to the NULL-terminated string
    195  *             to be print.
    196  *
    197  */
    198 pm_error_halt:
    199         movl $0xb8000, %edi  /* base of EGA text mode memory */
     165.code64
     166start64:
     167        movq $(PA2KA(START_STACK)), %rsp
     168       
     169        # call arch_pre_main(grub_eax, grub_ebx)
     170        xorq %rdi, %rdi
     171        movl grub_eax, %edi
     172        xorq %rsi, %rsi
     173        movl grub_ebx, %esi
     174       
     175        movabsq $arch_pre_main, %rax
     176        callq *%rax
     177       
     178        # create the first stack frame
     179        pushq $0
     180        movq %rsp, %rbp
     181       
     182        movabsq $main_bsp, %rax
     183        call *%rax
     184       
     185        # not reached
     186       
     187        cli
     188        hlt0:
     189                hlt
     190                jmp hlt0
     191
     192# Print string from %esi to EGA display (in red) and halt
     193error_halt:
     194        movl $0xb8000, %edi       # base of EGA text mode memory
    200195        xorl %eax, %eax
    201196       
    202         /* Read bits 8 - 15 of the cursor address */
    203         movw $0x3d4, %dx
     197        movw $0x3d4, %dx          # read bits 8 - 15 of the cursor address
    204198        movb $0xe, %al
    205199        outb %al, %dx
     
    209203        shl $8, %ax
    210204       
    211         /* Read bits 0 - 7 of the cursor address */
    212         movw $0x3d4, %dx
     205        movw $0x3d4, %dx          # read bits 0 - 7 of the cursor address
    213206        movb $0xf, %al
    214207        outb %al, %dx
     
    217210        inb %dx, %al
    218211       
    219         /* Sanity check for the cursor on screen */
    220         cmp $2000, %ax
    221         jb err_cursor_ok
    222        
    223                 movw $1998, %ax
    224        
    225         err_cursor_ok:
     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:
    226218       
    227219        movw %ax, %bx
     
    229221        addl %eax, %edi
    230222       
    231         err_ploop:
     223        movw $0x0c00, %ax         # black background, light red foreground
     224       
     225        ploop:
    232226                lodsb
    233                
    234227                cmp $0, %al
    235                 je err_ploop_end
    236                
    237                 movb $0x0c, %ah  /* black background, light red foreground */
     228                je ploop_end
    238229                stosw
    239                
    240                 /* Sanity check for the cursor on the last line */
    241230                inc %bx
    242                 cmp $2000, %bx
    243                 jb err_ploop
    244                
    245                 /* Scroll the screen (24 rows) */
    246                 movl %esi, %edx
    247                 movl $0xb80a0, %esi
    248                 movl $0xb8000, %edi
    249                 movl $1920, %ecx
    250                 rep movsw
    251                
    252                 /* Clear the 24th row */
    253                 xorl %eax, %eax
    254                 movl $80, %ecx
    255                 rep stosw
    256                
    257                 /* Go to row 24 */
    258                 movl %edx, %esi
    259                 movl $0xb8f00, %edi
    260                 movw $1920, %bx
    261                
    262                 jmp err_ploop
    263         err_ploop_end:
    264        
    265         /* Write bits 8 - 15 of the cursor address */
    266         movw $0x3d4, %dx
     231                jmp ploop
     232        ploop_end:
     233       
     234        movw $0x3d4, %dx          # write bits 8 - 15 of the cursor address
    267235        movb $0xe, %al
    268236        outb %al, %dx
     
    272240        outb %al, %dx
    273241       
    274         /* Write bits 0 - 7 of the cursor address */
    275         movw $0x3d4, %dx
     242        movw $0x3d4, %dx          # write bits 0 - 7 of the cursor address
    276243        movb $0xf, %al
    277244        outb %al, %dx
     
    286253                jmp hlt1
    287254
    288 /** Print string to EGA display (in light green).
    289  *
    290  * Should be called from 32 bit protected mode with paging
    291  * turned off. A stack space of at least 24 bytes is required,
    292  * but the function does not establish a stack frame.
    293  *
    294  * Macros such as pm_status and pm2_status take care that
    295  * this function is used only when CONFIG_EGA is enabled
    296  * and CONFIG_FB is disabled.
    297  *
    298  * @param %esi Pointer to the NULL-terminated string
    299  *             to be print.
    300  *
    301  */
    302 pm_early_puts:
    303         pushl %eax
    304         pushl %ebx
    305         pushl %ecx
    306         pushl %edx
    307         pushl %edi
    308        
    309         movl $0xb8000, %edi  /* base of EGA text mode memory */
    310         xorl %eax, %eax
    311        
    312         /* Read bits 8 - 15 of the cursor address */
    313         movw $0x3d4, %dx
    314         movb $0xe, %al
    315         outb %al, %dx
    316        
    317         movw $0x3d5, %dx
    318         inb %dx, %al
    319         shl $8, %ax
    320        
    321         /* Read bits 0 - 7 of the cursor address */
    322         movw $0x3d4, %dx
    323         movb $0xf, %al
    324         outb %al, %dx
    325        
    326         movw $0x3d5, %dx
    327         inb %dx, %al
    328        
    329         /* Sanity check for the cursor on screen */
    330         cmp $2000, %ax
    331         jb pm_puts_cursor_ok
    332        
    333                 movw $1998, %ax
    334        
    335         pm_puts_cursor_ok:
    336        
    337         movw %ax, %bx
    338         shl $1, %eax
    339         addl %eax, %edi
    340        
    341         pm_puts_ploop:
    342                 lodsb
    343                
    344                 cmp $0, %al
    345                 je pm_puts_ploop_end
    346                
    347                 movb $0x0a, %ah  /* black background, light green foreground */
    348                 stosw
    349                
    350                 /* Sanity check for the cursor on the last line */
    351                 inc %bx
    352                 cmp $2000, %bx
    353                 jb pm_puts_ploop
    354                
    355                 /* Scroll the screen (24 rows) */
    356                 movl %esi, %edx
    357                 movl $0xb80a0, %esi
    358                 movl $0xb8000, %edi
    359                 movl $1920, %ecx
    360                 rep movsw
    361                
    362                 /* Clear the 24th row */
    363                 xorl %eax, %eax
    364                 movl $80, %ecx
    365                 rep stosw
    366                
    367                 /* Go to row 24 */
    368                 movl %edx, %esi
    369                 movl $0xb8f00, %edi
    370                 movw $1920, %bx
    371                
    372                 jmp pm_puts_ploop
    373         pm_puts_ploop_end:
    374        
    375         /* Write bits 8 - 15 of the cursor address */
    376         movw $0x3d4, %dx
    377         movb $0xe, %al
    378         outb %al, %dx
    379        
    380         movw $0x3d5, %dx
    381         movb %bh, %al
    382         outb %al, %dx
    383        
    384         /* Write bits 0 - 7 of the cursor address */
    385         movw $0x3d4, %dx
    386         movb $0xf, %al
    387         outb %al, %dx
    388        
    389         movw $0x3d5, %dx
    390         movb %bl, %al
    391         outb %al, %dx
    392        
    393         popl %edi
    394         popl %edx
    395         popl %ecx
    396         popl %ebx
    397         popl %eax
    398        
    399         ret
    400 
    401 .code64
    402 
    403 .macro long_status msg
    404         pushq %rdi
    405         movq \msg, %rdi
    406         call early_puts
    407         popq %rdi
    408 .endm
    409 
    410 start64:
    411        
    412         /*
    413          * Long mode.
    414          */
    415        
    416         movq $(PA2KA(START_STACK)), %rsp
    417        
    418         /* Create the first stack frame */
    419         pushq $0
    420         movq %rsp, %rbp
    421        
    422         long_status $status_long
    423        
    424         /* Call arch_pre_main(grub_eax, grub_ebx) */
    425         xorq %rdi, %rdi
    426         movl grub_eax, %edi
    427         xorq %rsi, %rsi
    428         movl grub_ebx, %esi
    429        
    430         movabsq $arch_pre_main, %rax
    431         callq *%rax
    432        
    433         long_status $status_main
    434        
    435         /* Call main_bsp() */
    436         movabsq $main_bsp, %rax
    437         call *%rax
    438        
    439         /* Not reached */
    440         cli
    441         hlt0:
    442                 hlt
    443                 jmp hlt0
    444 
    445 /** Print string to EGA display.
    446  *
    447  * Should be called from long mode (with paging enabled
    448  * and stack established). This function is ABI compliant
    449  * (without red-zone).
    450  *
    451  * If CONFIG_EGA is undefined or CONFIG_FB is defined
    452  * then this function does nothing.
    453  *
    454  * @param %rdi Pointer to the NULL-terminated string
    455  *             to be printed.
    456  *
    457  */
    458 early_puts:
    459        
    460 #if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
    461        
    462         /* Prologue, save preserved registers */
    463         pushq %rbp
    464         movq %rsp, %rbp
    465         pushq %rbx
    466        
    467         movq %rdi, %rsi
    468         movq $(PA2KA(0xb8000)), %rdi  /* base of EGA text mode memory */
    469         xorq %rax, %rax
    470        
    471         /* Read bits 8 - 15 of the cursor address */
    472         movw $0x3d4, %dx
    473         movb $0xe, %al
    474         outb %al, %dx
    475        
    476         movw $0x3d5, %dx
    477         inb %dx, %al
    478         shl $8, %ax
    479        
    480         /* Read bits 0 - 7 of the cursor address */
    481         movw $0x3d4, %dx
    482         movb $0xf, %al
    483         outb %al, %dx
    484        
    485         movw $0x3d5, %dx
    486         inb %dx, %al
    487        
    488         /* Sanity check for the cursor on screen */
    489         cmp $2000, %ax
    490         jb early_puts_cursor_ok
    491        
    492                 movw $1998, %ax
    493        
    494         early_puts_cursor_ok:
    495        
    496         movw %ax, %bx
    497         shl $1, %rax
    498         addq %rax, %rdi
    499        
    500         early_puts_ploop:
    501                 lodsb
    502                
    503                 cmp $0, %al
    504                 je early_puts_ploop_end
    505                
    506                 movb $0x0e, %ah  /* black background, yellow foreground */
    507                 stosw
    508                
    509                 /* Sanity check for the cursor on the last line */
    510                 inc %bx
    511                 cmp $2000, %bx
    512                 jb early_puts_ploop
    513                
    514                 /* Scroll the screen (24 rows) */
    515                 movq %rsi, %rdx
    516                 movq $(PA2KA(0xb80a0)), %rsi
    517                 movq $(PA2KA(0xb8000)), %rdi
    518                 movq $1920, %rcx
    519                 rep movsw
    520                
    521                 /* Clear the 24th row */
    522                 xorq %rax, %rax
    523                 movq $80, %rcx
    524                 rep stosw
    525                
    526                 /* Go to row 24 */
    527                 movq %rdx, %rsi
    528                 movq $(PA2KA(0xb8f00)), %rdi
    529                 movw $1920, %bx
    530                
    531                 jmp early_puts_ploop
    532         early_puts_ploop_end:
    533        
    534         /* Write bits 8 - 15 of the cursor address */
    535         movw $0x3d4, %dx
    536         movb $0xe, %al
    537         outb %al, %dx
    538        
    539         movw $0x3d5, %dx
    540         movb %bh, %al
    541         outb %al, %dx
    542        
    543         /* Write bits 0 - 7 of the cursor address */
    544         movw $0x3d4, %dx
    545         movb $0xf, %al
    546         outb %al, %dx
    547        
    548         movw $0x3d5, %dx
    549         movb %bl, %al
    550         outb %al, %dx
    551        
    552         /* Epilogue, restore preserved registers */
    553         popq %rbx
    554         leave
    555        
    556 #endif
    557        
    558         ret
    559 
    560255#include "vesa_real.inc"
    561256
    562257.section K_INI_PTLS, "aw", @progbits
    563258
    564 /** Generate initial page table contents.
    565  *
    566  * @param cnt Number of entries to generate. Must be multiple of 8.
    567  * @param g   Number of GB that will be added to the mapping.
    568  *
    569  */
     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#
    570264.macro ptl2gen cnt g
    571265        .if \cnt
     
    582276.endm
    583277
    584 /* Page table for pages in the 1st gigabyte. */
     278# Page table for pages in the 1st gigabyte.
    585279.align 4096
    586280ptl_2_0g:
    587281        ptl2gen 512 0
    588282
    589 /* Page table for pages in the 2nd gigabyte. */
     283# Page table for pages in the 2nd gigabyte.
    590284.align 4096
    591285ptl_2_1g:
    592286        ptl2gen 512 1
    593287
    594 /* Page table for pages in the 3rd gigabyte. */
     288# Page table for pages in the 3rd gigabyte.
    595289.align 4096
    596290ptl_2_2g:
    597291        ptl2gen 512 2
    598292
    599 /* Page table for pages in the 4th gigabyte. */
     293# Page table for pages in the 4th gigabyte.
    600294.align 4096
    601295ptl_2_3g:
    602296        ptl2gen 512 3
    603297
    604 /* Page table for pages in the 5th gigabyte. */
     298# Page table for pages in the 5th gigabyte.
    605299.align 4096
    606300ptl_2_4g:
    607301        ptl2gen 512 3
    608302
    609 /* Page table for pages in the 6th gigabyte. */
     303# Page table for pages in the 6th gigabyte.
    610304.align 4096
    611305ptl_2_5g:
    612306        ptl2gen 512 3
    613307
    614 /* Page table for pages in the 7th gigabyte. */
     308# Page table for pages in the 7th gigabyte.
    615309.align 4096
    616310ptl_2_6g:
    617311        ptl2gen 512 3
    618312
    619 /* Page table for pages in the 8th gigabyte. */
     313# Page table for pages in the 8th gigabyte.
    620314.align 4096
    621315ptl_2_7g:
     
    624318.align 4096
    625319ptl_1:
    626         /* Identity mapping for [0; 8G) */
     320        # Identity mapping for [0; 8G)
    627321        .quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
    628322        .quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT)
     
    656350        .long 0
    657351
    658 err_extended_cpuid:
     352extended_cpuid_msg:
    659353        .asciz "Error: Extended CPUID not supported -- CPU is not 64-bit. System halted."
    660 err_long_mode:
     354long_mode_msg:
    661355        .asciz "Error: 64-bit long mode not supported. System halted."
    662 err_noexecute:
     356noexecute_msg:
    663357        .asciz "Error: No-execute pages not supported. System halted."
    664 err_fx:
     358fx_msg:
    665359        .asciz "Error: FXSAVE/FXRESTORE instructions not supported. System halted."
    666 err_sse2:
     360sse2_msg:
    667361        .asciz "Error: SSE2 instructions not supported. System halted."
    668 
    669 status_prot:
    670         .asciz "[prot] "
    671 status_vesa_copy:
    672         .asciz "[vesa_copy] "
    673 status_grub_cmdline:
    674         .asciz "[grub_cmdline] "
    675 status_vesa_real:
    676         .asciz "[vesa_real] "
    677 status_prot2:
    678         .asciz "[prot2] "
    679 status_long:
    680         .asciz "[long] "
    681 status_main:
    682         .asciz "[main] "
  • kernel/arch/amd64/src/boot/vesa_ret.inc

    re2ea4ab1 r4d1be48  
    11.code32
    22vesa_init_protected:
    3         cld
    4        
    5         /* Initialize stack pointer */
    6         movl $START_STACK, %esp
    7        
    8         /* Kernel data + stack */
    93        movw $gdtselector(KDATA_DES), %cx
    104        movw %cx, %es
    11         movw %cx, %ds
     5        movw %cx, %ds                       # kernel data + stack
    126        movw %cx, %ss
    137       
    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          */
     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        #
    1812       
    1913        movw $gdtselector(UDATA_DES), %cx
     
    2115        movw %cx, %gs
    2216       
     17        movl $START_STACK, %esp             # initialize stack pointer
     18       
    2319        jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point
  • kernel/arch/amd64/src/debugger.c

    re2ea4ab1 r4d1be48  
    230230                                return;
    231231                       
    232                         printf("*** Found ZERO on address %" PRIp " (slot %d) ***\n",
     232                        printf("*** Found ZERO on address %lx (slot %d) ***\n",
    233233                            breakpoints[slot].address, slot);
    234234                } else {
    235                         printf("Data watchpoint - new data: %" PRIp "\n",
     235                        printf("Data watchpoint - new data: %lx\n",
    236236                            *((unative_t *) breakpoints[slot].address));
    237237                }
    238238        }
    239239       
    240         printf("Reached breakpoint %d:%" PRIp " (%s)\n", slot, getip(istate),
     240        printf("Reached breakpoint %d:%lx (%s)\n", slot, getip(istate),
    241241            symtab_fmt_name_lookup(getip(istate)));
    242242       
  • kernel/arch/arm32/src/asm.S

    re2ea4ab1 r4d1be48  
    1 /*
    2  * Copyright (c) 2007 Michal Kebrt
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  *
    9  * - Redistributions of source code must retain the above copyright
    10  *   notice, this list of conditions and the following disclaimer.
    11  * - Redistributions in binary form must reproduce the above copyright
    12  *   notice, this list of conditions and the following disclaimer in the
    13  *   documentation and/or other materials provided with the distribution.
    14  * - The name of the author may not be used to endorse or promote products
    15  *   derived from this software without specific prior written permission.
    16  *
    17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    27  */
     1#
     2# Copyright (c) 2007 Michal Kebrt
     3# All rights reserved.
     4#
     5# Redistribution and use in source and binary forms, with or without
     6# modification, are permitted provided that the following conditions
     7# are met:
     8#
     9# - Redistributions of source code must retain the above copyright
     10#   notice, this list of conditions and the following disclaimer.
     11# - Redistributions in binary form must reproduce the above copyright
     12#   notice, this list of conditions and the following disclaimer in the
     13#   documentation and/or other materials provided with the distribution.
     14# - The name of the author may not be used to endorse or promote products
     15#   derived from this software without specific prior written permission.
     16#
     17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27#
    2828
     29       
    2930.text
    3031
     
    3637.global memcpy_from_uspace_failover_address
    3738.global memcpy_to_uspace_failover_address
    38 .global early_putchar
    3939
    4040memsetb:
     
    4747memcpy_from_uspace:
    4848memcpy_to_uspace:
    49         add r3, r1, #3
    50         bic r3, r3, #3
    51         cmp r1, r3
    52         stmdb sp!, {r4, r5, lr}
    53         mov r5, r0 /* save dst */
    54         beq 4f
    55        
    56         1:
    57                 cmp r2, #0
    58                 movne ip, #0
    59                 beq 3f
    60        
    61         2:
    62                 ldrb r3, [ip, r1]
    63                 strb r3, [ip, r0]
    64                 add ip, ip, #1
    65                 cmp ip, r2
    66                 bne 2b
    67        
    68         3:
    69                 mov r0, r5
    70                 ldmia sp!, {r4, r5, pc}
    71        
    72         4:
    73                 add r3, r0, #3
    74                 bic r3, r3, #3
    75                 cmp r0, r3
    76                 bne 1b
    77                 movs r4, r2, lsr #2
    78                 moveq lr, r4
    79                 beq 6f
    80                 mov lr, #0
    81                 mov ip, lr
    82        
    83         5:
    84                 ldr r3, [ip, r1]
    85                 add lr, lr, #1
    86                 cmp lr, r4
    87                 str r3, [ip, r0]
    88                 add ip, ip, #4
    89                 bne 5b
    90        
    91         6:
    92                 ands r4, r2, #3
    93                 beq 3b
    94                 mov r3, lr, lsl #2
    95                 add r0, r3, r0
    96                 add ip, r3, r1
    97                 mov r2, #0
    98        
    99         7:
    100                 ldrb r3, [r2, ip]
    101                 strb r3, [r2, r0]
    102                 add r2, r2, #1
    103                 cmp r2, r4
    104                 bne 7b
    105                 b 3b
     49        add     r3, r1, #3
     50        bic     r3, r3, #3
     51        cmp     r1, r3
     52        stmdb   sp!, {r4, r5, lr}
     53        mov     r5, r0                  /* save dst */
     54        beq     4f
     551:
     56        cmp     r2, #0
     57        movne   ip, #0
     58        beq     3f
     592:
     60        ldrb    r3, [ip, r1]
     61        strb    r3, [ip, r0]
     62        add     ip, ip, #1
     63        cmp     ip, r2
     64        bne     2b
     653:
     66        mov     r0, r5
     67        ldmia   sp!, {r4, r5, pc}
     684:
     69        add     r3, r0, #3
     70        bic     r3, r3, #3
     71        cmp     r0, r3
     72        bne     1b
     73        movs    r4, r2, lsr #2
     74        moveq   lr, r4
     75        beq     6f
     76        mov     lr, #0
     77        mov     ip, lr
     785:
     79        ldr     r3, [ip, r1]
     80        add     lr, lr, #1
     81        cmp     lr, r4
     82        str     r3, [ip, r0]
     83        add     ip, ip, #4
     84        bne     5b
     856:
     86        ands    r4, r2, #3
     87        beq     3b
     88        mov     r3, lr, lsl #2
     89        add     r0, r3, r0
     90        add     ip, r3, r1
     91        mov     r2, #0
     927:
     93        ldrb    r3, [r2, ip]
     94        strb    r3, [r2, r0]
     95        add     r2, r2, #1
     96        cmp     r2, r4
     97        bne     7b
     98        b       3b
    10699
    107100memcpy_from_uspace_failover_address:
    108101memcpy_to_uspace_failover_address:
    109         mov r0, #0
    110         ldmia sp!, {r4, r5, pc}
    111 
    112 early_putchar:
    113         mov pc, lr
     102        mov     r0, #0
     103        ldmia   sp!, {r4, r5, pc}
  • kernel/arch/ia32/include/smp/apic.h

    re2ea4ab1 r4d1be48  
    347347
    348348extern uint32_t apic_id_mask;
    349 extern uint8_t bsp_l_apic;
    350349
    351350extern void apic_init(void);
     
    356355extern int l_apic_send_init_ipi(uint8_t);
    357356extern void l_apic_debug(void);
     357extern uint8_t l_apic_id(void);
    358358
    359359extern uint32_t io_apic_read(uint8_t);
  • kernel/arch/ia32/src/asm.S

    re2ea4ab1 r4d1be48  
    1 /*
    2  * Copyright (c) 2001 Jakub Jermar
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  *
    9  * - Redistributions of source code must retain the above copyright
    10  *   notice, this list of conditions and the following disclaimer.
    11  * - Redistributions in binary form must reproduce the above copyright
    12  *   notice, this list of conditions and the following disclaimer in the
    13  *   documentation and/or other materials provided with the distribution.
    14  * - The name of the author may not be used to endorse or promote products
    15  *   derived from this software without specific prior written permission.
    16  *
    17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    27  */
    28 
    29 /** Very low and hardware-level functions
    30  *
    31  */
    32 
    33 /**
    34  * Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int
    35  * has no error word  and 1 means interrupt with error word
    36  *
    37  */
    38 #define ERROR_WORD_INTERRUPT_LIST  0x00027d00
    39 
    40 #include <arch/pm.h>
    41 #include <arch/mm/page.h>
     1#
     2# Copyright (c) 2001-2004 Jakub Jermar
     3# All rights reserved.
     4#
     5# Redistribution and use in source and binary forms, with or without
     6# modification, are permitted provided that the following conditions
     7# are met:
     8#
     9# - Redistributions of source code must retain the above copyright
     10#   notice, this list of conditions and the following disclaimer.
     11# - Redistributions in binary form must reproduce the above copyright
     12#   notice, this list of conditions and the following disclaimer in the
     13#   documentation and/or other materials provided with the distribution.
     14# - The name of the author may not be used to endorse or promote products
     15#   derived from this software without specific prior written permission.
     16#
     17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27#
     28
     29## very low and hardware-level functions
     30
     31# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error
     32# word and 1 means interrupt with error word
     33#define ERROR_WORD_INTERRUPT_LIST 0x00027d00
    4234
    4335.text
     36
    4437.global paging_on
    4538.global enable_l_apic_in_msr
     
    5245.global memcpy_to_uspace
    5346.global memcpy_to_uspace_failover_address
    54 .global early_putchar
    55 
    56 /* Wrapper for generic memsetb */
     47
     48
     49# Wrapper for generic memsetb
    5750memsetb:
    5851        jmp _memsetb
    5952
    60 /* Wrapper for generic memsetw */
     53# Wrapper for generic memsetw
    6154memsetw:
    6255        jmp _memsetw
    6356
    64 #define MEMCPY_DST   4
    65 #define MEMCPY_SRC   8
    66 #define MEMCPY_SIZE  12
     57
     58#define MEMCPY_DST      4
     59#define MEMCPY_SRC      8
     60#define MEMCPY_SIZE     12
    6761
    6862/** Copy memory to/from userspace.
     
    7468 * or copy_to_uspace().
    7569 *
    76  * @param MEMCPY_DST(%esp)  Destination address.
    77  * @param MEMCPY_SRC(%esp)  Source address.
    78  * @param MEMCPY_SIZE(%esp) Size.
     70 * @param MEMCPY_DST(%esp)      Destination address.
     71 * @param MEMCPY_SRC(%esp)      Source address.
     72 * @param MEMCPY_SIZE(%esp)     Size.
    7973 *
    8074 * @return MEMCPY_DST(%esp) on success and 0 on failure.
    81  *
    8275 */
    8376memcpy:
    8477memcpy_from_uspace:
    8578memcpy_to_uspace:
    86         movl %edi, %edx  /* save %edi */
    87         movl %esi, %eax  /* save %esi */
     79        movl %edi, %edx                 /* save %edi */
     80        movl %esi, %eax                 /* save %esi */
    8881       
    8982        movl MEMCPY_SIZE(%esp), %ecx
    90         shrl $2, %ecx  /* size / 4 */
     83        shrl $2, %ecx                   /* size / 4 */
    9184       
    9285        movl MEMCPY_DST(%esp), %edi
    9386        movl MEMCPY_SRC(%esp), %esi
    9487       
    95         /* Copy whole words */
    96         rep movsl
    97        
     88        rep movsl                       /* copy whole words */
     89
    9890        movl MEMCPY_SIZE(%esp), %ecx
    99         andl $3, %ecx  /* size % 4 */
     91        andl $3, %ecx                   /* size % 4 */
    10092        jz 0f
    10193       
    102         /* Copy the rest byte by byte */
    103         rep movsb
    104        
    105         0:
    106        
    107                 movl %edx, %edi
    108                 movl %eax, %esi
    109                
    110                 /* MEMCPY_DST(%esp), success */
    111                 movl MEMCPY_DST(%esp), %eax
    112                 ret
    113 
     94        rep movsb                       /* copy the rest byte by byte */
     95
     960:
     97        movl %edx, %edi
     98        movl %eax, %esi
     99        movl MEMCPY_DST(%esp), %eax     /* MEMCPY_DST(%esp), success */
     100        ret
     101       
    114102/*
    115103 * We got here from as_page_fault() after the memory operations
     
    120108        movl %edx, %edi
    121109        movl %eax, %esi
    122        
    123         /* Return 0, failure */
    124         xorl %eax, %eax
     110        xorl %eax, %eax                 /* return 0, failure */
    125111        ret
    126112
    127 /** Turn paging on
    128  *
    129  * Enable paging and write-back caching in CR0.
    130  *
    131  */
     113## Turn paging on
     114#
     115# Enable paging and write-back caching in CR0.
     116#
    132117paging_on:
    133118        movl %cr0, %edx
    134         orl $(1 << 31), %edx  /* paging on */
    135        
    136         /* Clear Cache Disable and not Write Though */
     119        orl $(1 << 31), %edx            # paging on
     120        # clear Cache Disable and not Write Though
    137121        andl $~((1 << 30) | (1 << 29)), %edx
    138         movl %edx, %cr0
     122        movl %edx,%cr0
    139123        jmp 0f
    140        
    141         0:
    142                 ret
    143 
    144 /** Enable local APIC
    145  *
    146  * Enable local APIC in MSR.
    147  *
    148  */
     1240:
     125        ret
     126
     127
     128## Enable local APIC
     129#
     130# Enable local APIC in MSR.
     131#
    149132enable_l_apic_in_msr:
    150133        movl $0x1b, %ecx
     
    155138        ret
    156139
    157 /** Clear nested flag
    158  *
    159  */
     140# Clear nested flag
     141# overwrites %ecx
    160142.macro CLEAR_NT_FLAG
    161143        pushfl
    162144        andl $0xffffbfff, (%esp)
    163145        popfl
    164 .endm
     146.endm   
    165147
    166148/*
     
    176158sysenter_handler:
    177159        sti
    178         pushl %ebp  /* remember user stack */
    179         pushl %edi  /* remember return user address */
    180        
    181         xorl %ebp, %ebp  /* stop stack traces here */
    182        
    183         pushl %gs  /* remember TLS */
    184        
    185         pushl %eax     /* syscall number */
    186         subl $8, %esp  /* unused sixth and fifth argument */
    187         pushl %esi     /* fourth argument */
    188         pushl %ebx     /* third argument */
    189         pushl %ecx     /* second argument */
    190         pushl %edx     /* first argument */
    191        
     160        pushl %ebp      # remember user stack
     161        pushl %edi      # remember return user address
     162
     163        xorl %ebp, %ebp # stop stack traces here
     164
     165        pushl %gs       # remember TLS
     166
     167        pushl %eax      # syscall number
     168        subl $8, %esp   # unused sixth and fifth argument
     169        pushl %esi      # fourth argument
     170        pushl %ebx      # third argument
     171        pushl %ecx      # second argument
     172        pushl %edx      # first argument
     173
    192174        movw $16, %ax
    193175        movw %ax, %ds
    194176        movw %ax, %es
    195        
     177
    196178        cld
    197179        call syscall_handler
    198         addl $28, %esp  /* remove arguments from stack */
    199        
    200         pop %gs  /* restore TLS */
    201        
    202         pop %edx  /* prepare return EIP for SYSEXIT */
    203         pop %ecx  /* prepare userspace ESP for SYSEXIT */
    204        
    205         sysexit   /* return to userspace */
    206 
    207 #define ISTATE_OFFSET_EAX         0
    208 #define ISTATE_OFFSET_EBX         4
    209 #define ISTATE_OFFSET_ECX         8
    210 #define ISTATE_OFFSET_EDX         12
    211 #define ISTATE_OFFSET_EDI         16
    212 #define ISTATE_OFFSET_ESI         20
    213 #define ISTATE_OFFSET_EBP         24
    214 #define ISTATE_OFFSET_EBP_FRAME   28
    215 #define ISTATE_OFFSET_EIP_FRAME   32
    216 #define ISTATE_OFFSET_GS          36
    217 #define ISTATE_OFFSET_FS          40
    218 #define ISTATE_OFFSET_ES          44
    219 #define ISTATE_OFFSET_DS          48
    220 #define ISTATE_OFFSET_ERROR_WORD  52
    221 #define ISTATE_OFFSET_EIP         56
    222 #define ISTATE_OFFSET_CS          60
    223 #define ISTATE_OFFSET_EFLAGS      64
    224 #define ISTATE_OFFSET_ESP         68
    225 #define ISTATE_OFFSET_SS          72
     180        addl $28, %esp  # remove arguments from stack
     181
     182        pop %gs         # restore TLS
     183
     184        pop %edx        # prepare return EIP for SYSEXIT
     185        pop %ecx        # prepare userspace ESP for SYSEXIT
     186
     187        sysexit         # return to userspace
     188
     189
     190#define ISTATE_OFFSET_EAX               0
     191#define ISTATE_OFFSET_EBX               4
     192#define ISTATE_OFFSET_ECX               8
     193#define ISTATE_OFFSET_EDX               12
     194#define ISTATE_OFFSET_EDI               16
     195#define ISTATE_OFFSET_ESI               20
     196#define ISTATE_OFFSET_EBP               24
     197#define ISTATE_OFFSET_EBP_FRAME         28
     198#define ISTATE_OFFSET_EIP_FRAME         32
     199#define ISTATE_OFFSET_GS                36
     200#define ISTATE_OFFSET_FS                40
     201#define ISTATE_OFFSET_ES                44
     202#define ISTATE_OFFSET_DS                48
     203#define ISTATE_OFFSET_ERROR_WORD        52
     204#define ISTATE_OFFSET_EIP               56
     205#define ISTATE_OFFSET_CS                60
     206#define ISTATE_OFFSET_EFLAGS            64
     207#define ISTATE_OFFSET_ESP               68
     208#define ISTATE_OFFSET_SS                72
    226209
    227210/*
    228  * Size of the istate structure without the hardware-saved part
    229  * and without the error word.
     211 * Size of the istate structure without the hardware-saved part and without the
     212 * error word.
    230213 */
    231 #define ISTATE_SOFT_SIZE  52
    232 
    233 /** Declare interrupt handlers
    234  *
    235  * Declare interrupt handlers for n interrupt
    236  * vectors starting at vector i.
    237  *
    238  * The handlers setup data segment registers
    239  * and call exc_dispatch().
    240  *
    241  */
    242 #define INTERRUPT_ALIGN  256
    243 
     214#define ISTATE_SOFT_SIZE                52
     215
     216## Declare interrupt handlers
     217#
     218# Declare interrupt handlers for n interrupt
     219# vectors starting at vector i.
     220#
     221# The handlers setup data segment registers
     222# and call exc_dispatch().
     223#
     224#define INTERRUPT_ALIGN 256
    244225.macro handler i n
    245         .ifeq \i - 0x30
    246                 /* Syscall handler */
    247                 pushl %ds
    248                 pushl %es
    249                 pushl %fs
    250                 pushl %gs
    251                
    252                 /*
    253                  * Push syscall arguments onto the stack
    254                  *
    255                  * NOTE: The idea behind the order of arguments passed
    256                  *       in registers is to use all scratch registers
    257                  *       first and preserved registers next. An optimized
    258                  *       libc syscall wrapper can make use of this setup.
    259                  *
    260                  */
    261                 pushl %eax
    262                 pushl %ebp
    263                 pushl %edi
    264                 pushl %esi
    265                 pushl %ebx
    266                 pushl %ecx
    267                 pushl %edx
    268                
    269                 /* We must fill the data segment registers */
    270                 movw $16, %ax
    271                 movw %ax, %ds
    272                 movw %ax, %es
    273                
    274                 xorl %ebp, %ebp
    275                
    276                 cld
    277                 sti
    278                
    279                 /* Call syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) */
    280                 call syscall_handler
    281                 cli
    282                
    283                 movl 20(%esp), %ebp  /* restore EBP */
    284                 addl $28, %esp       /* clean-up of parameters */
    285                
    286                 popl %gs
    287                 popl %fs
    288                 popl %es
    289                 popl %ds
    290                
    291                 CLEAR_NT_FLAG
    292                 iret
    293         .else
    294                 /*
    295                  * This macro distinguishes between two versions of ia32
    296                  * exceptions. One version has error word and the other
    297                  * does not have it. The latter version fakes the error
    298                  * word on the stack so that the handlers and istate_t
    299                  * can be the same for both types.
    300                  */
    301                 .iflt \i - 32
    302                         .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
    303                                 /*
    304                                  * Exception with error word: do nothing
    305                                  */
    306                         .else
    307                                 /*
    308                                  * Exception without error word: fake up one
    309                                  */
    310                                 pushl $0
    311                         .endif
    312                 .else
    313                         /*
    314                          * Interrupt: fake up one
    315                          */
    316                         pushl $0
    317                 .endif
    318                
    319                 subl $ISTATE_SOFT_SIZE, %esp
    320                
    321                 /*
    322                  * Save the general purpose registers.
    323                  */
    324                 movl %eax, ISTATE_OFFSET_EAX(%esp)
    325                 movl %ebx, ISTATE_OFFSET_EBX(%esp)
    326                 movl %ecx, ISTATE_OFFSET_ECX(%esp)
    327                 movl %edx, ISTATE_OFFSET_EDX(%esp)
    328                 movl %edi, ISTATE_OFFSET_EDI(%esp)
    329                 movl %esi, ISTATE_OFFSET_ESI(%esp)
    330                 movl %ebp, ISTATE_OFFSET_EBP(%esp)
    331                
    332                 /*
    333                  * Save the selector registers.
    334                  */
    335                 movl %gs, %eax
    336                 movl %fs, %ebx
    337                 movl %es, %ecx
    338                 movl %ds, %edx
    339                
    340                 movl %eax, ISTATE_OFFSET_GS(%esp)
    341                 movl %ebx, ISTATE_OFFSET_FS(%esp)
    342                 movl %ecx, ISTATE_OFFSET_ES(%esp)
    343                 movl %edx, ISTATE_OFFSET_DS(%esp)
    344                
    345                 /*
    346                  * Switch to kernel selectors.
    347                  */
    348                 movl $16, %eax
    349                 movl %eax, %ds
    350                 movl %eax, %es
    351                
    352                 /*
    353                  * Imitate a regular stack frame linkage.
    354                  * Stop stack traces here if we came from userspace.
    355                  */
    356                 cmpl $8, ISTATE_OFFSET_CS(%esp)
    357                 jz 0f
    358                 xorl %ebp, %ebp
    359                
    360                 0:
    361                
    362                         movl %ebp, ISTATE_OFFSET_EBP_FRAME(%esp)
    363                         movl ISTATE_OFFSET_EIP(%esp), %eax
    364                         movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp)
    365                         leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp
    366                        
    367                         cld
    368                        
    369                         pushl %esp   /* pass istate address */
    370                         pushl $(\i)  /* pass intnum */
    371                        
    372                         /* Call exc_dispatch(intnum, istate) */
    373                         call exc_dispatch
    374                        
    375                         addl $8, %esp  /* clear arguments from the stack */
    376                        
    377                         CLEAR_NT_FLAG
    378                        
    379                         /*
    380                          * Restore the selector registers.
    381                          */
    382                         movl ISTATE_OFFSET_GS(%esp), %eax
    383                         movl ISTATE_OFFSET_FS(%esp), %ebx
    384                         movl ISTATE_OFFSET_ES(%esp), %ecx
    385                         movl ISTATE_OFFSET_DS(%esp), %edx
    386                        
    387                         movl %eax, %gs
    388                         movl %ebx, %fs
    389                         movl %ecx, %es
    390                         movl %edx, %ds
    391                        
    392                         /*
    393                          * Restore the scratch registers and the preserved
    394                          * registers the handler cloberred itself
    395                          * (i.e. EBX and EBP).
    396                          */
    397                         movl ISTATE_OFFSET_EAX(%esp), %eax
    398                         movl ISTATE_OFFSET_EBX(%esp), %ebx
    399                         movl ISTATE_OFFSET_ECX(%esp), %ecx
    400                         movl ISTATE_OFFSET_EDX(%esp), %edx
    401                         movl ISTATE_OFFSET_EBP(%esp), %ebp
    402                        
    403                         addl $(ISTATE_SOFT_SIZE + 4), %esp
    404                         iret
    405                
    406         .endif
    407        
    408         .align INTERRUPT_ALIGN
    409         .if (\n - \i) - 1
    410                 handler "(\i + 1)", \n
    411         .endif
     226       
     227.ifeq \i - 0x30     # Syscall handler
     228        pushl %ds
     229        pushl %es
     230        pushl %fs
     231        pushl %gs
     232               
     233        #
     234        # Push syscall arguments onto the stack
     235        #
     236        # NOTE: The idea behind the order of arguments passed in registers is to
     237        #       use all scratch registers first and preserved registers next.
     238        #       An optimized libc syscall wrapper can make use of this setup.
     239        #
     240        pushl %eax
     241        pushl %ebp
     242        pushl %edi
     243        pushl %esi
     244        pushl %ebx
     245        pushl %ecx
     246        pushl %edx
     247               
     248        # we must fill the data segment registers
     249        movw $16, %ax
     250        movw %ax, %ds
     251        movw %ax, %es
     252       
     253        xorl %ebp, %ebp
     254
     255        cld
     256        sti
     257        # syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax)
     258        call syscall_handler
     259        cli
     260
     261        movl 20(%esp), %ebp     # restore EBP
     262        addl $28, %esp          # clean-up of parameters
     263               
     264        popl %gs
     265        popl %fs
     266        popl %es
     267        popl %ds
     268               
     269        CLEAR_NT_FLAG
     270        iret
     271.else
     272        /*
     273         * This macro distinguishes between two versions of ia32 exceptions.
     274         * One version has error word and the other does not have it.
     275         * The latter version fakes the error word on the stack so that the
     276         * handlers and istate_t can be the same for both types.
     277         */
     278.iflt \i - 32
     279.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
     280        #
     281        # Exception with error word: do nothing
     282        #
     283.else
     284        #
     285        # Exception without error word: fake up one
     286        #
     287        pushl $0
     288.endif
     289.else
     290        #
     291        # Interrupt: fake up one
     292        #
     293        pushl $0
     294.endif
     295               
     296        subl $ISTATE_SOFT_SIZE, %esp
     297
     298        #
     299        # Save the general purpose registers.
     300        #
     301        movl %eax, ISTATE_OFFSET_EAX(%esp)
     302        movl %ebx, ISTATE_OFFSET_EBX(%esp)
     303        movl %ecx, ISTATE_OFFSET_ECX(%esp)
     304        movl %edx, ISTATE_OFFSET_EDX(%esp)
     305        movl %edi, ISTATE_OFFSET_EDI(%esp)
     306        movl %esi, ISTATE_OFFSET_ESI(%esp)
     307        movl %ebp, ISTATE_OFFSET_EBP(%esp)
     308       
     309        #
     310        # Save the selector registers.
     311        #
     312        movl %gs, %eax
     313        movl %fs, %ebx
     314        movl %es, %ecx
     315        movl %ds, %edx
     316
     317        movl %eax, ISTATE_OFFSET_GS(%esp)
     318        movl %ebx, ISTATE_OFFSET_FS(%esp)
     319        movl %ecx, ISTATE_OFFSET_ES(%esp)
     320        movl %edx, ISTATE_OFFSET_DS(%esp)
     321
     322        #
     323        # Switch to kernel selectors.
     324        #
     325        movl $16, %eax
     326        movl %eax, %ds
     327        movl %eax, %es
     328               
     329        #
     330        # Imitate a regular stack frame linkage.
     331        # Stop stack traces here if we came from userspace.
     332        #
     333        cmpl $8, ISTATE_OFFSET_CS(%esp)
     334        jz 0f
     335        xorl %ebp, %ebp
     3360:      movl %ebp, ISTATE_OFFSET_EBP_FRAME(%esp)
     337        movl ISTATE_OFFSET_EIP(%esp), %eax
     338        movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp)
     339        leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp
     340
     341        cld
     342
     343        pushl %esp          # pass istate address
     344        pushl $(\i)         # pass intnum
     345        call exc_dispatch   # exc_dispatch(intnum, istate)
     346        addl $8, %esp       # Clear arguments from the stack
     347               
     348        CLEAR_NT_FLAG
     349       
     350        #
     351        # Restore the selector registers.
     352        #
     353        movl ISTATE_OFFSET_GS(%esp), %eax
     354        movl ISTATE_OFFSET_FS(%esp), %ebx
     355        movl ISTATE_OFFSET_ES(%esp), %ecx
     356        movl ISTATE_OFFSET_DS(%esp), %edx
     357
     358        movl %eax, %gs
     359        movl %ebx, %fs
     360        movl %ecx, %es
     361        movl %edx, %ds
     362
     363        #
     364        # Restore the scratch registers and the preserved registers the handler
     365        # cloberred itself (i.e. EBX and EBP).
     366        #
     367        movl ISTATE_OFFSET_EAX(%esp), %eax
     368        movl ISTATE_OFFSET_EBX(%esp), %ebx
     369        movl ISTATE_OFFSET_ECX(%esp), %ecx
     370        movl ISTATE_OFFSET_EDX(%esp), %edx
     371        movl ISTATE_OFFSET_EBP(%esp), %ebp
     372       
     373        addl $(ISTATE_SOFT_SIZE + 4), %esp
     374        iret
     375.endif
     376       
     377.align INTERRUPT_ALIGN
     378.if (\n- \i) - 1
     379        handler "(\i + 1)", \n
     380.endif
    412381.endm
    413382
    414 /* Keep in sync with pm.h! */
    415 #define IDT_ITEMS  64
    416 
     383# keep in sync with pm.h !!!
     384IDT_ITEMS = 64
    417385.align INTERRUPT_ALIGN
    418386interrupt_handlers:
    419         h_start:
    420                 handler 0 IDT_ITEMS
    421         h_end:
    422 
    423 /** Print Unicode character to EGA display.
    424  *
    425  * If CONFIG_EGA is undefined or CONFIG_FB is defined
    426  * then this function does nothing.
    427  *
    428  * Since the EGA can only display Extended ASCII (usually
    429  * ISO Latin 1) characters, some of the Unicode characters
    430  * can be displayed in a wrong way. Only the newline character
    431  * is interpreted, all other characters (even unprintable) are
    432  * printed verbatim.
    433  *
    434  * @param %ebp+0x08 Unicode character to be printed.
    435  *
    436  */
    437 early_putchar:
    438        
    439 #if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
    440        
    441         /* Prologue, save preserved registers */
    442         pushl %ebp
    443         movl %esp, %ebp
    444         pushl %ebx
    445         pushl %esi
    446         pushl %edi
    447        
    448         movl $(PA2KA(0xb8000)), %edi  /* base of EGA text mode memory */
    449         xorl %eax, %eax
    450        
    451         /* Read bits 8 - 15 of the cursor address */
    452         movw $0x3d4, %dx
    453         movb $0xe, %al
    454         outb %al, %dx
    455        
    456         movw $0x3d5, %dx
    457         inb %dx, %al
    458         shl $8, %ax
    459        
    460         /* Read bits 0 - 7 of the cursor address */
    461         movw $0x3d4, %dx
    462         movb $0xf, %al
    463         outb %al, %dx
    464        
    465         movw $0x3d5, %dx
    466         inb %dx, %al
    467        
    468         /* Sanity check for the cursor on screen */
    469         cmp $2000, %ax
    470         jb early_putchar_cursor_ok
    471        
    472                 movw $1998, %ax
    473        
    474         early_putchar_cursor_ok:
    475        
    476         movw %ax, %bx
    477         shl $1, %eax
    478         addl %eax, %edi
    479        
    480         movl 0x08(%ebp), %eax
    481        
    482         cmp $0x0a, %al
    483         jne early_putchar_print
    484        
    485                 /* Interpret newline */
    486                
    487                 movw %bx, %ax  /* %bx -> %dx:%ax */
    488                 xorw %dx, %dx
    489                
    490                 movw $80, %cx
    491                 idivw %cx, %ax  /* %dx = %bx % 80 */
    492                
    493                 /* %bx <- %bx + 80 - (%bx % 80) */
    494                 addw %cx, %bx
    495                 subw %dx, %bx
    496                
    497                 jmp early_putchar_newline
    498        
    499         early_putchar_print:
    500        
    501                 /* Print character */
    502                
    503                 movb $0x0e, %ah  /* black background, yellow foreground */
    504                 stosw
    505                 inc %bx
    506        
    507         early_putchar_newline:
    508        
    509         /* Sanity check for the cursor on the last line */
    510         cmp $2000, %bx
    511         jb early_putchar_no_scroll
    512        
    513                 /* Scroll the screen (24 rows) */
    514                 movl $(PA2KA(0xb80a0)), %esi
    515                 movl $(PA2KA(0xb8000)), %edi
    516                 movl $1920, %ecx
    517                 rep movsw
    518                
    519                 /* Clear the 24th row */
    520                 xorl %eax, %eax
    521                 movl $80, %ecx
    522                 rep stosw
    523                
    524                 /* Go to row 24 */
    525                 movw $1920, %bx
    526        
    527         early_putchar_no_scroll:
    528        
    529         /* Write bits 8 - 15 of the cursor address */
    530         movw $0x3d4, %dx
    531         movb $0xe, %al
    532         outb %al, %dx
    533        
    534         movw $0x3d5, %dx
    535         movb %bh, %al
    536         outb %al, %dx
    537        
    538         /* Write bits 0 - 7 of the cursor address */
    539         movw $0x3d4, %dx
    540         movb $0xf, %al
    541         outb %al, %dx
    542        
    543         movw $0x3d5, %dx
    544         movb %bl, %al
    545         outb %al, %dx
    546        
    547         /* Epilogue, restore preserved registers */
    548         popl %edi
    549         popl %esi
    550         popl %ebx
    551         leave
    552        
    553 #endif
    554        
    555         ret
     387h_start:
     388        handler 0 IDT_ITEMS
     389h_end:
    556390
    557391.data
  • kernel/arch/ia32/src/boot/boot.S

    re2ea4ab1 r4d1be48  
    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  */
     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#
    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 
    6141.align 4
    6242.global multiboot_image_start
     
    6444        .long MULTIBOOT_HEADER_MAGIC
    6545        .long MULTIBOOT_HEADER_FLAGS
    66         .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)  /* checksum */
     46        .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)  # checksum
    6747        .long multiboot_header
    6848        .long unmapped_ktext_start
     
    7353multiboot_image_start:
    7454        cld
    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 */
     55        movl $START_STACK, %esp     # initialize stack pointer
     56        lgdt KA2PA(bootstrap_gdtr)  # initialize Global Descriptor Table register
     57       
    8358        movw $gdtselector(KDATA_DES), %cx
    8459        movw %cx, %es
    8560        movw %cx, %fs
    8661        movw %cx, %gs
    87         movw %cx, %ds
     62        movw %cx, %ds               # kernel data + stack
    8863        movw %cx, %ss
    8964       
     
    9166        multiboot_meeting_point:
    9267       
    93         /* Save GRUB arguments */
    94         movl %eax, grub_eax
     68        movl %eax, grub_eax         # save parameters from GRUB
    9569        movl %ebx, grub_ebx
    96        
    97         pm_status $status_prot
    9870       
    9971        movl $(INTEL_CPUID_LEVEL), %eax
    10072        cpuid
    101         cmp $0x0, %eax  /* any function > 0? */
     73        cmp $0x0, %eax              # any function > 0?
    10274        jbe pse_unsupported
    10375       
     
    10880       
    10981        pse_unsupported:
    110                
    111                 pm_error $err_pse
     82                movl $pse_msg, %esi
     83                jmp error_halt
    11284       
    11385        pse_supported:
    11486       
    11587#include "vesa_prot.inc"
    116        
    117         /* Map kernel and turn paging on */
     88
     89        # map kernel and turn paging on
    11890        call map_kernel
    11991       
    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) */
     92        # call arch_pre_main(grub_eax, grub_ebx)
    12793        pushl grub_ebx
    12894        pushl grub_eax
    12995        call arch_pre_main
    130        
    131         pm2_status $status_main
    132        
    133         /* Call main_bsp() */
     96
     97        # Create the first stack frame
     98        pushl $0
     99        movl %esp, %ebp
     100       
    134101        call main_bsp
    135102       
    136         /* Not reached */
     103        # not reached
    137104        cli
    138105        hlt0:
     
    140107                jmp hlt0
    141108
    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  */
    148109.global map_kernel
    149110map_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        #
    150115        movl %cr4, %ecx
    151         orl $(1 << 4), %ecx      /* PSE on */
    152         andl $(~(1 << 5)), %ecx  /* PAE off */
     116        orl $(1 << 4), %ecx                 # turn PSE on
     117        andl $(~(1 << 5)), %ecx             # turn PAE off
    153118        movl %ecx, %cr4
    154119       
     
    161126                movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
    162127                orl %ebx, %eax
    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)
     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
    167130                addl $(4 * 1024 * 1024), %ebx
    168131               
     
    174137       
    175138        movl %cr0, %ebx
    176         orl $(1 << 31), %ebx  /* paging on */
     139        orl $(1 << 31), %ebx                # turn paging on
    177140        movl %ebx, %cr0
    178141        ret
    179142
    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  */
    191 pm_error_halt:
    192         movl $0xb8000, %edi  /* base of EGA text mode memory */
     143# Print string from %esi to EGA display (in red) and halt
     144error_halt:
     145        movl $0xb8000, %edi         # base of EGA text mode memory
    193146        xorl %eax, %eax
    194147       
    195         /* Read bits 8 - 15 of the cursor address */
    196         movw $0x3d4, %dx
     148        movw $0x3d4, %dx            # read bits 8 - 15 of the cursor address
    197149        movb $0xe, %al
    198150        outb %al, %dx
     
    202154        shl $8, %ax
    203155       
    204         /* Read bits 0 - 7 of the cursor address */
    205         movw $0x3d4, %dx
     156        movw $0x3d4, %dx            # read bits 0 - 7 of the cursor address
    206157        movb $0xf, %al
    207158        outb %al, %dx
     
    210161        inb %dx, %al
    211162       
    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:
     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:
    219169       
    220170        movw %ax, %bx
     
    222172        addl %eax, %edi
    223173       
    224         err_ploop:
     174        movw $0x0c00, %ax           # black background, light red foreground
     175       
     176        ploop:
    225177                lodsb
    226                
    227178                cmp $0, %al
    228                 je err_ploop_end
    229                
    230                 movb $0x0c, %ah  /* black background, light red foreground */
     179                je ploop_end
    231180                stosw
    232                
    233                 /* Sanity check for the cursor on the last line */
    234181                inc %bx
    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
     182                jmp ploop
     183        ploop_end:
     184       
     185        movw $0x3d4, %dx            # write bits 8 - 15 of the cursor address
    260186        movb $0xe, %al
    261187        outb %al, %dx
     
    265191        outb %al, %dx
    266192       
    267         /* Write bits 0 - 7 of the cursor address */
    268         movw $0x3d4, %dx
     193        movw $0x3d4, %dx            # write bits 0 - 7 of the cursor address
    269194        movb $0xf, %al
    270195        outb %al, %dx
     
    279204                jmp hlt1
    280205
    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  */
    293 pm_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  */
    403 early_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 
    509206#include "vesa_real.inc"
    510207
     
    521218        .long 0
    522219
    523 err_pse:
     220pse_msg:
    524221        .asciz "Page Size Extension not supported. System halted."
    525222
    526 status_prot:
    527         .asciz "[prot] "
    528 status_vesa_copy:
    529         .asciz "[vesa_copy] "
    530 status_grub_cmdline:
    531         .asciz "[grub_cmdline] "
    532 status_vesa_real:
    533         .asciz "[vesa_real] "
    534 status_prot2:
    535         .asciz "[prot2] "
    536 status_main:
    537         .asciz "[main] "
  • kernel/arch/ia32/src/boot/vesa_prot.inc

    re2ea4ab1 r4d1be48  
    55#define MBINFO_OFFSET_CMDLINE   16
    66
    7         /* Copy real mode VESA initialization code */
    8        
    9         pm_status $status_vesa_copy
     7        # copy real mode VESA initialization code
    108       
    119        mov $vesa_init, %esi
     
    1412        rep movsb
    1513       
    16         /* Check for GRUB command line */
    17        
    18         pm_status $status_grub_cmdline
     14        # check for GRUB command line
    1915       
    2016        mov grub_eax, %eax
     
    2723        jnc no_cmdline
    2824       
    29         /* Skip the kernel path in command line */
     25        # skip the kernel path in command line
    3026       
    3127        mov MBINFO_OFFSET_CMDLINE(%ebx), %esi
     
    5652        space_loop_done:
    5753       
    58         /* Copy at most 23 characters from command line */
     54        # copy at most 23 characters from command line
    5955       
    6056        mov $VESA_INIT_SEGMENT << 4, %edi
     
    7268        cmd_loop_done:
    7369       
    74         /* Zero termination */
     70        # zero termination
    7571       
    7672        xor %eax, %eax
     
    7975        no_cmdline:
    8076       
    81         /* Jump to the real mode */
    82        
    83         pm_status $status_vesa_real
     77        # jump to the real mode
    8478       
    8579        mov $VESA_INIT_SEGMENT << 4, %edi
     
    8781       
    8882        vesa_meeting_point:
    89                 /* Returned back to protected mode */
     83                # returned back to protected mode
    9084               
    9185                mov %ax, KA2PA(vesa_scanline)
  • kernel/arch/ia32/src/boot/vesa_real.inc

    re2ea4ab1 r4d1be48  
    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 */
    170                
     169                # try next mode
    171170                mov %gs:(%si), %cx
    172171                cmp $VESA_END_OF_MODES, %cx
     
    187186                jne no_mode
    188187               
    189                 /*
    190                  * Check for proper attributes (supported,
    191                  * color, graphics, linear framebuffer).
    192                  */
     188                # check for proper attributes (supported, color, graphics, linear framebuffer)
    193189               
    194190                mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
     
    197193                jne next_mode
    198194               
    199                 /* Check for proper resolution */
     195                # check for proper resolution
    200196               
    201197                mov default_width - vesa_init, %ax
     
    207203                jne next_mode
    208204               
    209                 /* Check for proper bpp */
     205                # check for proper bpp
    210206               
    211207                mov default_bpp - vesa_init, %al
     
    217213                jne next_mode
    218214               
    219                 /* For 24 bpp modes accept also 32 bit bpp */
     215                # for 24 bpp modes accept also 32 bit bpp
    220216               
    221217                mov $32, %al
     
    234230                jnz no_mode
    235231               
    236                 /* Set 3:2:3 VGA palette */
     232                # set 3:2:3 VGA palette
    237233               
    238234                mov VESA_MODE_BPP_OFFSET(%di), %al
     
    245241                mov $0x100, %ecx
    246242               
    247                 /* Test if VGA compatible registers are present */
    248                 bt $5, %ax
     243                bt $5, %ax              # test if VGA compatible registers are present
    249244                jnc vga_compat
    250245               
    251                         /* Use VESA routine to set the palette */
    252                        
     246                        # try VESA routine to set palette
    253247                        mov $VESA_SET_PALETTE, %ax
    254248                        xor %bl, %bl
     
    260254               
    261255                vga_compat:
    262                        
    263                         /* Use VGA registers to set the palette */
    264                        
    265                         movw $0x3c6, %dx  /* set palette mask */
     256                        # try VGA registers to set palette
     257                        movw $0x3c6, %dx    # set palette mask
    266258                        movb $0xff, %al
    267259                        outb %al, %dx
    268260                       
    269                         movw $0x3c8, %dx  /* first index to set */
     261                        movw $0x3c8, %dx    # first index to set
    270262                        xor %al, %al
    271263                        outb %al, %dx
    272264                       
    273                         movw $0x3c9, %dx  /* data port */
     265                        movw $0x3c9, %dx    # data port
    274266                       
    275267                        vga_loop:
     
    292284                vga_not_set:
    293285               
    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                  */
     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
    302292               
    303293                mov VESA_MODE_BPP_OFFSET(%di), %al
     
    338328       
    339329        no_mode:
    340                
    341                 /* No prefered mode found */
    342                
     330                # no prefered mode found
    343331                mov $0x111, %cx
    344332                push %di
     
    351339                cmp $VESA_OK, %al
    352340                jnz text_mode
    353                 jz set_mode  /* force relative jump */
     341                jz set_mode             # force relative jump
    354342       
    355343        text_mode:
    356                
    357                 /* Reset to EGA text mode (because of problems with VESA) */
    358                
     344                # reset to EGA text mode (because of problems with VESA)
    359345                mov $0x0003, %ax
    360346                int $0x10
    361347                mov $0xffffffff, %edi
    362348                xor %ax, %ax
    363                 jz vesa_leave_real  /* force relative jump */
     349                jz vesa_leave_real      # force relative jump
    364350
    365351vga323:
  • kernel/arch/ia32/src/boot/vesa_ret.inc

    re2ea4ab1 r4d1be48  
    11.code32
    22vesa_init_protected:
    3         cld
    4        
    5         /* Initialize stack pointer */
    6         movl $START_STACK, %esp
    7        
    8         /* Kernel data + stack */
    93        movw $gdtselector(KDATA_DES), %cx
    104        movw %cx, %es
    115        movw %cx, %fs
    126        movw %cx, %gs
    13         movw %cx, %ds
     7        movw %cx, %ds               # kernel data + stack
    148        movw %cx, %ss
    159       
     10        movl $START_STACK, %esp     # initialize stack pointer
     11       
    1612        jmpl $gdtselector(KTEXT_DES), $vesa_meeting_point
  • kernel/arch/ia32/src/smp/apic.c

    re2ea4ab1 r4d1be48  
    7676
    7777uint32_t apic_id_mask = 0;
    78 uint8_t bsp_l_apic = 0;
    79 
    8078static irq_t l_apic_timer_irq;
    8179
     
    156154}
    157155
    158 /** Get Local APIC ID.
    159  *
    160  * @return Local APIC ID.
    161  *
    162  */
    163 static 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 
    171156/** Initialize APIC on BSP. */
    172157void apic_init(void)
     
    223208        l_apic_init();
    224209        l_apic_debug();
    225        
    226         bsp_l_apic = l_apic_id();
    227210}
    228211
     
    477460{
    478461#ifdef LAPIC_VERBOSE
    479         printf("LVT on cpu%" PRIs ", LAPIC ID: %" PRIu8 "\n",
    480             CPU->id, l_apic_id());
     462        printf("LVT on cpu%" PRIs ", LAPIC ID: %" PRIu8 "\n", CPU->id, l_apic_id());
    481463       
    482464        lvt_tm_t tm;
    483465        tm.value = l_apic[LVT_Tm];
    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]);
     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]);
    487467       
    488468        lvt_lint_t lint;
    489469        lint.value = l_apic[LVT_LINT0];
    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]);
     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]); 
    500473       
    501474        lvt_error_t error;
    502475        error.value = l_apic[LVT_Err];
    503         printf("LVT Err: vector=%" PRIu8 ", %s, %s\n", error.vector,
    504             delivs_str[error.delivs], mask_str[error.masked]);
     476        printf("LVT Err: vector=%hhd, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]);
    505477#endif
     478}
     479
     480/** Get Local APIC ID.
     481 *
     482 * @return Local APIC ID.
     483 *
     484 */
     485uint8_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;
    506491}
    507492
  • kernel/arch/ia32/src/smp/mps.c

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

    re2ea4ab1 r4d1be48  
    6262void smp_init(void)
    6363{
     64        uintptr_t l_apic_address;
     65        uintptr_t io_apic_address;
     66       
    6467        if (acpi_madt) {
    6568                acpi_madt_parse();
     
    7275        }
    7376       
     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       
    7487        if (config.cpu_count > 1) {
    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);
     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;
    7797        }
    7898}
     
    113133        apic_init();
    114134       
     135        uint8_t apic = l_apic_id();
     136       
    115137        for (i = 0; i < config.cpu_count; i++) {
    116138                /*
     
    126148                        continue;
    127149               
    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);
     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);
    131153                        continue;
    132154                }
  • kernel/arch/ia64/src/asm.S

    re2ea4ab1 r4d1be48  
    1 /*
    2  * Copyright (c) 2005 Jakub Jermar
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  *
    9  * - Redistributions of source code must retain the above copyright
    10  *   notice, this list of conditions and the following disclaimer.
    11  * - Redistributions in binary form must reproduce the above copyright
    12  *   notice, this list of conditions and the following disclaimer in the
    13  *   documentation and/or other materials provided with the distribution.
    14  * - The name of the author may not be used to endorse or promote products
    15  *   derived from this software without specific prior written permission.
    16  *
    17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    27  */
     1#
     2# Copyright (c) 2005 Jakub Jermar
     3# All rights reserved.
     4#
     5# Redistribution and use in source and binary forms, with or without
     6# modification, are permitted provided that the following conditions
     7# are met:
     8#
     9# - Redistributions of source code must retain the above copyright
     10#   notice, this list of conditions and the following disclaimer.
     11# - Redistributions in binary form must reproduce the above copyright
     12#   notice, this list of conditions and the following disclaimer in the
     13#   documentation and/or other materials provided with the distribution.
     14# - The name of the author may not be used to endorse or promote products
     15#   derived from this software without specific prior written permission.
     16#
     17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27#
    2828
    2929#include <arch/register.h>
    3030
    3131.text
    32 .global memcpy
    33 .global memcpy_from_uspace
    34 .global memcpy_to_uspace
    35 .global memcpy_from_uspace_failover_address
    36 .global memcpy_to_uspace_failover_address
    3732
    3833/** Copy memory from/to userspace.
     
    4439 * @param in1 Source address.
    4540 * @param in2 Number of byte to copy.
    46  *
    4741 */
     42.global memcpy
     43.global memcpy_from_uspace
     44.global memcpy_to_uspace
     45.global memcpy_from_uspace_failover_address
     46.global memcpy_to_uspace_failover_address
    4847memcpy:
    4948memcpy_from_uspace:
    5049memcpy_to_uspace:
    5150        alloc loc0 = ar.pfs, 3, 1, 0, 0
    52        
     51
    5352        adds r14 = 7, in1
    5453        mov r2 = ar.lc
     
    5655        and r14 = -8, r14 ;;
    5756        cmp.ne p6, p7 = r14, in1
    58         (p7) br.cond.dpnt 3f ;;
     57(p7)    br.cond.dpnt 3f ;;
     580:
     59        cmp.ne p6, p7 = 0, in2
     60(p7)    br.cond.dpnt 2f ;;
     61(p6)    adds r14 = -1, in2
     62(p6)    mov r16 = r0
     63(p6)    mov r17 = r0 ;;
     64(p6)    mov ar.lc = r14
     651:
     66        add r14 = r16, in1
     67        add r15 = r16, in0
     68        adds r17 = 1, r17 ;;
     69        ld1 r14 = [r14]
     70        mov r16 = r17 ;;
     71        st1 [r15] = r14
     72        br.cloop.sptk.few 1b ;;
     732:
     74        mov ar.lc = r2
     75        mov ar.pfs = loc0
     76        br.ret.sptk.many rp
     773:
     78        adds r14 = 7, in0 ;;
     79        and r14 = -8, r14 ;;
     80        cmp.eq p6, p7 = r14, in0
     81(p7)    br.cond.dptk 0b
     82        shr.u r18 = in2, 3 ;;
     83        cmp.ne p6, p7 = 0, r18
     84(p7)    br.cond.dpnt 5f ;;
     85(p6)    adds r14 = -1, r18
     86(p6)    mov r16 = r0
     87(p6)    mov r17 = r0 ;;
     88(p6)    mov ar.lc = r14
     894:
     90        shladd r14 = r16, 3, r0
     91        adds r16 = 1, r17 ;;
     92        add r15 = in1, r14
     93        add r14 = in0, r14
     94        mov r17 = r16 ;;
     95        ld8 r15 = [r15] ;;
     96        st8 [r14] = r15
     97        br.cloop.sptk.few 4b
     985:
     99        and r15 = 7, in2
     100        shladd r14 = r18, 3, r0
     101        mov r16 = r0
     102        mov r18 = r0 ;;
     103        cmp.eq p6, p7 = 0, r15
     104        add in0 = r14, in0
     105        adds r15 = -1, r15
     106        add r17 = r14, in1
     107(p6)    br.cond.dpnt 2b ;;
     108        mov ar.lc = r15
     1096:
     110        add r14 = r16, r17
     111        add r15 = r16, in0
     112        adds r16 = 1, r18 ;;
     113        ld1 r14 = [r14]
     114        mov r18 = r16 ;;
     115        st1 [r15] = r14
     116        br.cloop.sptk.few 6b ;;
     117        mov ar.lc = r2
     118        mov ar.pfs = loc0
     119        br.ret.sptk.many rp
    59120       
    60         0:
    61        
    62                 cmp.ne p6, p7 = 0, in2
    63                 (p7) br.cond.dpnt 2f ;;
    64                 (p6) adds r14 = -1, in2
    65                 (p6) mov r16 = r0
    66                 (p6) mov r17 = r0 ;;
    67                 (p6) mov ar.lc = r14
    68        
    69         1:
    70        
    71                 add r14 = r16, in1
    72                 add r15 = r16, in0
    73                 adds r17 = 1, r17 ;;
    74                 ld1 r14 = [r14]
    75                 mov r16 = r17 ;;
    76                 st1 [r15] = r14
    77                 br.cloop.sptk.few 1b ;;
    78        
    79         2:
    80        
    81                 mov ar.lc = r2
    82                 mov ar.pfs = loc0
    83                 br.ret.sptk.many rp
    84        
    85         3:
    86        
    87                 adds r14 = 7, in0 ;;
    88                 and r14 = -8, r14 ;;
    89                 cmp.eq p6, p7 = r14, in0
    90                 (p7) br.cond.dptk 0b
    91                 shr.u r18 = in2, 3 ;;
    92                 cmp.ne p6, p7 = 0, r18
    93                 (p7) br.cond.dpnt 5f ;;
    94                 (p6) adds r14 = -1, r18
    95                 (p6) mov r16 = r0
    96                 (p6) mov r17 = r0 ;;
    97                 (p6) mov ar.lc = r14
    98        
    99         4:
    100        
    101                 shladd r14 = r16, 3, r0
    102                 adds r16 = 1, r17 ;;
    103                 add r15 = in1, r14
    104                 add r14 = in0, r14
    105                 mov r17 = r16 ;;
    106                 ld8 r15 = [r15] ;;
    107                 st8 [r14] = r15
    108                 br.cloop.sptk.few 4b
    109        
    110         5:
    111        
    112                 and r15 = 7, in2
    113                 shladd r14 = r18, 3, r0
    114                 mov r16 = r0
    115                 mov r18 = r0 ;;
    116                 cmp.eq p6, p7 = 0, r15
    117                 add in0 = r14, in0
    118                 adds r15 = -1, r15
    119                 add r17 = r14, in1
    120                 (p6) br.cond.dpnt 2b ;;
    121                 mov ar.lc = r15
    122        
    123         6:
    124        
    125                 add r14 = r16, r17
    126                 add r15 = r16, in0
    127                 adds r16 = 1, r18 ;;
    128                 ld1 r14 = [r14]
    129                 mov r18 = r16 ;;
    130                 st1 [r15] = r14
    131                 br.cloop.sptk.few 6b ;;
    132                 mov ar.lc = r2
    133                 mov ar.pfs = loc0
    134                 br.ret.sptk.many rp
    135 
    136121memcpy_from_uspace_failover_address:
    137122memcpy_to_uspace_failover_address:
    138         /* Return 0 on failure */
    139         mov r8 = r0
     123        mov r8 = r0                     /* return 0 on failure */
    140124        mov ar.pfs = loc0
    141125        br.ret.sptk.many rp
     
    161145 * @param in4 Value to be stored in IPSR.
    162146 * @param in5 Value to be stored in RSC.
    163  *
    164147 */
    165148.global switch_to_userspace
    166149switch_to_userspace:
    167150        alloc loc0 = ar.pfs, 6, 3, 0, 0
    168        
    169         /* Disable interruption collection and interrupts */
    170         rsm (PSR_IC_MASK | PSR_I_MASK)
     151        rsm (PSR_IC_MASK | PSR_I_MASK)          /* disable interruption collection and interrupts */
    171152        srlz.d ;;
    172153        srlz.i ;;
     
    175156        mov cr.iip = in0
    176157        mov r12 = in1
    177        
     158
    178159        xor r1 = r1, r1
    179160       
     
    184165        movl loc2 = PFM_MASK ;;
    185166        and loc1 = loc2, loc1 ;;
    186         mov cr.ifs = loc1 ;;  /* prevent decrementing BSP by rfi */
    187        
     167        mov cr.ifs = loc1 ;;                    /* prevent decrementing BSP by rfi */
     168
    188169        invala
    189170       
    190171        mov loc1 = ar.rsc ;;
    191         and loc1 = ~3, loc1 ;;
    192         mov ar.rsc = loc1 ;;  /* put RSE into enforced lazy mode */
    193        
     172        and loc1 = ~3, loc1 ;;                 
     173        mov ar.rsc = loc1 ;;                    /* put RSE into enforced lazy mode */
     174
    194175        flushrs ;;
    195176       
     
    200181       
    201182        rfi ;;
    202 
    203 .global early_putchar
    204 early_putchar:
    205         br.ret.sptk.many b0
  • kernel/arch/ia64/src/start.S

    re2ea4ab1 r4d1be48  
    4747
    4848stack0:
    49 
    50 #
    51 # Kernel entry point.
    52 #
    53 # This is where we are passed control from the boot code.
    54 # Register contents:
    55 #
    56 #       r2      Address of the boot code's bootinfo structure.
    57 #
    5849kernel_image_start:
    5950        .auto
     
    166157        loadrs
    167158       
    168         #
    169         # Initialize memory stack to some sane value and allocate a scratch are
    170         # on it.
    171         #
    172         movl sp = stack0 ;;
    173         add sp = -16, sp
     159        # Initialize memory stack to some sane value
     160        movl r12 = stack0 ;;
     161        add r12 = -16, r12  /* allocate a scratch area on the stack */
    174162       
    175163        # Initialize gp (Global Pointer) register
    176         movl gp = kernel_image_start
     164        movl r20 = (VRN_KERNEL << VRN_SHIFT) ;;
     165        or r20 = r20, r1 ;;
     166        movl r1 = kernel_image_start
    177167       
    178         #       
    179         # Initialize bootinfo on BSP.
    180         #
    181         movl r20 = (VRN_KERNEL << VRN_SHIFT) ;;
    182         or r20 = r20, r2 ;;
     168        /*
     169         * Initialize bootinfo on BSP.
     170         */
    183171        addl r21 = @gprel(bootinfo), gp ;;
    184172        st8 [r21] = r20
  • kernel/arch/mips32/src/asm.S

    re2ea4ab1 r4d1be48  
    1 /*
    2  * Copyright (c) 2003 Jakub Jermar
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  *
    9  * - Redistributions of source code must retain the above copyright
    10  *   notice, this list of conditions and the following disclaimer.
    11  * - Redistributions in binary form must reproduce the above copyright
    12  *   notice, this list of conditions and the following disclaimer in the
    13  *   documentation and/or other materials provided with the distribution.
    14  * - The name of the author may not be used to endorse or promote products
    15  *   derived from this software without specific prior written permission.
    16  *
    17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    27  */
     1#
     2# Copyright (c) 2003-2004 Jakub Jermar
     3# All rights reserved.
     4#
     5# Redistribution and use in source and binary forms, with or without
     6# modification, are permitted provided that the following conditions
     7# are met:
     8#
     9# - Redistributions of source code must retain the above copyright
     10#   notice, this list of conditions and the following disclaimer.
     11# - Redistributions in binary form must reproduce the above copyright
     12#   notice, this list of conditions and the following disclaimer in the
     13#   documentation and/or other materials provided with the distribution.
     14# - The name of the author may not be used to endorse or promote products
     15#   derived from this software without specific prior written permission.
     16#
     17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27#
    2828
    2929#include <arch/asm/regname.h>
     
    5757        nop
    5858
     59
    5960.global memsetb
    6061memsetb:
     
    6263        nop
    6364
     65
    6466.global memsetw
    6567memsetw:
    6668        j _memsetw
    6769        nop
     70
    6871
    6972.global memcpy
     
    7578memcpy_from_uspace:
    7679memcpy_to_uspace:
    77         move $t2, $a0  /* save dst */
     80        move $t2, $a0      # save dst
    7881       
    7982        addiu $v0, $a1, 3
    80         li $v1, -4  /* 0xfffffffffffffffc */
     83        li $v1, -4         # 0xfffffffffffffffc
    8184        and $v0, $v0, $v1
    8285        beq $a1, $v0, 3f
     
    146149        move $v0, $zero
    147150
     151
     152
    148153.macro fpu_gp_save reg ctx
    149154        mfc1 $t0, $\reg
     
    159164        cfc1 $t0, $1
    160165        sw $t0, (\reg + 32) * 4(\ctx)
    161 .endm
     166.endm   
    162167
    163168.macro fpu_ct_restore reg ctx
     
    165170        ctc1 $t0, $\reg
    166171.endm
     172
    167173
    168174.global fpu_context_save
     
    307313        j $ra
    308314        nop
    309 
    310 .global early_putchar
    311 early_putchar:
    312         j $ra
    313         nop
  • kernel/arch/ppc32/src/asm.S

    re2ea4ab1 r4d1be48  
    1 /*
    2  * Copyright (c) 2005 Martin Decky
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  *
    9  * - Redistributions of source code must retain the above copyright
    10  *   notice, this list of conditions and the following disclaimer.
    11  * - Redistributions in binary form must reproduce the above copyright
    12  *   notice, this list of conditions and the following disclaimer in the
    13  *   documentation and/or other materials provided with the distribution.
    14  * - The name of the author may not be used to endorse or promote products
    15  *   derived from this software without specific prior written permission.
    16  *
    17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    27  */
     1#
     2# Copyright (c) 2005 Martin Decky
     3# All rights reserved.
     4#
     5# Redistribution and use in source and binary forms, with or without
     6# modification, are permitted provided that the following conditions
     7# are met:
     8#
     9# - Redistributions of source code must retain the above copyright
     10#   notice, this list of conditions and the following disclaimer.
     11# - Redistributions in binary form must reproduce the above copyright
     12#   notice, this list of conditions and the following disclaimer in the
     13#   documentation and/or other materials provided with the distribution.
     14# - The name of the author may not be used to endorse or promote products
     15#   derived from this software without specific prior written permission.
     16#
     17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27#
    2828
    2929#include <arch/asm/regname.h>
     
    4242.global memcpy_from_uspace_failover_address
    4343.global memcpy_to_uspace_failover_address
    44 .global early_putchar
    4544
    4645userspace_asm:
    4746       
    48         /*
    49          * r3 = uspace_uarg
    50          * r4 = stack
    51          * r5 = entry
    52          */
    53        
    54         /* Disable interrupts */
     47        # r3 = uspace_uarg
     48        # r4 = stack
     49        # r5 = entry
     50       
     51        # disable interrupts
    5552       
    5653        mfmsr r31
     
    5855        mtmsr r31
    5956       
    60         /* Set entry point */
     57        # set entry point
    6158       
    6259        mtsrr0 r5
    6360       
    64         /* Set problem state, enable interrupts */
     61        # set problem state, enable interrupts
    6562       
    6663        ori r31, r31, MSR_PR
     
    6865        mtsrr1 r31
    6966       
    70         /* Set stack */
     67        # set stack
    7168       
    7269        mr sp, r4
    7370       
    74         /* %r6 is defined to hold pcb_ptr - set it to 0 */
     71        # %r6 is defined to hold pcb_ptr - set it to 0
    7572       
    7673        xor r6, r6, r6
    7774       
    78         /* Jump to userspace */
     75        # jump to userspace
    7976       
    8077        rfi
     
    8279iret:
    8380       
    84         /* Disable interrupts */
     81        # disable interrupts
    8582       
    8683        mfmsr r31
     
    144141iret_syscall:
    145142       
    146         /* Reset decrementer */
     143        # reset decrementer
    147144       
    148145        li r31, 1000
    149146        mtdec r31
    150147       
    151         /* Disable interrupts */
     148        # disable interrupts
    152149       
    153150        mfmsr r31
     
    281278memcpy_from_uspace_failover_address:
    282279memcpy_to_uspace_failover_address:
    283         /* Return zero, failure */
     280        # return zero, failure
    284281        xor r3, r3, r3
    285282        blr
    286 
    287 early_putchar:
    288         blr
  • kernel/arch/sparc64/src/asm.S

    re2ea4ab1 r4d1be48  
    1 /*
    2  * Copyright (c) 2005 Jakub Jermar
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  *
    9  * - Redistributions of source code must retain the above copyright
    10  *   notice, this list of conditions and the following disclaimer.
    11  * - Redistributions in binary form must reproduce the above copyright
    12  *   notice, this list of conditions and the following disclaimer in the
    13  *   documentation and/or other materials provided with the distribution.
    14  * - The name of the author may not be used to endorse or promote products
    15  *   derived from this software without specific prior written permission.
    16  *
    17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    27  */
     1#
     2# Copyright (c) 2005 Jakub Jermar
     3# All rights reserved.
     4#
     5# Redistribution and use in source and binary forms, with or without
     6# modification, are permitted provided that the following conditions
     7# are met:
     8#
     9# - Redistributions of source code must retain the above copyright
     10#   notice, this list of conditions and the following disclaimer.
     11# - Redistributions in binary form must reproduce the above copyright
     12#   notice, this list of conditions and the following disclaimer in the
     13#   documentation and/or other materials provided with the distribution.
     14# - The name of the author may not be used to endorse or promote products
     15#   derived from this software without specific prior written permission.
     16#
     17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27#
    2828
    2929#include <arch/arch.h>
     
    3232.text
    3333
    34 .register %g2, #scratch
    35 .register %g3, #scratch
     34.register       %g2, #scratch
     35.register       %g3, #scratch
    3636
    3737/*
     
    4040.global memcpy
    4141memcpy:
    42         mov %o0, %o3  /* save dst */
    43         add %o1, 7, %g1
    44         and %g1, -8, %g1
    45         cmp %o1, %g1
    46         be,pn %xcc, 3f
    47         add %o0, 7, %g1
    48         mov 0, %g3
    49        
    50         0:
    51        
    52                 brz,pn %o2, 2f
    53                 mov 0, %g2
    54        
    55         1:
    56        
    57                 ldub [%g3 + %o1], %g1
    58                 add %g2, 1, %g2
    59                 cmp %o2, %g2
    60                 stb %g1, [%g3 + %o0]
    61                 bne,pt %xcc, 1b
    62                 mov %g2, %g3
    63        
    64         2:
    65        
    66                 jmp %o7 + 8  /* exit point */
    67                 mov %o3, %o0
    68        
    69         3:
    70        
    71                 and %g1, -8, %g1
    72                 cmp %o0, %g1
    73                 bne,pt %xcc, 0b
    74                 mov 0, %g3
    75                 srlx %o2, 3, %g4
    76                 brz,pn %g4, 5f
    77                 mov 0, %g5
    78        
    79         4:
    80        
    81                 sllx %g3, 3, %g2
    82                 add %g5, 1, %g3
    83                 ldx [%o1 + %g2], %g1
    84                 mov %g3, %g5
    85                 cmp %g4, %g3
    86                 bne,pt %xcc, 4b
    87                 stx %g1, [%o0 + %g2]
    88        
    89         5:
    90        
    91                 and %o2, 7, %o2
    92                 brz,pn %o2, 2b
    93                 sllx %g4, 3, %g1
    94                 mov 0, %g2
    95                 add %g1, %o0, %o0
    96                 add %g1, %o1, %g4
    97                 mov 0, %g3
    98        
    99         6:
    100        
    101                 ldub [%g2 + %g4], %g1
    102                 stb %g1, [%g2 + %o0]
    103                 add %g3, 1, %g2
    104                 cmp %o2, %g2
    105                 bne,pt %xcc, 6b
    106                 mov %g2, %g3
    107                
    108                 jmp %o7 + 8  /* exit point */
    109                 mov %o3, %o0
     42        mov     %o0, %o3                ! save dst
     43        add     %o1, 7, %g1
     44        and     %g1, -8, %g1
     45        cmp     %o1, %g1
     46        be,pn   %xcc, 3f
     47        add     %o0, 7, %g1
     48        mov     0, %g3
     490:
     50        brz,pn  %o2, 2f
     51        mov     0, %g2
     521:
     53        ldub    [%g3 + %o1], %g1
     54        add     %g2, 1, %g2
     55        cmp     %o2, %g2
     56        stb     %g1, [%g3 + %o0]
     57        bne,pt  %xcc, 1b
     58        mov     %g2, %g3
     592:
     60        jmp     %o7 + 8                 ! exit point
     61        mov     %o3, %o0
     623:
     63        and     %g1, -8, %g1
     64        cmp     %o0, %g1
     65        bne,pt  %xcc, 0b
     66        mov     0, %g3
     67        srlx    %o2, 3, %g4
     68        brz,pn  %g4, 5f
     69        mov     0, %g5
     704:
     71        sllx    %g3, 3, %g2
     72        add     %g5, 1, %g3
     73        ldx     [%o1 + %g2], %g1
     74        mov     %g3, %g5
     75        cmp     %g4, %g3
     76        bne,pt  %xcc, 4b
     77        stx     %g1, [%o0 + %g2]
     785:
     79        and     %o2, 7, %o2
     80        brz,pn  %o2, 2b
     81        sllx    %g4, 3, %g1
     82        mov     0, %g2
     83        add     %g1, %o0, %o0
     84        add     %g1, %o1, %g4
     85        mov     0, %g3
     866:
     87        ldub    [%g2 + %g4], %g1
     88        stb     %g1, [%g2 + %o0]
     89        add     %g3, 1, %g2
     90        cmp     %o2, %g2
     91        bne,pt  %xcc, 6b
     92        mov     %g2, %g3
     93
     94        jmp     %o7 + 8                 ! exit point
     95        mov     %o3, %o0
    11096
    11197/*
     
    114100.global memcpy_from_uspace
    115101memcpy_from_uspace:
    116         mov %o0, %o3  /* save dst */
    117         add %o1, 7, %g1
    118         and %g1, -8, %g1
    119         cmp %o1, %g1
    120         be,pn %xcc, 3f
    121         add %o0, 7, %g1
    122         mov 0, %g3
    123        
    124         0:
    125        
    126                 brz,pn %o2, 2f
    127                 mov 0, %g2
    128        
    129         1:
    130        
    131                 lduba [%g3 + %o1] ASI_AIUS, %g1
    132                 add %g2, 1, %g2
    133                 cmp %o2, %g2
    134                 stb %g1, [%g3 + %o0]
    135                 bne,pt %xcc, 1b
    136                 mov %g2, %g3
    137        
    138         2:
    139        
    140                 jmp %o7 + 8  /* exit point */
    141                 mov %o3, %o0
    142        
    143         3:
    144        
    145                 and %g1, -8, %g1
    146                 cmp %o0, %g1
    147                 bne,pt %xcc, 0b
    148                 mov 0, %g3
    149                 srlx %o2, 3, %g4
    150                 brz,pn %g4, 5f
    151                 mov 0, %g5
    152        
    153         4:
    154        
    155                 sllx %g3, 3, %g2
    156                 add %g5, 1, %g3
    157                 ldxa [%o1 + %g2] ASI_AIUS, %g1
    158                 mov %g3, %g5
    159                 cmp %g4, %g3
    160                 bne,pt %xcc, 4b
    161                 stx %g1, [%o0 + %g2]
    162        
    163         5:
    164        
    165                 and %o2, 7, %o2
    166                 brz,pn %o2, 2b
    167                 sllx %g4, 3, %g1
    168                 mov 0, %g2
    169                 add %g1, %o0, %o0
    170                 add %g1, %o1, %g4
    171                 mov 0, %g3
    172        
    173         6:
    174        
    175                 lduba [%g2 + %g4] ASI_AIUS, %g1
    176                 stb %g1, [%g2 + %o0]
    177                 add %g3, 1, %g2
    178                 cmp %o2, %g2
    179                 bne,pt %xcc, 6b
    180                 mov %g2, %g3
    181                
    182                 jmp %o7 + 8  /* exit point */
    183                 mov %o3, %o0
     102        mov     %o0, %o3                ! save dst
     103        add     %o1, 7, %g1
     104        and     %g1, -8, %g1
     105        cmp     %o1, %g1
     106        be,pn   %xcc, 3f
     107        add     %o0, 7, %g1
     108        mov     0, %g3
     1090:
     110        brz,pn  %o2, 2f
     111        mov     0, %g2
     1121:
     113        lduba   [%g3 + %o1] ASI_AIUS, %g1
     114        add     %g2, 1, %g2
     115        cmp     %o2, %g2
     116        stb     %g1, [%g3 + %o0]
     117        bne,pt  %xcc, 1b
     118        mov     %g2, %g3
     1192:
     120        jmp     %o7 + 8                 ! exit point
     121        mov     %o3, %o0
     1223:
     123        and     %g1, -8, %g1
     124        cmp     %o0, %g1
     125        bne,pt  %xcc, 0b
     126        mov     0, %g3
     127        srlx    %o2, 3, %g4
     128        brz,pn  %g4, 5f
     129        mov     0, %g5
     1304:
     131        sllx    %g3, 3, %g2
     132        add     %g5, 1, %g3
     133        ldxa    [%o1 + %g2] ASI_AIUS, %g1
     134        mov     %g3, %g5
     135        cmp     %g4, %g3
     136        bne,pt  %xcc, 4b
     137        stx     %g1, [%o0 + %g2]
     1385:
     139        and     %o2, 7, %o2
     140        brz,pn  %o2, 2b
     141        sllx    %g4, 3, %g1
     142        mov     0, %g2
     143        add     %g1, %o0, %o0
     144        add     %g1, %o1, %g4
     145        mov     0, %g3
     1466:
     147        lduba   [%g2 + %g4] ASI_AIUS, %g1
     148        stb     %g1, [%g2 + %o0]
     149        add     %g3, 1, %g2
     150        cmp     %o2, %g2
     151        bne,pt  %xcc, 6b
     152        mov     %g2, %g3
     153
     154        jmp     %o7 + 8                 ! exit point
     155        mov     %o3, %o0
    184156
    185157/*
     
    188160.global memcpy_to_uspace
    189161memcpy_to_uspace:
    190         mov %o0, %o3  /* save dst */
    191         add %o1, 7, %g1
    192         and %g1, -8, %g1
    193         cmp %o1, %g1
    194         be,pn %xcc, 3f
    195         add %o0, 7, %g1
    196         mov 0, %g3
    197        
    198         0:
    199        
    200                 brz,pn %o2, 2f
    201                 mov 0, %g2
    202        
    203         1:
    204        
    205                 ldub [%g3 + %o1], %g1
    206                 add %g2, 1, %g2
    207                 cmp %o2, %g2
    208                 stba %g1, [%g3 + %o0] ASI_AIUS
    209                 bne,pt %xcc, 1b
    210                 mov %g2, %g3
    211        
    212         2:
    213        
    214                 jmp %o7 + 8  /* exit point */
    215                 mov %o3, %o0
    216        
    217         3:
    218        
    219                 and %g1, -8, %g1
    220                 cmp %o0, %g1
    221                 bne,pt %xcc, 0b
    222                 mov 0, %g3
    223                 srlx %o2, 3, %g4
    224                 brz,pn %g4, 5f
    225                 mov 0, %g5
    226        
    227         4:
    228        
    229                 sllx %g3, 3, %g2
    230                 add %g5, 1, %g3
    231                 ldx [%o1 + %g2], %g1
    232                 mov %g3, %g5
    233                 cmp %g4, %g3
    234                 bne,pt %xcc, 4b
    235                 stxa %g1, [%o0 + %g2] ASI_AIUS
    236        
    237         5:
    238        
    239                 and %o2, 7, %o2
    240                 brz,pn %o2, 2b
    241                 sllx %g4, 3, %g1
    242                 mov 0, %g2
    243                 add %g1, %o0, %o0
    244                 add %g1, %o1, %g4
    245                 mov 0, %g3
    246        
    247         6:
    248        
    249                 ldub [%g2 + %g4], %g1
    250                 stba %g1, [%g2 + %o0] ASI_AIUS
    251                 add %g3, 1, %g2
    252                 cmp %o2, %g2
    253                 bne,pt %xcc, 6b
    254                 mov %g2, %g3
    255                
    256                 jmp     %o7 + 8  /* exit point */
    257                 mov     %o3, %o0
     162        mov     %o0, %o3                ! save dst
     163        add     %o1, 7, %g1
     164        and     %g1, -8, %g1
     165        cmp     %o1, %g1
     166        be,pn   %xcc, 3f
     167        add     %o0, 7, %g1
     168        mov     0, %g3
     1690:
     170        brz,pn  %o2, 2f
     171        mov     0, %g2
     1721:
     173        ldub    [%g3 + %o1], %g1
     174        add     %g2, 1, %g2
     175        cmp     %o2, %g2
     176        stba    %g1, [%g3 + %o0] ASI_AIUS
     177        bne,pt  %xcc, 1b
     178        mov     %g2, %g3
     1792:
     180        jmp     %o7 + 8                 ! exit point
     181        mov     %o3, %o0
     1823:
     183        and     %g1, -8, %g1
     184        cmp     %o0, %g1
     185        bne,pt  %xcc, 0b
     186        mov     0, %g3
     187        srlx    %o2, 3, %g4
     188        brz,pn  %g4, 5f
     189        mov     0, %g5
     1904:
     191        sllx    %g3, 3, %g2
     192        add     %g5, 1, %g3
     193        ldx     [%o1 + %g2], %g1
     194        mov     %g3, %g5
     195        cmp     %g4, %g3
     196        bne,pt  %xcc, 4b
     197        stxa    %g1, [%o0 + %g2] ASI_AIUS
     1985:
     199        and     %o2, 7, %o2
     200        brz,pn  %o2, 2b
     201        sllx    %g4, 3, %g1
     202        mov     0, %g2
     203        add     %g1, %o0, %o0
     204        add     %g1, %o1, %g4
     205        mov     0, %g3
     2066:
     207        ldub    [%g2 + %g4], %g1
     208        stba    %g1, [%g2 + %o0] ASI_AIUS
     209        add     %g3, 1, %g2
     210        cmp     %o2, %g2
     211        bne,pt  %xcc, 6b
     212        mov     %g2, %g3
     213
     214        jmp     %o7 + 8                 ! exit point
     215        mov     %o3, %o0
    258216
    259217.global memcpy_from_uspace_failover_address
     
    261219memcpy_from_uspace_failover_address:
    262220memcpy_to_uspace_failover_address:
    263         jmp %o7 + 8   /* exit point */
    264         mov %g0, %o0  /* return 0 on failure */
     221        jmp     %o7 + 8                 ! exit point
     222        mov     %g0, %o0                ! return 0 on failure
    265223
    266224.global memsetb
     
    274232        nop
    275233
    276 .global early_putchar
    277 early_putchar:
    278         retl
    279         nop
  • kernel/arch/sparc64/src/trap/sun4v/interrupt.c

    re2ea4ab1 r4d1be48  
    111111                        ((void (*)(void)) data1)();
    112112                } else {
    113                         printf("Spurious interrupt on %d, data = %" PRIx64 ".\n",
     113                        printf("Spurious interrupt on %d, data = %lx.\n",
    114114                            CPU->arch.id, data1);
    115115                }
  • kernel/genarch/src/acpi/madt.c

    re2ea4ab1 r4d1be48  
    9595        /*
    9696         * FIXME: The current local APIC driver limits usable
    97          * CPU IDs to 8.
     97         * APIC IDs to 8.
    9898         *
    9999         */
    100         if (i > 7)
     100        if (madt_cpu_apic_id(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             bsp_l_apic;
     113            l_apic_id();
    114114}
    115115
     
    131131};
    132132
    133 static 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;
     133static 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;
    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 == 0)
     149        if (!madt_l_apic_entry_cnt++)
    150150                madt_l_apic_entry_index = i;
    151        
    152         madt_l_apic_entry_cnt++;
    153151       
    154152        if (!(la->flags & 0x1)) {
     
    162160static void madt_io_apic_entry(struct madt_io_apic *ioa, size_t i)
    163161{
    164         if (madt_io_apic_entry_cnt == 0) {
     162        if (!madt_io_apic_entry_cnt++) {
    165163                /* Remember index of the first io apic entry */
    166164                madt_io_apic_entry_index = i;
     
    169167                /* Currently not supported */
    170168        }
    171        
    172         madt_io_apic_entry_cnt++;
    173169}
    174170
     
    194190        /* Count MADT entries */
    195191        unsigned int madt_entries_index_cnt = 0;
    196         for (hdr = acpi_madt->apic_header; hdr < end;
     192        for (hdr = &acpi_madt->apic_header[0]; hdr < end;
    197193            hdr = (struct madt_apic_header *) (((uint8_t *) hdr) + hdr->length))
    198194                madt_entries_index_cnt++;
     
    200196        /* Create MADT APIC entries index array */
    201197        madt_entries_index = (struct madt_apic_header **)
    202             malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header *),
     198            malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header **),
    203199            FRAME_ATOMIC);
    204200        if (!madt_entries_index)
     
    207203        size_t i = 0;
    208204       
    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         }
     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;
    214208       
    215209        /* Sort MADT index structure */
    216         if (!gsort(madt_entries_index, madt_entries_index_cnt,
    217             sizeof(struct madt_apic_header *), madt_cmp, NULL))
    218                 panic("Sorting error.");
     210        qsort(madt_entries_index, madt_entries_index_cnt, sizeof(uintptr_t),
     211            &madt_cmp);
    219212       
    220213        /* Parse MADT entries */
  • kernel/generic/include/console/console.h

    re2ea4ab1 r4d1be48  
    5656extern outdev_t *stdout;
    5757
    58 extern void early_putchar(wchar_t);
    59 
    6058extern indev_t *stdin_wire(void);
    6159extern void stdout_wire(outdev_t *outdev);
  • kernel/generic/include/context.h

    re2ea4ab1 r4d1be48  
    8787 *
    8888 * @param ctx Context structure.
    89  *
    9089 */
    91 static inline void __attribute__((no_instrument_function))
    92     context_restore(context_t *ctx)
     90static inline void context_restore(context_t *ctx)
    9391{
    9492        context_restore_arch(ctx);
  • kernel/generic/include/debug.h

    re2ea4ab1 r4d1be48  
    9393#define LOG(format, ...) \
    9494        do { \
    95                 printf("%s() from %s at %s:%u: " format "\n", __func__, \
    96                     symtab_fmt_name_lookup(CALLER), __FILE__, __LINE__, \
    97                     ##__VA_ARGS__); \
     95                printf("%s->%s() at %s:%u: " format "\n", symtab_fmt_name_lookup(CALLER), \
     96                    __func__, __FILE__, __LINE__, ##__VA_ARGS__); \
     97        } while (0)
     98
     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; \
    98111        } while (0)
    99112
     
    101114
    102115#define LOG(format, ...)
     116#define LOG_EXEC(fnc)     fnc
    103117
    104 #endif /* CONFIG_LOG */
    105 
    106 #ifdef CONFIG_TRACE
    107 
    108 extern void __cyg_profile_func_enter(void *, void *);
    109 extern void __cyg_profile_func_exit(void *, void *);
    110 
    111 #endif /* CONFIG_TRACE */
     118#endif /* CONFOG_LOG */
    112119
    113120#endif
  • kernel/generic/include/macros.h

    re2ea4ab1 r4d1be48  
    4747 * @param sz2 Size of the second interval.
    4848 */
    49 static inline int __attribute__((no_instrument_function))
    50     overlaps(uintptr_t s1, size_t sz1, uintptr_t s2, size_t sz2)
     49static inline int overlaps(uintptr_t s1, size_t sz1, uintptr_t s2, size_t sz2)
    5150{
    5251        uintptr_t e1 = s1 + sz1;
  • kernel/generic/include/sort.h

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

    re2ea4ab1 r4d1be48  
    3333/**
    3434 * @file
    35  * @brief B+tree implementation.
     35 * @brief       B+tree implementation.
    3636 *
    3737 * This file implements B+tree type and operations.
     
    5454#include <print.h>
    5555
     56static void btree_destroy_subtree(btree_node_t *root);
     57static void _btree_insert(btree_t *t, btree_key_t key, void *value, btree_node_t *rsubtree, btree_node_t *node);
     58static void _btree_remove(btree_t *t, btree_key_t key, btree_node_t *node);
     59static void node_initialize(btree_node_t *node);
     60static void node_insert_key_and_lsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *lsubtree);
     61static void node_insert_key_and_rsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree);
     62static void node_remove_key_and_lsubtree(btree_node_t *node, btree_key_t key);
     63static void node_remove_key_and_rsubtree(btree_node_t *node, btree_key_t key);
     64static btree_node_t *node_split(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree, btree_key_t *median);
     65static btree_node_t *node_combine(btree_node_t *node);
     66static size_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right);
     67static void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, size_t idx);
     68static void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, size_t idx);
     69static bool try_insert_by_rotation_to_left(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree);
     70static bool try_insert_by_rotation_to_right(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree);
     71static bool try_rotation_from_left(btree_node_t *rnode);
     72static bool try_rotation_from_right(btree_node_t *lnode);
     73
     74#define ROOT_NODE(n)            (!(n)->parent)
     75#define INDEX_NODE(n)           ((n)->subtree[0] != NULL)
     76#define LEAF_NODE(n)            ((n)->subtree[0] == NULL)
     77
     78#define FILL_FACTOR             ((BTREE_M-1)/2)
     79
     80#define MEDIAN_LOW_INDEX(n)     (((n)->keys-1)/2)
     81#define MEDIAN_HIGH_INDEX(n)    ((n)->keys/2)
     82#define MEDIAN_LOW(n)           ((n)->key[MEDIAN_LOW_INDEX((n))]);
     83#define MEDIAN_HIGH(n)          ((n)->key[MEDIAN_HIGH_INDEX((n))]);
     84
    5685static slab_cache_t *btree_node_slab;
    57 
    58 #define ROOT_NODE(n)   (!(n)->parent)
    59 #define INDEX_NODE(n)  ((n)->subtree[0] != NULL)
    60 #define LEAF_NODE(n)   ((n)->subtree[0] == NULL)
    61 
    62 #define FILL_FACTOR  ((BTREE_M - 1) / 2)
    63 
    64 #define MEDIAN_LOW_INDEX(n)   (((n)->keys-1) / 2)
    65 #define MEDIAN_HIGH_INDEX(n)  ((n)->keys / 2)
    66 #define MEDIAN_LOW(n)         ((n)->key[MEDIAN_LOW_INDEX((n))]);
    67 #define MEDIAN_HIGH(n)        ((n)->key[MEDIAN_HIGH_INDEX((n))]);
    6886
    6987/** Initialize B-trees. */
    7088void btree_init(void)
    7189{
    72         btree_node_slab = slab_cache_create("btree_node_slab",
    73             sizeof(btree_node_t), 0, NULL, NULL, SLAB_CACHE_MAGDEFERRED);
    74 }
    75 
    76 /** Initialize B-tree node.
    77  *
    78  * @param node B-tree node.
    79  *
    80  */
    81 static void node_initialize(btree_node_t *node)
    82 {
    83         unsigned int i;
    84        
    85         node->keys = 0;
    86        
    87         /* Clean also space for the extra key. */
    88         for (i = 0; i < BTREE_MAX_KEYS + 1; i++) {
    89                 node->key[i] = 0;
    90                 node->value[i] = NULL;
    91                 node->subtree[i] = NULL;
    92         }
    93        
    94         node->subtree[i] = NULL;
    95         node->parent = NULL;
    96        
    97         link_initialize(&node->leaf_link);
    98         link_initialize(&node->bfs_link);
    99         node->depth = 0;
     90        btree_node_slab = slab_cache_create("btree_node_slab", sizeof(btree_node_t), 0, NULL, NULL, SLAB_CACHE_MAGDEFERRED);
    10091}
    10192
     
    10394 *
    10495 * @param t B-tree.
    105  *
    10696 */
    10797void btree_create(btree_t *t)
     
    113103}
    114104
     105/** Destroy empty B-tree. */
     106void btree_destroy(btree_t *t)
     107{
     108        btree_destroy_subtree(t->root);
     109}
     110
     111/** Insert key-value pair into B-tree.
     112 *
     113 * @param t B-tree.
     114 * @param key Key to be inserted.
     115 * @param value Value to be inserted.
     116 * @param leaf_node Leaf node where the insertion should begin.
     117 */
     118void btree_insert(btree_t *t, btree_key_t key, void *value, btree_node_t *leaf_node)
     119{
     120        btree_node_t *lnode;
     121       
     122        ASSERT(value);
     123       
     124        lnode = leaf_node;
     125        if (!lnode) {
     126                if (btree_search(t, key, &lnode)) {
     127                        panic("B-tree %p already contains key %" PRIu64 ".", t, key);
     128                }
     129        }
     130       
     131        _btree_insert(t, key, value, NULL, lnode);
     132}
     133
    115134/** Destroy subtree rooted in a node.
    116135 *
    117136 * @param root Root of the subtree.
    118  *
    119  */
    120 static void btree_destroy_subtree(btree_node_t *root)
     137 */
     138void btree_destroy_subtree(btree_node_t *root)
    121139{
    122140        size_t i;
    123        
     141
    124142        if (root->keys) {
    125143                for (i = 0; i < root->keys + 1; i++) {
     
    128146                }
    129147        }
    130        
    131148        slab_free(btree_node_slab, root);
    132149}
    133150
    134 /** Destroy empty B-tree. */
    135 void btree_destroy(btree_t *t)
    136 {
    137         btree_destroy_subtree(t->root);
    138 }
    139 
    140 /** Insert key-value-rsubtree triplet into B-tree node.
    141  *
    142  * It is actually possible to have more keys than BTREE_MAX_KEYS.
    143  * This feature is used during splitting the node when the
    144  * number of keys is BTREE_MAX_KEYS + 1. Insert by left rotation
    145  * also makes use of this feature.
    146  *
    147  * @param node     B-tree node into wich the new key is to be inserted.
    148  * @param key      The key to be inserted.
    149  * @param value    Pointer to value to be inserted.
    150  * @param rsubtree Pointer to the right subtree.
    151  *
    152  */
    153 static void node_insert_key_and_rsubtree(btree_node_t *node, btree_key_t key,
    154     void *value, btree_node_t *rsubtree)
    155 {
    156         size_t i;
    157        
    158         for (i = 0; i < node->keys; i++) {
    159                 if (key < node->key[i]) {
    160                         size_t j;
    161                        
    162                         for (j = node->keys; j > i; j--) {
    163                                 node->key[j] = node->key[j - 1];
    164                                 node->value[j] = node->value[j - 1];
    165                                 node->subtree[j + 1] = node->subtree[j];
    166                         }
    167                        
    168                         break;
    169                 }
    170         }
    171        
    172         node->key[i] = key;
    173         node->value[i] = value;
    174         node->subtree[i + 1] = rsubtree;
    175         node->keys++;
    176 }
    177 
    178 /** Find key by its left or right subtree.
    179  *
    180  * @param node    B-tree node.
    181  * @param subtree Left or right subtree of a key found in node.
    182  * @param right   If true, subtree is a right subtree. If false,
    183  *                subtree is a left subtree.
    184  *
    185  * @return Index of the key associated with the subtree.
    186  *
    187  */
    188 static size_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree,
    189     bool right)
    190 {
    191         size_t i;
    192        
    193         for (i = 0; i < node->keys + 1; i++) {
    194                 if (subtree == node->subtree[i])
    195                         return i - (int) (right != false);
    196         }
    197        
    198         panic("Node %p does not contain subtree %p.", node, subtree);
    199 }
    200 
    201 /** Remove key and its left subtree pointer from B-tree node.
    202  *
    203  * Remove the key and eliminate gaps in node->key array.
    204  * Note that the value pointer and the left subtree pointer
    205  * is removed from the node as well.
    206  *
    207  * @param node B-tree node.
    208  * @param key  Key to be removed.
    209  *
    210  */
    211 static void node_remove_key_and_lsubtree(btree_node_t *node, btree_key_t key)
    212 {
    213         size_t i;
    214         size_t j;
    215        
    216         for (i = 0; i < node->keys; i++) {
    217                 if (key == node->key[i]) {
    218                         for (j = i + 1; j < node->keys; j++) {
    219                                 node->key[j - 1] = node->key[j];
    220                                 node->value[j - 1] = node->value[j];
    221                                 node->subtree[j - 1] = node->subtree[j];
    222                         }
    223                        
    224                         node->subtree[j - 1] = node->subtree[j];
    225                         node->keys--;
    226                        
    227                         return;
    228                 }
    229         }
    230        
    231         panic("Node %p does not contain key %" PRIu64 ".", node, key);
    232 }
    233 
    234 /** Remove key and its right subtree pointer from B-tree node.
    235  *
    236  * Remove the key and eliminate gaps in node->key array.
    237  * Note that the value pointer and the right subtree pointer
    238  * is removed from the node as well.
    239  *
    240  * @param node B-tree node.
    241  * @param key  Key to be removed.
    242  *
    243  */
    244 static void node_remove_key_and_rsubtree(btree_node_t *node, btree_key_t key)
    245 {
    246         size_t i, j;
    247        
    248         for (i = 0; i < node->keys; i++) {
    249                 if (key == node->key[i]) {
    250                         for (j = i + 1; j < node->keys; j++) {
    251                                 node->key[j - 1] = node->key[j];
    252                                 node->value[j - 1] = node->value[j];
    253                                 node->subtree[j] = node->subtree[j + 1];
    254                         }
    255                        
    256                         node->keys--;
    257                         return;
    258                 }
    259         }
    260        
    261         panic("Node %p does not contain key %" PRIu64 ".", node, key);
    262 }
    263 
    264 /** Insert key-value-lsubtree triplet into B-tree node.
    265  *
    266  * It is actually possible to have more keys than BTREE_MAX_KEYS.
    267  * This feature is used during insert by right rotation.
    268  *
    269  * @param node     B-tree node into wich the new key is to be inserted.
    270  * @param key      The key to be inserted.
    271  * @param value    Pointer to value to be inserted.
    272  * @param lsubtree Pointer to the left subtree.
    273  *
    274  */
    275 static void node_insert_key_and_lsubtree(btree_node_t *node, btree_key_t key,
    276     void *value, btree_node_t *lsubtree)
    277 {
    278         size_t i;
    279        
    280         for (i = 0; i < node->keys; i++) {
    281                 if (key < node->key[i]) {
    282                         size_t j;
    283                        
    284                         for (j = node->keys; j > i; j--) {
    285                                 node->key[j] = node->key[j - 1];
    286                                 node->value[j] = node->value[j - 1];
    287                                 node->subtree[j + 1] = node->subtree[j];
    288                         }
    289                        
    290                         node->subtree[j + 1] = node->subtree[j];
    291                         break;
    292                 }
    293         }
    294        
    295         node->key[i] = key;
    296         node->value[i] = value;
    297         node->subtree[i] = lsubtree;
    298        
    299         node->keys++;
    300 }
    301 
    302 /** Rotate one key-value-rsubtree triplet from the left sibling to the right sibling.
    303  *
    304  * The biggest key and its value and right subtree is rotated
    305  * from the left node to the right. If the node is an index node,
    306  * than the parent node key belonging to the left node takes part
    307  * in the rotation.
    308  *
    309  * @param lnode Left sibling.
    310  * @param rnode Right sibling.
    311  * @param idx   Index of the parent node key that is taking part
    312  *              in the rotation.
    313  *
    314  */
    315 static void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, size_t idx)
    316 {
    317         btree_key_t key = lnode->key[lnode->keys - 1];
    318        
    319         if (LEAF_NODE(lnode)) {
    320                 void *value = lnode->value[lnode->keys - 1];
    321                
    322                 node_remove_key_and_rsubtree(lnode, key);
    323                 node_insert_key_and_lsubtree(rnode, key, value, NULL);
    324                 lnode->parent->key[idx] = key;
    325         } else {
    326                 btree_node_t *rsubtree = lnode->subtree[lnode->keys];
    327                
    328                 node_remove_key_and_rsubtree(lnode, key);
    329                 node_insert_key_and_lsubtree(rnode, lnode->parent->key[idx], NULL, rsubtree);
    330                 lnode->parent->key[idx] = key;
    331                
    332                 /* Fix parent link of the reconnected right subtree. */
    333                 rsubtree->parent = rnode;
    334         }
    335 }
    336 
    337 /** Rotate one key-value-lsubtree triplet from the right sibling to the left sibling.
    338  *
    339  * The smallest key and its value and left subtree is rotated
    340  * from the right node to the left. If the node is an index node,
    341  * than the parent node key belonging to the right node takes part
    342  * in the rotation.
    343  *
    344  * @param lnode Left sibling.
    345  * @param rnode Right sibling.
    346  * @param idx   Index of the parent node key that is taking part
    347  *              in the rotation.
    348  *
    349  */
    350 static void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, size_t idx)
    351 {
    352         btree_key_t key = rnode->key[0];
    353        
    354         if (LEAF_NODE(rnode)) {
    355                 void *value = rnode->value[0];
    356                
    357                 node_remove_key_and_lsubtree(rnode, key);
    358                 node_insert_key_and_rsubtree(lnode, key, value, NULL);
    359                 rnode->parent->key[idx] = rnode->key[0];
    360         } else {
    361                 btree_node_t *lsubtree = rnode->subtree[0];
    362                
    363                 node_remove_key_and_lsubtree(rnode, key);
    364                 node_insert_key_and_rsubtree(lnode, rnode->parent->key[idx], NULL, lsubtree);
    365                 rnode->parent->key[idx] = key;
    366                
    367                 /* Fix parent link of the reconnected left subtree. */
    368                 lsubtree->parent = lnode;
    369         }
    370 }
    371 
    372 /** Insert key-value-rsubtree triplet and rotate the node to the left, if this operation can be done.
    373  *
    374  * Left sibling of the node (if it exists) is checked for free space.
    375  * If there is free space, the key is inserted and the smallest key of
    376  * the node is moved there. The index node which is the parent of both
    377  * nodes is fixed.
    378  *
    379  * @param node     B-tree node.
    380  * @param inskey   Key to be inserted.
    381  * @param insvalue Value to be inserted.
    382  * @param rsubtree Right subtree of inskey.
    383  *
    384  * @return True if the rotation was performed, false otherwise.
    385  *
    386  */
    387 static bool try_insert_by_rotation_to_left(btree_node_t *node,
    388     btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
    389 {
    390         size_t idx;
    391         btree_node_t *lnode;
    392        
    393         /*
    394          * If this is root node, the rotation can not be done.
    395          */
    396         if (ROOT_NODE(node))
    397                 return false;
    398        
    399         idx = find_key_by_subtree(node->parent, node, true);
    400         if ((int) idx == -1) {
    401                 /*
    402                  * If this node is the leftmost subtree of its parent,
    403                  * the rotation can not be done.
    404                  */
    405                 return false;
    406         }
    407        
    408         lnode = node->parent->subtree[idx];
    409         if (lnode->keys < BTREE_MAX_KEYS) {
    410                 /*
    411                  * The rotaion can be done. The left sibling has free space.
    412                  */
    413                 node_insert_key_and_rsubtree(node, inskey, insvalue, rsubtree);
    414                 rotate_from_right(lnode, node, idx);
    415                 return true;
    416         }
    417        
    418         return false;
    419 }
    420 
    421 /** Insert key-value-rsubtree triplet and rotate the node to the right, if this operation can be done.
    422  *
    423  * Right sibling of the node (if it exists) is checked for free space.
    424  * If there is free space, the key is inserted and the biggest key of
    425  * the node is moved there. The index node which is the parent of both
    426  * nodes is fixed.
    427  *
    428  * @param node     B-tree node.
    429  * @param inskey   Key to be inserted.
    430  * @param insvalue Value to be inserted.
    431  * @param rsubtree Right subtree of inskey.
    432  *
    433  * @return True if the rotation was performed, false otherwise.
    434  *
    435  */
    436 static bool try_insert_by_rotation_to_right(btree_node_t *node,
    437     btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
    438 {
    439         size_t idx;
    440         btree_node_t *rnode;
    441        
    442         /*
    443          * If this is root node, the rotation can not be done.
    444          */
    445         if (ROOT_NODE(node))
    446                 return false;
    447        
    448         idx = find_key_by_subtree(node->parent, node, false);
    449         if (idx == node->parent->keys) {
    450                 /*
    451                  * If this node is the rightmost subtree of its parent,
    452                  * the rotation can not be done.
    453                  */
    454                 return false;
    455         }
    456        
    457         rnode = node->parent->subtree[idx + 1];
    458         if (rnode->keys < BTREE_MAX_KEYS) {
    459                 /*
    460                  * The rotaion can be done. The right sibling has free space.
    461                  */
    462                 node_insert_key_and_rsubtree(node, inskey, insvalue, rsubtree);
    463                 rotate_from_left(node, rnode, idx);
    464                 return true;
    465         }
    466        
    467         return false;
    468 }
    469 
    470 /** Split full B-tree node and insert new key-value-right-subtree triplet.
    471  *
    472  * This function will split a node and return a pointer to a newly created
    473  * node containing keys greater than or equal to the greater of medians
    474  * (or median) of the old keys and the newly added key. It will also write
    475  * the median key to a memory address supplied by the caller.
    476  *
    477  * If the node being split is an index node, the median will not be
    478  * included in the new node. If the node is a leaf node,
    479  * the median will be copied there.
    480  *
    481  * @param node     B-tree node wich is going to be split.
    482  * @param key      The key to be inserted.
    483  * @param value    Pointer to the value to be inserted.
    484  * @param rsubtree Pointer to the right subtree of the key being added.
    485  * @param median   Address in memory, where the median key will be stored.
    486  *
    487  * @return Newly created right sibling of node.
    488  *
    489  */
    490 static btree_node_t *node_split(btree_node_t *node, btree_key_t key,
    491     void *value, btree_node_t *rsubtree, btree_key_t *median)
    492 {
    493         btree_node_t *rnode;
    494         size_t i;
    495         size_t j;
    496        
    497         ASSERT(median);
    498         ASSERT(node->keys == BTREE_MAX_KEYS);
    499        
    500         /*
    501          * Use the extra space to store the extra node.
    502          */
    503         node_insert_key_and_rsubtree(node, key, value, rsubtree);
    504        
    505         /*
    506          * Compute median of keys.
    507          */
    508         *median = MEDIAN_HIGH(node);
    509        
    510         /*
    511          * Allocate and initialize new right sibling.
    512          */
    513         rnode = (btree_node_t *) slab_alloc(btree_node_slab, 0);
    514         node_initialize(rnode);
    515         rnode->parent = node->parent;
    516         rnode->depth = node->depth;
    517        
    518         /*
    519          * Copy big keys, values and subtree pointers to the new right sibling.
    520          * If this is an index node, do not copy the median.
    521          */
    522         i = (size_t) INDEX_NODE(node);
    523         for (i += MEDIAN_HIGH_INDEX(node), j = 0; i < node->keys; i++, j++) {
    524                 rnode->key[j] = node->key[i];
    525                 rnode->value[j] = node->value[i];
    526                 rnode->subtree[j] = node->subtree[i];
    527                
    528                 /*
    529                  * Fix parent links in subtrees.
    530                  */
    531                 if (rnode->subtree[j])
    532                         rnode->subtree[j]->parent = rnode;
    533         }
    534        
    535         rnode->subtree[j] = node->subtree[i];
    536         if (rnode->subtree[j])
    537                 rnode->subtree[j]->parent = rnode;
    538        
    539         rnode->keys = j;  /* Set number of keys of the new node. */
    540         node->keys /= 2;  /* Shrink the old node. */
    541        
    542         return rnode;
    543 }
    544 
    545151/** Recursively insert into B-tree.
    546152 *
    547  * @param t        B-tree.
    548  * @param key      Key to be inserted.
    549  * @param value    Value to be inserted.
     153 * @param t B-tree.
     154 * @param key Key to be inserted.
     155 * @param value Value to be inserted.
    550156 * @param rsubtree Right subtree of the inserted key.
    551  * @param node     Start inserting into this node.
    552  *
    553  */
    554 static void _btree_insert(btree_t *t, btree_key_t key, void *value,
    555     btree_node_t *rsubtree, btree_node_t *node)
     157 * @param node Start inserting into this node.
     158 */
     159void _btree_insert(btree_t *t, btree_key_t key, void *value, btree_node_t *rsubtree, btree_node_t *node)
    556160{
    557161        if (node->keys < BTREE_MAX_KEYS) {
     
    579183                 * bigger keys (i.e. the new node) into its parent.
    580184                 */
    581                
     185
    582186                rnode = node_split(node, key, value, rsubtree, &median);
    583                
     187
    584188                if (LEAF_NODE(node)) {
    585189                        list_prepend(&rnode->leaf_link, &node->leaf_link);
     
    598202                         * Left-hand side subtree will be the old root (i.e. node).
    599203                         * Right-hand side subtree will be rnode.
    600                          */
     204                         */                     
    601205                        t->root->subtree[0] = node;
    602                        
     206
    603207                        t->root->depth = node->depth + 1;
    604208                }
    605209                _btree_insert(t, median, NULL, rnode, node->parent);
    606         }
    607 }
    608 
    609 /** Insert key-value pair into B-tree.
    610  *
    611  * @param t         B-tree.
    612  * @param key       Key to be inserted.
    613  * @param value     Value to be inserted.
    614  * @param leaf_node Leaf node where the insertion should begin.
    615  *
    616  */
    617 void btree_insert(btree_t *t, btree_key_t key, void *value,
    618     btree_node_t *leaf_node)
     210        }       
     211               
     212}
     213
     214/** Remove B-tree node.
     215 *
     216 * @param t B-tree.
     217 * @param key Key to be removed from the B-tree along with its associated value.
     218 * @param leaf_node If not NULL, pointer to the leaf node where the key is found.
     219 */
     220void btree_remove(btree_t *t, btree_key_t key, btree_node_t *leaf_node)
    619221{
    620222        btree_node_t *lnode;
    621        
    622         ASSERT(value);
    623223       
    624224        lnode = leaf_node;
    625225        if (!lnode) {
    626                 if (btree_search(t, key, &lnode))
    627                         panic("B-tree %p already contains key %" PRIu64 ".", t, key);
    628         }
    629        
    630         _btree_insert(t, key, value, NULL, lnode);
    631 }
    632 
    633 /** Rotate in a key from the left sibling or from the index node, if this operation can be done.
    634  *
    635  * @param rnode Node into which to add key from its left sibling
    636  *              or from the index node.
    637  *
    638  * @return True if the rotation was performed, false otherwise.
    639  *
    640  */
    641 static bool try_rotation_from_left(btree_node_t *rnode)
    642 {
    643         size_t idx;
    644         btree_node_t *lnode;
    645        
    646         /*
    647          * If this is root node, the rotation can not be done.
    648          */
    649         if (ROOT_NODE(rnode))
    650                 return false;
    651        
    652         idx = find_key_by_subtree(rnode->parent, rnode, true);
    653         if ((int) idx == -1) {
    654                 /*
    655                  * If this node is the leftmost subtree of its parent,
    656                  * the rotation can not be done.
    657                  */
    658                 return false;
    659         }
    660        
    661         lnode = rnode->parent->subtree[idx];
    662         if (lnode->keys > FILL_FACTOR) {
    663                 rotate_from_left(lnode, rnode, idx);
    664                 return true;
    665         }
    666        
    667         return false;
    668 }
    669 
    670 /** Rotate in a key from the right sibling or from the index node, if this operation can be done.
    671  *
    672  * @param lnode Node into which to add key from its right sibling
    673  *              or from the index node.
    674  *
    675  * @return True if the rotation was performed, false otherwise.
    676  *
    677  */
    678 static bool try_rotation_from_right(btree_node_t *lnode)
    679 {
    680         size_t idx;
    681         btree_node_t *rnode;
    682        
    683         /*
    684          * If this is root node, the rotation can not be done.
    685          */
    686         if (ROOT_NODE(lnode))
    687                 return false;
    688        
    689         idx = find_key_by_subtree(lnode->parent, lnode, false);
    690         if (idx == lnode->parent->keys) {
    691                 /*
    692                  * If this node is the rightmost subtree of its parent,
    693                  * the rotation can not be done.
    694                  */
    695                 return false;
    696         }
    697        
    698         rnode = lnode->parent->subtree[idx + 1];
    699         if (rnode->keys > FILL_FACTOR) {
    700                 rotate_from_right(lnode, rnode, idx);
    701                 return true;
    702         }
    703        
    704         return false;
    705 }
    706 
    707 /** Combine node with any of its siblings.
    708  *
    709  * The siblings are required to be below the fill factor.
    710  *
    711  * @param node Node to combine with one of its siblings.
    712  *
    713  * @return Pointer to the rightmost of the two nodes.
    714  *
    715  */
    716 static btree_node_t *node_combine(btree_node_t *node)
    717 {
    718         size_t idx;
    719         btree_node_t *rnode;
    720         size_t i;
    721        
    722         ASSERT(!ROOT_NODE(node));
    723        
    724         idx = find_key_by_subtree(node->parent, node, false);
    725         if (idx == node->parent->keys) {
    726                 /*
    727                  * Rightmost subtree of its parent, combine with the left sibling.
    728                  */
    729                 idx--;
    730                 rnode = node;
    731                 node = node->parent->subtree[idx];
    732         } else
    733                 rnode = node->parent->subtree[idx + 1];
    734        
    735         /* Index nodes need to insert parent node key in between left and right node. */
    736         if (INDEX_NODE(node))
    737                 node->key[node->keys++] = node->parent->key[idx];
    738        
    739         /* Copy the key-value-subtree triplets from the right node. */
    740         for (i = 0; i < rnode->keys; i++) {
    741                 node->key[node->keys + i] = rnode->key[i];
    742                 node->value[node->keys + i] = rnode->value[i];
    743                
    744                 if (INDEX_NODE(node)) {
    745                         node->subtree[node->keys + i] = rnode->subtree[i];
    746                         rnode->subtree[i]->parent = node;
    747                 }
    748         }
    749        
    750         if (INDEX_NODE(node)) {
    751                 node->subtree[node->keys + i] = rnode->subtree[i];
    752                 rnode->subtree[i]->parent = node;
    753         }
    754        
    755         node->keys += rnode->keys;
    756         return rnode;
     226                if (!btree_search(t, key, &lnode)) {
     227                        panic("B-tree %p does not contain key %" PRIu64 ".", t, key);
     228                }
     229        }
     230       
     231        _btree_remove(t, key, lnode);
    757232}
    758233
    759234/** Recursively remove B-tree node.
    760235 *
    761  * @param t    B-tree.
    762  * @param key  Key to be removed from the B-tree along with its associated value.
     236 * @param t B-tree.
     237 * @param key Key to be removed from the B-tree along with its associated value.
    763238 * @param node Node where the key being removed resides.
    764  *
    765  */
    766 static void _btree_remove(btree_t *t, btree_key_t key, btree_node_t *node)
     239 */
     240void _btree_remove(btree_t *t, btree_key_t key, btree_node_t *node)
    767241{
    768242        if (ROOT_NODE(node)) {
    769                 if ((node->keys == 1) && (node->subtree[0])) {
     243                if (node->keys == 1 && node->subtree[0]) {
    770244                        /*
    771245                         * Free the current root and set new root.
     
    783257                        node_remove_key_and_rsubtree(node, key);
    784258                }
    785                
    786259                return;
    787260        }
     
    798271        if (node->keys > FILL_FACTOR) {
    799272                size_t i;
    800                
     273
    801274                /*
    802275                 * The key can be immediatelly removed.
     
    807280                 */
    808281                node_remove_key_and_rsubtree(node, key);
    809                
    810282                for (i = 0; i < node->parent->keys; i++) {
    811283                        if (node->parent->key[i] == key)
    812284                                node->parent->key[i] = node->key[0];
    813285                }
     286               
    814287        } else {
    815288                size_t idx;
    816                 btree_node_t *rnode;
    817                 btree_node_t *parent;
    818                
     289                btree_node_t *rnode, *parent;
     290
    819291                /*
    820292                 * The node is below the fill factor as well as its left and right sibling.
     
    826298                node_remove_key_and_rsubtree(node, key);
    827299                rnode = node_combine(node);
    828                
    829300                if (LEAF_NODE(rnode))
    830301                        list_remove(&rnode->leaf_link);
    831                
    832302                idx = find_key_by_subtree(parent, rnode, true);
    833303                ASSERT((int) idx != -1);
     
    837307}
    838308
    839 /** Remove B-tree node.
    840  *
    841  * @param t         B-tree.
    842  * @param key       Key to be removed from the B-tree along
    843  *                  with its associated value.
    844  * @param leaf_node If not NULL, pointer to the leaf node where
    845  *                  the key is found.
    846  *
    847  */
    848 void btree_remove(btree_t *t, btree_key_t key, btree_node_t *leaf_node)
    849 {
    850         btree_node_t *lnode;
    851        
    852         lnode = leaf_node;
    853         if (!lnode) {
    854                 if (!btree_search(t, key, &lnode))
    855                         panic("B-tree %p does not contain key %" PRIu64 ".", t, key);
    856         }
    857        
    858         _btree_remove(t, key, lnode);
    859 }
    860 
    861309/** Search key in a B-tree.
    862310 *
    863  * @param t         B-tree.
    864  * @param key       Key to be searched.
     311 * @param t B-tree.
     312 * @param key Key to be searched.
    865313 * @param leaf_node Address where to put pointer to visited leaf node.
    866314 *
    867315 * @return Pointer to value or NULL if there is no such key.
    868  *
    869316 */
    870317void *btree_search(btree_t *t, btree_key_t key, btree_node_t **leaf_node)
     
    876323         */
    877324        for (cur = t->root; cur; cur = next) {
    878                 /*
    879                  * Last iteration will set this with proper
    880                  * leaf node address.
    881                  */
     325
     326                /* Last iteration will set this with proper leaf node address. */
    882327                *leaf_node = cur;
    883328               
     
    892337                        void *val;
    893338                        size_t i;
    894                        
     339               
    895340                        /*
    896341                         * Now if the key is smaller than cur->key[i]
     
    902347                                        next = cur->subtree[i];
    903348                                        val = cur->value[i - 1];
    904                                        
     349
    905350                                        if (LEAF_NODE(cur))
    906351                                                return key == cur->key[i - 1] ? val : NULL;
    907                                        
     352
    908353                                        goto descend;
    909                                 }
     354                                } 
    910355                        }
    911356                       
    912357                        /*
    913                          * Last possibility is that the key is
    914                          * in the rightmost subtree.
     358                         * Last possibility is that the key is in the rightmost subtree.
    915359                         */
    916360                        next = cur->subtree[i];
    917361                        val = cur->value[i - 1];
    918                        
    919362                        if (LEAF_NODE(cur))
    920363                                return key == cur->key[i - 1] ? val : NULL;
    921364                }
    922365                descend:
    923                 ;
    924         }
    925        
     366                        ;
     367        }
     368
    926369        /*
    927          * The key was not found in the *leaf_node and
    928          * is smaller than any of its keys.
     370         * The key was not found in the *leaf_node and is smaller than any of its keys.
    929371         */
    930372        return NULL;
     
    933375/** Return pointer to B-tree leaf node's left neighbour.
    934376 *
    935  * @param t    B-tree.
     377 * @param t B-tree.
    936378 * @param node Node whose left neighbour will be returned.
    937379 *
    938  * @return Left neighbour of the node or NULL if the node
    939  *         does not have the left neighbour.
    940  *
     380 * @return Left neighbour of the node or NULL if the node does not have the left neighbour.
    941381 */
    942382btree_node_t *btree_leaf_node_left_neighbour(btree_t *t, btree_node_t *node)
    943383{
    944384        ASSERT(LEAF_NODE(node));
    945        
    946385        if (node->leaf_link.prev != &t->leaf_head)
    947386                return list_get_instance(node->leaf_link.prev, btree_node_t, leaf_link);
     
    952391/** Return pointer to B-tree leaf node's right neighbour.
    953392 *
    954  * @param t    B-tree.
     393 * @param t B-tree.
    955394 * @param node Node whose right neighbour will be returned.
    956395 *
    957  * @return Right neighbour of the node or NULL if the node
    958  *         does not have the right neighbour.
    959  *
     396 * @return Right neighbour of the node or NULL if the node does not have the right neighbour.
    960397 */
    961398btree_node_t *btree_leaf_node_right_neighbour(btree_t *t, btree_node_t *node)
    962399{
    963400        ASSERT(LEAF_NODE(node));
    964        
    965401        if (node->leaf_link.next != &t->leaf_head)
    966402                return list_get_instance(node->leaf_link.next, btree_node_t, leaf_link);
     
    969405}
    970406
     407/** Initialize B-tree node.
     408 *
     409 * @param node B-tree node.
     410 */
     411void node_initialize(btree_node_t *node)
     412{
     413        int i;
     414
     415        node->keys = 0;
     416       
     417        /* Clean also space for the extra key. */
     418        for (i = 0; i < BTREE_MAX_KEYS + 1; i++) {
     419                node->key[i] = 0;
     420                node->value[i] = NULL;
     421                node->subtree[i] = NULL;
     422        }
     423        node->subtree[i] = NULL;
     424       
     425        node->parent = NULL;
     426       
     427        link_initialize(&node->leaf_link);
     428
     429        link_initialize(&node->bfs_link);
     430        node->depth = 0;
     431}
     432
     433/** Insert key-value-lsubtree triplet into B-tree node.
     434 *
     435 * It is actually possible to have more keys than BTREE_MAX_KEYS.
     436 * This feature is used during insert by right rotation.
     437 *
     438 * @param node B-tree node into wich the new key is to be inserted.
     439 * @param key The key to be inserted.
     440 * @param value Pointer to value to be inserted.
     441 * @param lsubtree Pointer to the left subtree.
     442 */
     443void node_insert_key_and_lsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *lsubtree)
     444{
     445        size_t i;
     446
     447        for (i = 0; i < node->keys; i++) {
     448                if (key < node->key[i]) {
     449                        size_t j;
     450               
     451                        for (j = node->keys; j > i; j--) {
     452                                node->key[j] = node->key[j - 1];
     453                                node->value[j] = node->value[j - 1];
     454                                node->subtree[j + 1] = node->subtree[j];
     455                        }
     456                        node->subtree[j + 1] = node->subtree[j];
     457                        break; 
     458                }
     459        }
     460        node->key[i] = key;
     461        node->value[i] = value;
     462        node->subtree[i] = lsubtree;
     463                       
     464        node->keys++;
     465}
     466
     467/** Insert key-value-rsubtree triplet into B-tree node.
     468 *
     469 * It is actually possible to have more keys than BTREE_MAX_KEYS.
     470 * This feature is used during splitting the node when the
     471 * number of keys is BTREE_MAX_KEYS + 1. Insert by left rotation
     472 * also makes use of this feature.
     473 *
     474 * @param node B-tree node into wich the new key is to be inserted.
     475 * @param key The key to be inserted.
     476 * @param value Pointer to value to be inserted.
     477 * @param rsubtree Pointer to the right subtree.
     478 */
     479void node_insert_key_and_rsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree)
     480{
     481        size_t i;
     482
     483        for (i = 0; i < node->keys; i++) {
     484                if (key < node->key[i]) {
     485                        size_t j;
     486               
     487                        for (j = node->keys; j > i; j--) {
     488                                node->key[j] = node->key[j - 1];
     489                                node->value[j] = node->value[j - 1];
     490                                node->subtree[j + 1] = node->subtree[j];
     491                        }
     492                        break; 
     493                }
     494        }
     495        node->key[i] = key;
     496        node->value[i] = value;
     497        node->subtree[i + 1] = rsubtree;
     498                       
     499        node->keys++;
     500}
     501
     502/** Remove key and its left subtree pointer from B-tree node.
     503 *
     504 * Remove the key and eliminate gaps in node->key array.
     505 * Note that the value pointer and the left subtree pointer
     506 * is removed from the node as well.
     507 *
     508 * @param node B-tree node.
     509 * @param key Key to be removed.
     510 */
     511void node_remove_key_and_lsubtree(btree_node_t *node, btree_key_t key)
     512{
     513        size_t i, j;
     514       
     515        for (i = 0; i < node->keys; i++) {
     516                if (key == node->key[i]) {
     517                        for (j = i + 1; j < node->keys; j++) {
     518                                node->key[j - 1] = node->key[j];
     519                                node->value[j - 1] = node->value[j];
     520                                node->subtree[j - 1] = node->subtree[j];
     521                        }
     522                        node->subtree[j - 1] = node->subtree[j];
     523                        node->keys--;
     524                        return;
     525                }
     526        }
     527        panic("Node %p does not contain key %" PRIu64 ".", node, key);
     528}
     529
     530/** Remove key and its right subtree pointer from B-tree node.
     531 *
     532 * Remove the key and eliminate gaps in node->key array.
     533 * Note that the value pointer and the right subtree pointer
     534 * is removed from the node as well.
     535 *
     536 * @param node B-tree node.
     537 * @param key Key to be removed.
     538 */
     539void node_remove_key_and_rsubtree(btree_node_t *node, btree_key_t key)
     540{
     541        size_t i, j;
     542       
     543        for (i = 0; i < node->keys; i++) {
     544                if (key == node->key[i]) {
     545                        for (j = i + 1; j < node->keys; j++) {
     546                                node->key[j - 1] = node->key[j];
     547                                node->value[j - 1] = node->value[j];
     548                                node->subtree[j] = node->subtree[j + 1];
     549                        }
     550                        node->keys--;
     551                        return;
     552                }
     553        }
     554        panic("Node %p does not contain key %" PRIu64 ".", node, key);
     555}
     556
     557/** Split full B-tree node and insert new key-value-right-subtree triplet.
     558 *
     559 * This function will split a node and return a pointer to a newly created
     560 * node containing keys greater than or equal to the greater of medians
     561 * (or median) of the old keys and the newly added key. It will also write
     562 * the median key to a memory address supplied by the caller.
     563 *
     564 * If the node being split is an index node, the median will not be
     565 * included in the new node. If the node is a leaf node,
     566 * the median will be copied there.
     567 *
     568 * @param node B-tree node wich is going to be split.
     569 * @param key The key to be inserted.
     570 * @param value Pointer to the value to be inserted.
     571 * @param rsubtree Pointer to the right subtree of the key being added.
     572 * @param median Address in memory, where the median key will be stored.
     573 *
     574 * @return Newly created right sibling of node.
     575 */
     576btree_node_t *node_split(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree, btree_key_t *median)
     577{
     578        btree_node_t *rnode;
     579        size_t i, j;
     580
     581        ASSERT(median);
     582        ASSERT(node->keys == BTREE_MAX_KEYS);
     583
     584        /*
     585         * Use the extra space to store the extra node.
     586         */
     587        node_insert_key_and_rsubtree(node, key, value, rsubtree);
     588
     589        /*
     590         * Compute median of keys.
     591         */
     592        *median = MEDIAN_HIGH(node);
     593               
     594        /*
     595         * Allocate and initialize new right sibling.
     596         */
     597        rnode = (btree_node_t *) slab_alloc(btree_node_slab, 0);
     598        node_initialize(rnode);
     599        rnode->parent = node->parent;
     600        rnode->depth = node->depth;
     601       
     602        /*
     603         * Copy big keys, values and subtree pointers to the new right sibling.
     604         * If this is an index node, do not copy the median.
     605         */
     606        i = (size_t) INDEX_NODE(node);
     607        for (i += MEDIAN_HIGH_INDEX(node), j = 0; i < node->keys; i++, j++) {
     608                rnode->key[j] = node->key[i];
     609                rnode->value[j] = node->value[i];
     610                rnode->subtree[j] = node->subtree[i];
     611               
     612                /*
     613                 * Fix parent links in subtrees.
     614                 */
     615                if (rnode->subtree[j])
     616                        rnode->subtree[j]->parent = rnode;
     617                       
     618        }
     619        rnode->subtree[j] = node->subtree[i];
     620        if (rnode->subtree[j])
     621                rnode->subtree[j]->parent = rnode;
     622
     623        rnode->keys = j;        /* Set number of keys of the new node. */
     624        node->keys /= 2;        /* Shrink the old node. */
     625               
     626        return rnode;
     627}
     628
     629/** Combine node with any of its siblings.
     630 *
     631 * The siblings are required to be below the fill factor.
     632 *
     633 * @param node Node to combine with one of its siblings.
     634 *
     635 * @return Pointer to the rightmost of the two nodes.
     636 */
     637btree_node_t *node_combine(btree_node_t *node)
     638{
     639        size_t idx;
     640        btree_node_t *rnode;
     641        size_t i;
     642
     643        ASSERT(!ROOT_NODE(node));
     644       
     645        idx = find_key_by_subtree(node->parent, node, false);
     646        if (idx == node->parent->keys) {
     647                /*
     648                 * Rightmost subtree of its parent, combine with the left sibling.
     649                 */
     650                idx--;
     651                rnode = node;
     652                node = node->parent->subtree[idx];
     653        } else {
     654                rnode = node->parent->subtree[idx + 1];
     655        }
     656
     657        /* Index nodes need to insert parent node key in between left and right node. */
     658        if (INDEX_NODE(node))
     659                node->key[node->keys++] = node->parent->key[idx];
     660       
     661        /* Copy the key-value-subtree triplets from the right node. */
     662        for (i = 0; i < rnode->keys; i++) {
     663                node->key[node->keys + i] = rnode->key[i];
     664                node->value[node->keys + i] = rnode->value[i];
     665                if (INDEX_NODE(node)) {
     666                        node->subtree[node->keys + i] = rnode->subtree[i];
     667                        rnode->subtree[i]->parent = node;
     668                }
     669        }
     670        if (INDEX_NODE(node)) {
     671                node->subtree[node->keys + i] = rnode->subtree[i];
     672                rnode->subtree[i]->parent = node;
     673        }
     674
     675        node->keys += rnode->keys;
     676
     677        return rnode;
     678}
     679
     680/** Find key by its left or right subtree.
     681 *
     682 * @param node B-tree node.
     683 * @param subtree Left or right subtree of a key found in node.
     684 * @param right If true, subtree is a right subtree. If false, subtree is a left subtree.
     685 *
     686 * @return Index of the key associated with the subtree.
     687 */
     688size_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right)
     689{
     690        size_t i;
     691       
     692        for (i = 0; i < node->keys + 1; i++) {
     693                if (subtree == node->subtree[i])
     694                        return i - (int) (right != false);
     695        }
     696        panic("Node %p does not contain subtree %p.", node, subtree);
     697}
     698
     699/** Rotate one key-value-rsubtree triplet from the left sibling to the right sibling.
     700 *
     701 * The biggest key and its value and right subtree is rotated from the left node
     702 * to the right. If the node is an index node, than the parent node key belonging to
     703 * the left node takes part in the rotation.
     704 *
     705 * @param lnode Left sibling.
     706 * @param rnode Right sibling.
     707 * @param idx Index of the parent node key that is taking part in the rotation.
     708 */
     709void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, size_t idx)
     710{
     711        btree_key_t key;
     712
     713        key = lnode->key[lnode->keys - 1];
     714               
     715        if (LEAF_NODE(lnode)) {
     716                void *value;
     717
     718                value = lnode->value[lnode->keys - 1];
     719                node_remove_key_and_rsubtree(lnode, key);
     720                node_insert_key_and_lsubtree(rnode, key, value, NULL);
     721                lnode->parent->key[idx] = key;
     722        } else {
     723                btree_node_t *rsubtree;
     724
     725                rsubtree = lnode->subtree[lnode->keys];
     726                node_remove_key_and_rsubtree(lnode, key);
     727                node_insert_key_and_lsubtree(rnode, lnode->parent->key[idx], NULL, rsubtree);
     728                lnode->parent->key[idx] = key;
     729
     730                /* Fix parent link of the reconnected right subtree. */
     731                rsubtree->parent = rnode;
     732        }
     733
     734}
     735
     736/** Rotate one key-value-lsubtree triplet from the right sibling to the left sibling.
     737 *
     738 * The smallest key and its value and left subtree is rotated from the right node
     739 * to the left. If the node is an index node, than the parent node key belonging to
     740 * the right node takes part in the rotation.
     741 *
     742 * @param lnode Left sibling.
     743 * @param rnode Right sibling.
     744 * @param idx Index of the parent node key that is taking part in the rotation.
     745 */
     746void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, size_t idx)
     747{
     748        btree_key_t key;
     749
     750        key = rnode->key[0];
     751               
     752        if (LEAF_NODE(rnode)) {
     753                void *value;
     754
     755                value = rnode->value[0];
     756                node_remove_key_and_lsubtree(rnode, key);
     757                node_insert_key_and_rsubtree(lnode, key, value, NULL);
     758                rnode->parent->key[idx] = rnode->key[0];
     759        } else {
     760                btree_node_t *lsubtree;
     761
     762                lsubtree = rnode->subtree[0];
     763                node_remove_key_and_lsubtree(rnode, key);
     764                node_insert_key_and_rsubtree(lnode, rnode->parent->key[idx], NULL, lsubtree);
     765                rnode->parent->key[idx] = key;
     766
     767                /* Fix parent link of the reconnected left subtree. */
     768                lsubtree->parent = lnode;
     769        }
     770
     771}
     772
     773/** Insert key-value-rsubtree triplet and rotate the node to the left, if this operation can be done.
     774 *
     775 * Left sibling of the node (if it exists) is checked for free space.
     776 * If there is free space, the key is inserted and the smallest key of
     777 * the node is moved there. The index node which is the parent of both
     778 * nodes is fixed.
     779 *
     780 * @param node B-tree node.
     781 * @param inskey Key to be inserted.
     782 * @param insvalue Value to be inserted.
     783 * @param rsubtree Right subtree of inskey.
     784 *
     785 * @return True if the rotation was performed, false otherwise.
     786 */
     787bool try_insert_by_rotation_to_left(btree_node_t *node, btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
     788{
     789        size_t idx;
     790        btree_node_t *lnode;
     791
     792        /*
     793         * If this is root node, the rotation can not be done.
     794         */
     795        if (ROOT_NODE(node))
     796                return false;
     797       
     798        idx = find_key_by_subtree(node->parent, node, true);
     799        if ((int) idx == -1) {
     800                /*
     801                 * If this node is the leftmost subtree of its parent,
     802                 * the rotation can not be done.
     803                 */
     804                return false;
     805        }
     806               
     807        lnode = node->parent->subtree[idx];
     808        if (lnode->keys < BTREE_MAX_KEYS) {
     809                /*
     810                 * The rotaion can be done. The left sibling has free space.
     811                 */
     812                node_insert_key_and_rsubtree(node, inskey, insvalue, rsubtree);
     813                rotate_from_right(lnode, node, idx);
     814                return true;
     815        }
     816
     817        return false;
     818}
     819
     820/** Insert key-value-rsubtree triplet and rotate the node to the right, if this operation can be done.
     821 *
     822 * Right sibling of the node (if it exists) is checked for free space.
     823 * If there is free space, the key is inserted and the biggest key of
     824 * the node is moved there. The index node which is the parent of both
     825 * nodes is fixed.
     826 *
     827 * @param node B-tree node.
     828 * @param inskey Key to be inserted.
     829 * @param insvalue Value to be inserted.
     830 * @param rsubtree Right subtree of inskey.
     831 *
     832 * @return True if the rotation was performed, false otherwise.
     833 */
     834bool try_insert_by_rotation_to_right(btree_node_t *node, btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
     835{
     836        size_t idx;
     837        btree_node_t *rnode;
     838
     839        /*
     840         * If this is root node, the rotation can not be done.
     841         */
     842        if (ROOT_NODE(node))
     843                return false;
     844       
     845        idx = find_key_by_subtree(node->parent, node, false);
     846        if (idx == node->parent->keys) {
     847                /*
     848                 * If this node is the rightmost subtree of its parent,
     849                 * the rotation can not be done.
     850                 */
     851                return false;
     852        }
     853               
     854        rnode = node->parent->subtree[idx + 1];
     855        if (rnode->keys < BTREE_MAX_KEYS) {
     856                /*
     857                 * The rotaion can be done. The right sibling has free space.
     858                 */
     859                node_insert_key_and_rsubtree(node, inskey, insvalue, rsubtree);
     860                rotate_from_left(node, rnode, idx);
     861                return true;
     862        }
     863
     864        return false;
     865}
     866
     867/** Rotate in a key from the left sibling or from the index node, if this operation can be done.
     868 *
     869 * @param rnode Node into which to add key from its left sibling or from the index node.
     870 *
     871 * @return True if the rotation was performed, false otherwise.
     872 */
     873bool try_rotation_from_left(btree_node_t *rnode)
     874{
     875        size_t idx;
     876        btree_node_t *lnode;
     877
     878        /*
     879         * If this is root node, the rotation can not be done.
     880         */
     881        if (ROOT_NODE(rnode))
     882                return false;
     883       
     884        idx = find_key_by_subtree(rnode->parent, rnode, true);
     885        if ((int) idx == -1) {
     886                /*
     887                 * If this node is the leftmost subtree of its parent,
     888                 * the rotation can not be done.
     889                 */
     890                return false;
     891        }
     892               
     893        lnode = rnode->parent->subtree[idx];
     894        if (lnode->keys > FILL_FACTOR) {
     895                rotate_from_left(lnode, rnode, idx);
     896                return true;
     897        }
     898       
     899        return false;
     900}
     901
     902/** Rotate in a key from the right sibling or from the index node, if this operation can be done.
     903 *
     904 * @param lnode Node into which to add key from its right sibling or from the index node.
     905 *
     906 * @return True if the rotation was performed, false otherwise.
     907 */
     908bool try_rotation_from_right(btree_node_t *lnode)
     909{
     910        size_t idx;
     911        btree_node_t *rnode;
     912
     913        /*
     914         * If this is root node, the rotation can not be done.
     915         */
     916        if (ROOT_NODE(lnode))
     917                return false;
     918       
     919        idx = find_key_by_subtree(lnode->parent, lnode, false);
     920        if (idx == lnode->parent->keys) {
     921                /*
     922                 * If this node is the rightmost subtree of its parent,
     923                 * the rotation can not be done.
     924                 */
     925                return false;
     926        }
     927               
     928        rnode = lnode->parent->subtree[idx + 1];
     929        if (rnode->keys > FILL_FACTOR) {
     930                rotate_from_right(lnode, rnode, idx);
     931                return true;
     932        }       
     933
     934        return false;
     935}
     936
    971937/** Print B-tree.
    972938 *
    973939 * @param t Print out B-tree.
    974  *
    975940 */
    976941void btree_print(btree_t *t)
     
    979944        int depth = t->root->depth;
    980945        link_t head, *cur;
    981        
     946
    982947        printf("Printing B-tree:\n");
    983948        list_initialize(&head);
    984949        list_append(&t->root->bfs_link, &head);
    985        
     950
    986951        /*
    987952         * Use BFS search to print out the tree.
    988953         * Levels are distinguished from one another by node->depth.
    989          */
     954         */     
    990955        while (!list_empty(&head)) {
    991956                link_t *hlp;
     
    1003968                        depth = node->depth;
    1004969                }
    1005                
     970
    1006971                printf("(");
    1007                
    1008972                for (i = 0; i < node->keys; i++) {
    1009973                        printf("%" PRIu64 "%s", node->key[i], i < node->keys - 1 ? "," : "");
     
    1012976                        }
    1013977                }
    1014                
    1015                 if (node->depth && node->subtree[i])
     978                if (node->depth && node->subtree[i]) {
    1016979                        list_append(&node->subtree[i]->bfs_link, &head);
    1017                
     980                }
    1018981                printf(")");
    1019982        }
    1020        
    1021983        printf("\n");
    1022984       
     
    1028990               
    1029991                ASSERT(node);
    1030                
     992
    1031993                printf("(");
    1032                
    1033994                for (i = 0; i < node->keys; i++)
    1034995                        printf("%" PRIu64 "%s", node->key[i], i < node->keys - 1 ? "," : "");
    1035                
    1036996                printf(")");
    1037997        }
    1038        
    1039998        printf("\n");
    1040999}
  • kernel/generic/src/console/console.c

    re2ea4ab1 r4d1be48  
    294294                stdout->op->write(stdout, ch, silent);
    295295        else {
    296                 /*
    297                  * No standard output routine defined yet.
    298                  * The character is still stored in the kernel log
    299                  * for possible future output.
    300                  *
    301                  * The early_putchar() function is used to output
    302                  * the character for low-level debugging purposes.
    303                  * Note that the early_putc() function might be
    304                  * a no-op on certain hardware configurations.
    305                  *
    306                  */
    307                 early_putchar(ch);
    308                
     296                /* The character is just in the kernel log */
    309297                if (klog_stored < klog_len)
    310298                        klog_stored++;
  • kernel/generic/src/cpu/cpu.c

    re2ea4ab1 r4d1be48  
    119119/** @}
    120120 */
     121
  • kernel/generic/src/debug/stacktrace.c

    re2ea4ab1 r4d1be48  
    5252                    ops->symbol_resolve(pc, &symbol, &offset)) {
    5353                        if (offset)
    54                                 printf("%p: %s+%" PRIp "()\n", fp, symbol, offset);
     54                                printf("%p: %s+%lx()\n", fp, symbol, offset);
    5555                        else
    5656                                printf("%p: %s()\n", fp, symbol);
  • kernel/generic/src/lib/sort.c

    re2ea4ab1 r4d1be48  
    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 gnome sort).
    39  *
    40  */
    41 
     38 * algorithms (e.g. quick sort and bubble sort).
     39 */
     40 
    4241#include <mm/slab.h>
    4342#include <memstr.h>
    4443#include <sort.h>
    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  */
    73 static 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;
     44#include <panic.h>
     45
     46#define EBUFSIZE        32
     47
     48void _qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot);
     49void _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 */
     64void 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);
     74        }
     75
     76        _qsort(data, n, e_size, cmp, tmp, pivot);
    7777       
    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++;
     78        if (e_size > EBUFSIZE) {
     79                free(tmp);
     80                free(pivot);
    8981        }
    9082}
     
    9284/** Quicksort
    9385 *
    94  * Apply generic quicksort algorithm on supplied data,
    95  * using pre-allocated buffers.
    96  *
    97  * @param data      Pointer to data to be sorted.
    98  * @param cnt       Number of elements to be sorted.
    99  * @param elem_size Size of one element.
    100  * @param cmp       Comparator function.
    101  * @param arg       3rd argument passed to cmp.
    102  * @param slot      Pointer to scratch memory buffer
    103  *                  elem_size bytes long.
    104  * @param pivot     Pointer to scratch memory buffer
    105  *                  elem_size bytes long.
    106  *
    107  */
    108 static void _qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
    109     void *arg, void *slot, void *pivot)
    110 {
    111         if (cnt > 4) {
    112                 size_t i = 0;
    113                 size_t j = cnt - 1;
    114                
    115                 memcpy(pivot, data, elem_size);
    116                
    117                 while (true) {
    118                         while ((cmp(INDEX(data, i, elem_size), pivot, arg) < 0) && (i < cnt))
     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 */
     96void _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))
    119105                                i++;
    120                        
    121                         while ((cmp(INDEX(data, j, elem_size), pivot, arg) >= 0) && (j > 0))
     106                        while ((cmp(data + j * e_size, pivot) >= 0) && (j > 0))
    122107                                j--;
    123108                       
    124109                        if (i < j) {
    125                                 memcpy(slot, INDEX(data, i, elem_size), elem_size);
    126                                 memcpy(INDEX(data, i, elem_size), INDEX(data, j, elem_size),
    127                                     elem_size);
    128                                 memcpy(INDEX(data, j, elem_size), slot, elem_size);
    129                         } else
     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 {
    130114                                break;
     115                        }
    131116                }
    132                
    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);
    136         } else
    137                 _gsort(data, cnt, elem_size, cmp, arg, slot);
    138 }
    139 
    140 /** Gnome sort wrapper
    141  *
    142  * This is only a wrapper that takes care of memory
    143  * allocations for storing the slot element for generic
    144  * gnome sort algorithm.
    145  *
    146  * This function can sleep.
    147  *
    148  * @param data      Pointer to data to be sorted.
    149  * @param cnt       Number of elements to be sorted.
    150  * @param elem_size Size of one element.
    151  * @param cmp       Comparator function.
    152  * @param arg       3rd argument passed to cmp.
    153  *
    154  * @return True if sorting succeeded.
    155  *
    156  */
    157 bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
    158 {
    159         uint8_t ibuf_slot[IBUF_SIZE];
    160         void *slot;
     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);
     120        } else {
     121                _bubblesort(data, n, e_size, cmp, tmp);
     122        }
     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 */
     136void 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;
    161140       
    162         if (elem_size > IBUF_SIZE) {
    163                 slot = (void *) malloc(elem_size, 0);
    164                 if (!slot)
    165                         return false;
    166         } else
    167                 slot = (void *) ibuf_slot;
     141        if (e_size > EBUFSIZE) {
     142                slot = (void *) malloc(e_size, 0);
     143        }
     144
     145        _bubblesort(data, n, e_size, cmp, slot);
    168146       
    169         _gsort(data, cnt, elem_size, cmp, arg, slot);
    170        
    171         if (elem_size > IBUF_SIZE)
     147        if (e_size > EBUFSIZE) {
    172148                free(slot);
    173        
    174         return true;
    175 }
    176 
    177 /** Quicksort wrapper
    178  *
    179  * This is only a wrapper that takes care of memory
    180  * allocations for storing the pivot and temporary elements
    181  * for generic quicksort algorithm.
    182  *
    183  * This function can sleep.
    184  *
    185  * @param data      Pointer to data to be sorted.
    186  * @param cnt       Number of elements to be sorted.
    187  * @param elem_size Size of one element.
    188  * @param cmp       Comparator function.
    189  * @param arg       3rd argument passed to cmp.
    190  *
    191  * @return True if sorting succeeded.
    192  *
    193  */
    194 bool qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
    195 {
    196         uint8_t ibuf_slot[IBUF_SIZE];
    197         uint8_t ibuf_pivot[IBUF_SIZE];
    198         void *slot;
    199         void *pivot;
    200        
    201         if (elem_size > IBUF_SIZE) {
    202                 slot = (void *) malloc(elem_size, 0);
    203                 if (!slot)
    204                         return false;
    205                
    206                 pivot = (void *) malloc(elem_size, 0);
    207                 if (!pivot) {
    208                         free(slot);
    209                         return false;
     149        }
     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 */
     163void _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                        }
    210177                }
    211         } else {
    212                 slot = (void *) ibuf_slot;
    213                 pivot = (void *) ibuf_pivot;
    214         }
    215        
    216         _qsort(data, cnt, elem_size, cmp, arg, slot, pivot);
    217        
    218         if (elem_size > IBUF_SIZE) {
    219                 free(pivot);
    220                 free(slot);
    221         }
    222        
    223         return true;
     178        }
     179
     180}
     181
     182/*
     183 * Comparator returns 1 if a > b, 0 if a == b, -1 if a < b
     184 */
     185int int_cmp(void * a, void * b)
     186{
     187        return (* (int *) a > * (int*)b) ? 1 : (*(int *)a < * (int *)b) ? -1 : 0;
     188}
     189
     190int 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
     195int 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
     200int 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;
    224203}
    225204
  • kernel/generic/src/main/main.c

    re2ea4ab1 r4d1be48  
    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 
    116115#ifdef CONFIG_SMP
    117116static void main_ap_separated_stack(void);
    118117#endif
    119118
    120 #define CONFIG_STACK_SIZE  ((1 << STACK_FRAMES) * STACK_SIZE)
     119#define CONFIG_STACK_SIZE       ((1 << STACK_FRAMES) * STACK_SIZE)
    121120
    122121/** Main kernel routine for bootstrap CPU.
     
    131130 *
    132131 */
    133 void __attribute__((no_instrument_function)) main_bsp(void)
     132void main_bsp(void)
    134133{
    135134        config.cpu_count = 1;
     
    152151                            init.tasks[i].size, config.stack_size);
    153152        }
    154        
     153
    155154        /* Avoid placing stack on top of boot allocations. */
    156155        if (ballocs.size) {
     
    171170}
    172171
     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. */
     
    183183        version_print();
    184184       
    185         LOG("\nconfig.base=%p config.kernel_size=%" PRIs
    186             "\nconfig.stack_base=%p config.stack_size=%" PRIs,
     185        LOG("\nconfig.base=%#" PRIp " config.kernel_size=%" PRIs
     186            "\nconfig.stack_base=%#" PRIp " config.stack_size=%" PRIs,
    187187            config.base, config.kernel_size, config.stack_base,
    188188            config.stack_size);
     
    194194         * commands.
    195195         */
    196         kconsole_init();
     196        LOG_EXEC(kconsole_init());
    197197#endif
    198198       
     
    201201         * starts adding its own handlers
    202202         */
    203         exc_init();
     203        LOG_EXEC(exc_init());
    204204       
    205205        /*
    206206         * Memory management subsystems initialization.
    207207         */
    208         arch_pre_mm_init();
    209         frame_init();
     208        LOG_EXEC(arch_pre_mm_init());
     209        LOG_EXEC(frame_init());
    210210       
    211211        /* Initialize at least 1 memory segment big enough for slab to work. */
    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();
     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());
    223223       
    224224        /* Slab must be initialized after we know the number of processors. */
    225         slab_enable_cpucache();
     225        LOG_EXEC(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         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();
     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());
    239239       
    240240        if (init.cnt > 0) {
    241241                size_t i;
    242242                for (i = 0; i < init.cnt; i++)
    243                         LOG("init[%" PRIs "].addr=%p, init[%" PRIs
    244                             "].size=%" PRIs, i, init.tasks[i].addr, i,
     243                        LOG("init[%" PRIs "].addr=%#" PRIp ", init[%" PRIs
     244                            "].size=%#" PRIs, i, init.tasks[i].addr, i,
    245245                            init.tasks[i].size);
    246246        } else
    247247                printf("No init binaries found.\n");
    248248       
    249         ipc_init();
    250         event_init();
    251         klog_init();
    252         stats_init();
     249        LOG_EXEC(ipc_init());
     250        LOG_EXEC(event_init());
     251        LOG_EXEC(klog_init());
     252        LOG_EXEC(stats_init());
    253253       
    254254        /*
     
    266266        if (!kinit_thread)
    267267                panic("Cannot create kinit thread.");
    268         thread_ready(kinit_thread);
     268        LOG_EXEC(thread_ready(kinit_thread));
    269269       
    270270        /*
     
    276276}
    277277
     278
    278279#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
    328329/** Main kernel routine for application CPUs using new stack.
    329330 *
     
    337338         */
    338339        timeout_init();
    339        
     340
    340341        waitq_wakeup(&ap_completion_wq, WAKEUP_FIRST);
    341342        scheduler();
    342343        /* not reached */
    343344}
    344 
    345345#endif /* CONFIG_SMP */
    346346
  • kernel/generic/src/mm/as.c

    re2ea4ab1 r4d1be48  
    116116as_t *AS_KERNEL = NULL;
    117117
     118static unsigned int area_flags_to_page_flags(unsigned int);
     119static as_area_t *find_area_and_lock(as_t *, uintptr_t);
     120static bool check_area_conflicts(as_t *, uintptr_t, size_t, as_area_t *);
     121static void sh_info_remove_reference(share_info_t *);
     122
    118123static int as_constructor(void *obj, unsigned int flags)
    119124{
     
    291296        if (atomic_predec(&as->refcount) == 0)
    292297                as_destroy(as);
    293 }
    294 
    295 /** Check area conflicts with other areas.
    296  *
    297  * @param as         Address space.
    298  * @param va         Starting virtual address of the area being tested.
    299  * @param size       Size of the area being tested.
    300  * @param avoid_area Do not touch this area.
    301  *
    302  * @return True if there is no conflict, false otherwise.
    303  *
    304  */
    305 static bool check_area_conflicts(as_t *as, uintptr_t va, size_t size,
    306     as_area_t *avoid_area)
    307 {
    308         ASSERT(mutex_locked(&as->lock));
    309        
    310         /*
    311          * We don't want any area to have conflicts with NULL page.
    312          *
    313          */
    314         if (overlaps(va, size, NULL, PAGE_SIZE))
    315                 return false;
    316        
    317         /*
    318          * The leaf node is found in O(log n), where n is proportional to
    319          * the number of address space areas belonging to as.
    320          * The check for conflicts is then attempted on the rightmost
    321          * record in the left neighbour, the leftmost record in the right
    322          * neighbour and all records in the leaf node itself.
    323          *
    324          */
    325         btree_node_t *leaf;
    326         as_area_t *area =
    327             (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
    328         if (area) {
    329                 if (area != avoid_area)
    330                         return false;
    331         }
    332        
    333         /* First, check the two border cases. */
    334         btree_node_t *node =
    335             btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
    336         if (node) {
    337                 area = (as_area_t *) node->value[node->keys - 1];
    338                
    339                 mutex_lock(&area->lock);
    340                
    341                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
    342                         mutex_unlock(&area->lock);
    343                         return false;
    344                 }
    345                
    346                 mutex_unlock(&area->lock);
    347         }
    348        
    349         node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
    350         if (node) {
    351                 area = (as_area_t *) node->value[0];
    352                
    353                 mutex_lock(&area->lock);
    354                
    355                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
    356                         mutex_unlock(&area->lock);
    357                         return false;
    358                 }
    359                
    360                 mutex_unlock(&area->lock);
    361         }
    362        
    363         /* Second, check the leaf node. */
    364         btree_key_t i;
    365         for (i = 0; i < leaf->keys; i++) {
    366                 area = (as_area_t *) leaf->value[i];
    367                
    368                 if (area == avoid_area)
    369                         continue;
    370                
    371                 mutex_lock(&area->lock);
    372                
    373                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
    374                         mutex_unlock(&area->lock);
    375                         return false;
    376                 }
    377                
    378                 mutex_unlock(&area->lock);
    379         }
    380        
    381         /*
    382          * So far, the area does not conflict with other areas.
    383          * Check if it doesn't conflict with kernel address space.
    384          *
    385          */
    386         if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
    387                 return !overlaps(va, size,
    388                     KERNEL_ADDRESS_SPACE_START,
    389                     KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
    390         }
    391        
    392         return true;
    393298}
    394299
     
    452357       
    453358        return area;
    454 }
    455 
    456 /** Find address space area and lock it.
    457  *
    458  * @param as Address space.
    459  * @param va Virtual address.
    460  *
    461  * @return Locked address space area containing va on success or
    462  *         NULL on failure.
    463  *
    464  */
    465 static as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
    466 {
    467         ASSERT(mutex_locked(&as->lock));
    468        
    469         btree_node_t *leaf;
    470         as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
    471         if (area) {
    472                 /* va is the base address of an address space area */
    473                 mutex_lock(&area->lock);
    474                 return area;
    475         }
    476        
    477         /*
    478          * Search the leaf node and the righmost record of its left neighbour
    479          * to find out whether this is a miss or va belongs to an address
    480          * space area found there.
    481          *
    482          */
    483        
    484         /* First, search the leaf node itself. */
    485         btree_key_t i;
    486        
    487         for (i = 0; i < leaf->keys; i++) {
    488                 area = (as_area_t *) leaf->value[i];
    489                
    490                 mutex_lock(&area->lock);
    491                
    492                 if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE))
    493                         return area;
    494                
    495                 mutex_unlock(&area->lock);
    496         }
    497        
    498         /*
    499          * Second, locate the left neighbour and test its last record.
    500          * Because of its position in the B+tree, it must have base < va.
    501          *
    502          */
    503         btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
    504         if (lnode) {
    505                 area = (as_area_t *) lnode->value[lnode->keys - 1];
    506                
    507                 mutex_lock(&area->lock);
    508                
    509                 if (va < area->base + area->pages * PAGE_SIZE)
    510                         return area;
    511                
    512                 mutex_unlock(&area->lock);
    513         }
    514        
    515         return NULL;
    516359}
    517360
     
    710553}
    711554
    712 /** Remove reference to address space area share info.
    713  *
    714  * If the reference count drops to 0, the sh_info is deallocated.
    715  *
    716  * @param sh_info Pointer to address space area share info.
    717  *
    718  */
    719 static void sh_info_remove_reference(share_info_t *sh_info)
    720 {
    721         bool dealloc = false;
    722        
    723         mutex_lock(&sh_info->lock);
    724         ASSERT(sh_info->refcount);
    725        
    726         if (--sh_info->refcount == 0) {
    727                 dealloc = true;
    728                 link_t *cur;
    729                
    730                 /*
    731                  * Now walk carefully the pagemap B+tree and free/remove
    732                  * reference from all frames found there.
    733                  */
    734                 for (cur = sh_info->pagemap.leaf_head.next;
    735                     cur != &sh_info->pagemap.leaf_head; cur = cur->next) {
    736                         btree_node_t *node
    737                             = list_get_instance(cur, btree_node_t, leaf_link);
    738                         btree_key_t i;
    739                        
    740                         for (i = 0; i < node->keys; i++)
    741                                 frame_free((uintptr_t) node->value[i]);
    742                 }
    743                
    744         }
    745         mutex_unlock(&sh_info->lock);
    746        
    747         if (dealloc) {
    748                 btree_destroy(&sh_info->pagemap);
    749                 free(sh_info);
    750         }
    751 }
    752 
    753555/** Destroy address space area.
    754556 *
     
    1003805}
    1004806
    1005 /** Convert address space area flags to page flags.
    1006  *
    1007  * @param aflags Flags of some address space area.
    1008  *
    1009  * @return Flags to be passed to page_mapping_insert().
    1010  *
    1011  */
    1012 static unsigned int area_flags_to_page_flags(unsigned int aflags)
    1013 {
    1014         unsigned int flags = PAGE_USER | PAGE_PRESENT;
    1015        
    1016         if (aflags & AS_AREA_READ)
    1017                 flags |= PAGE_READ;
    1018                
    1019         if (aflags & AS_AREA_WRITE)
    1020                 flags |= PAGE_WRITE;
    1021        
    1022         if (aflags & AS_AREA_EXEC)
    1023                 flags |= PAGE_EXEC;
    1024        
    1025         if (aflags & AS_AREA_CACHEABLE)
    1026                 flags |= PAGE_CACHEABLE;
    1027        
    1028         return flags;
    1029 }
    1030 
    1031807/** Change adress space area flags.
    1032808 *
     
    13851161}
    13861162
    1387 
     1163/** Convert address space area flags to page flags.
     1164 *
     1165 * @param aflags Flags of some address space area.
     1166 *
     1167 * @return Flags to be passed to page_mapping_insert().
     1168 *
     1169 */
     1170unsigned int area_flags_to_page_flags(unsigned int aflags)
     1171{
     1172        unsigned int flags = PAGE_USER | PAGE_PRESENT;
     1173       
     1174        if (aflags & AS_AREA_READ)
     1175                flags |= PAGE_READ;
     1176               
     1177        if (aflags & AS_AREA_WRITE)
     1178                flags |= PAGE_WRITE;
     1179       
     1180        if (aflags & AS_AREA_EXEC)
     1181                flags |= PAGE_EXEC;
     1182       
     1183        if (aflags & AS_AREA_CACHEABLE)
     1184                flags |= PAGE_CACHEABLE;
     1185       
     1186        return flags;
     1187}
    13881188
    13891189/** Compute flags for virtual address translation subsytem.
     
    14721272/** Test whether page tables are locked.
    14731273 *
    1474  * @param as Address space where the page tables belong.
    1475  *
    1476  * @return True if the page tables belonging to the address soace
    1477  *         are locked, otherwise false.
     1274 * @param as            Address space where the page tables belong.
     1275 *
     1276 * @return              True if the page tables belonging to the address soace
     1277 *                      are locked, otherwise false.
    14781278 */
    14791279bool page_table_locked(as_t *as)
     
    14831283
    14841284        return as_operations->page_table_locked(as);
     1285}
     1286
     1287
     1288/** Find address space area and lock it.
     1289 *
     1290 * @param as Address space.
     1291 * @param va Virtual address.
     1292 *
     1293 * @return Locked address space area containing va on success or
     1294 *         NULL on failure.
     1295 *
     1296 */
     1297as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
     1298{
     1299        ASSERT(mutex_locked(&as->lock));
     1300
     1301        btree_node_t *leaf;
     1302        as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
     1303        if (area) {
     1304                /* va is the base address of an address space area */
     1305                mutex_lock(&area->lock);
     1306                return area;
     1307        }
     1308       
     1309        /*
     1310         * Search the leaf node and the righmost record of its left neighbour
     1311         * to find out whether this is a miss or va belongs to an address
     1312         * space area found there.
     1313         *
     1314         */
     1315       
     1316        /* First, search the leaf node itself. */
     1317        btree_key_t i;
     1318       
     1319        for (i = 0; i < leaf->keys; i++) {
     1320                area = (as_area_t *) leaf->value[i];
     1321               
     1322                mutex_lock(&area->lock);
     1323               
     1324                if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE))
     1325                        return area;
     1326               
     1327                mutex_unlock(&area->lock);
     1328        }
     1329       
     1330        /*
     1331         * Second, locate the left neighbour and test its last record.
     1332         * Because of its position in the B+tree, it must have base < va.
     1333         *
     1334         */
     1335        btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
     1336        if (lnode) {
     1337                area = (as_area_t *) lnode->value[lnode->keys - 1];
     1338               
     1339                mutex_lock(&area->lock);
     1340               
     1341                if (va < area->base + area->pages * PAGE_SIZE)
     1342                        return area;
     1343               
     1344                mutex_unlock(&area->lock);
     1345        }
     1346       
     1347        return NULL;
     1348}
     1349
     1350/** Check area conflicts with other areas.
     1351 *
     1352 * @param as         Address space.
     1353 * @param va         Starting virtual address of the area being tested.
     1354 * @param size       Size of the area being tested.
     1355 * @param avoid_area Do not touch this area.
     1356 *
     1357 * @return True if there is no conflict, false otherwise.
     1358 *
     1359 */
     1360bool check_area_conflicts(as_t *as, uintptr_t va, size_t size,
     1361    as_area_t *avoid_area)
     1362{
     1363        ASSERT(mutex_locked(&as->lock));
     1364
     1365        /*
     1366         * We don't want any area to have conflicts with NULL page.
     1367         *
     1368         */
     1369        if (overlaps(va, size, NULL, PAGE_SIZE))
     1370                return false;
     1371       
     1372        /*
     1373         * The leaf node is found in O(log n), where n is proportional to
     1374         * the number of address space areas belonging to as.
     1375         * The check for conflicts is then attempted on the rightmost
     1376         * record in the left neighbour, the leftmost record in the right
     1377         * neighbour and all records in the leaf node itself.
     1378         *
     1379         */
     1380        btree_node_t *leaf;
     1381        as_area_t *area =
     1382            (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
     1383        if (area) {
     1384                if (area != avoid_area)
     1385                        return false;
     1386        }
     1387       
     1388        /* First, check the two border cases. */
     1389        btree_node_t *node =
     1390            btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
     1391        if (node) {
     1392                area = (as_area_t *) node->value[node->keys - 1];
     1393               
     1394                mutex_lock(&area->lock);
     1395               
     1396                if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     1397                        mutex_unlock(&area->lock);
     1398                        return false;
     1399                }
     1400               
     1401                mutex_unlock(&area->lock);
     1402        }
     1403       
     1404        node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
     1405        if (node) {
     1406                area = (as_area_t *) node->value[0];
     1407               
     1408                mutex_lock(&area->lock);
     1409               
     1410                if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     1411                        mutex_unlock(&area->lock);
     1412                        return false;
     1413                }
     1414               
     1415                mutex_unlock(&area->lock);
     1416        }
     1417       
     1418        /* Second, check the leaf node. */
     1419        btree_key_t i;
     1420        for (i = 0; i < leaf->keys; i++) {
     1421                area = (as_area_t *) leaf->value[i];
     1422               
     1423                if (area == avoid_area)
     1424                        continue;
     1425               
     1426                mutex_lock(&area->lock);
     1427               
     1428                if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     1429                        mutex_unlock(&area->lock);
     1430                        return false;
     1431                }
     1432               
     1433                mutex_unlock(&area->lock);
     1434        }
     1435       
     1436        /*
     1437         * So far, the area does not conflict with other areas.
     1438         * Check if it doesn't conflict with kernel address space.
     1439         *
     1440         */
     1441        if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
     1442                return !overlaps(va, size,
     1443                    KERNEL_ADDRESS_SPACE_START,
     1444                    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
     1445        }
     1446       
     1447        return true;
    14851448}
    14861449
     
    19971960}
    19981961
     1962/** Remove reference to address space area share info.
     1963 *
     1964 * If the reference count drops to 0, the sh_info is deallocated.
     1965 *
     1966 * @param sh_info Pointer to address space area share info.
     1967 *
     1968 */
     1969void sh_info_remove_reference(share_info_t *sh_info)
     1970{
     1971        bool dealloc = false;
     1972       
     1973        mutex_lock(&sh_info->lock);
     1974        ASSERT(sh_info->refcount);
     1975       
     1976        if (--sh_info->refcount == 0) {
     1977                dealloc = true;
     1978                link_t *cur;
     1979               
     1980                /*
     1981                 * Now walk carefully the pagemap B+tree and free/remove
     1982                 * reference from all frames found there.
     1983                 */
     1984                for (cur = sh_info->pagemap.leaf_head.next;
     1985                    cur != &sh_info->pagemap.leaf_head; cur = cur->next) {
     1986                        btree_node_t *node
     1987                            = list_get_instance(cur, btree_node_t, leaf_link);
     1988                        btree_key_t i;
     1989                       
     1990                        for (i = 0; i < node->keys; i++)
     1991                                frame_free((uintptr_t) node->value[i]);
     1992                }
     1993               
     1994        }
     1995        mutex_unlock(&sh_info->lock);
     1996       
     1997        if (dealloc) {
     1998                btree_destroy(&sh_info->pagemap);
     1999                free(sh_info);
     2000        }
     2001}
     2002
    19992003/*
    20002004 * Address space related syscalls.
  • kernel/generic/src/mm/page.c

    re2ea4ab1 r4d1be48  
    3838 * mappings between virtual addresses and physical addresses.
    3939 * Functions here are mere wrappers that call the real implementation.
    40  * They however, define the single interface.
     40 * They however, define the single interface. 
    4141 *
    4242 */
  • kernel/generic/src/proc/the.c

    re2ea4ab1 r4d1be48  
    3333/**
    3434 * @file
    35  * @brief THE structure functions.
     35 * @brief       THE structure functions.
    3636 *
    3737 * This file contains functions to manage the THE structure.
     
    4343
    4444#include <arch.h>
     45
    4546
    4647/** Initialize THE structure
  • uspace/lib/c/arch/ia64/src/entry.s

    re2ea4ab1 r4d1be48  
    3939__entry:
    4040        alloc loc0 = ar.pfs, 0, 1, 2, 0
    41         movl gp = _gp
     41        movl r1 = _gp
    4242
    4343        # Pass PCB pointer as the first argument to __main
  • uspace/lib/c/arch/ia64/src/thread_entry.s

    re2ea4ab1 r4d1be48  
    3737        alloc loc0 = ar.pfs, 0, 1, 1, 0
    3838
    39         movl gp = _gp
     39        movl r1 = _gp
    4040       
    4141        #
  • uspace/lib/c/generic/sort.c

    re2ea4ab1 r4d1be48  
    3636 *
    3737 * This files contains functions implementing several sorting
    38  * algorithms (e.g. quick sort and gnome sort).
     38 * algorithms (e.g. quick sort and bubble sort).
    3939 *
    4040 */
     
    4444#include <malloc.h>
    4545
    46 /** Immediate buffer size.
     46/** Bubble sort
    4747 *
    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,
     48 * Apply generic bubble sort algorithm on supplied data,
    6249 * using pre-allocated buffer.
    6350 *
     
    7158 *
    7259 */
    73 static void _gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
     60static void _bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
    7461    void *arg, void *slot)
    7562{
    76         size_t i = 0;
     63        bool done = false;
     64        void *tmp;
    7765       
    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++;
     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                }
    8978        }
    9079}
     
    10089 * @param cmp       Comparator function.
    10190 * @param arg       3rd argument passed to cmp.
    102  * @param slot      Pointer to scratch memory buffer
     91 * @param tmp       Pointer to scratch memory buffer
    10392 *                  elem_size bytes long.
    10493 * @param pivot     Pointer to scratch memory buffer
     
    10796 */
    10897static void _qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
    109     void *arg, void *slot, void *pivot)
     98    void *arg, void *tmp, void *pivot)
    11099{
    111100        if (cnt > 4) {
     
    116105               
    117106                while (true) {
    118                         while ((cmp(INDEX(data, i, elem_size), pivot, arg) < 0) && (i < cnt))
     107                        while ((cmp(data + i * elem_size, pivot, arg) < 0) && (i < cnt))
    119108                                i++;
    120109                       
    121                         while ((cmp(INDEX(data, j, elem_size), pivot, arg) >= 0) && (j > 0))
     110                        while ((cmp(data + j * elem_size, pivot, arg) >= 0) && (j > 0))
    122111                                j--;
    123112                       
    124113                        if (i < j) {
    125                                 memcpy(slot, INDEX(data, i, elem_size), elem_size);
    126                                 memcpy(INDEX(data, i, elem_size), INDEX(data, j, elem_size),
     114                                memcpy(tmp, data + i * elem_size, elem_size);
     115                                memcpy(data + i * elem_size, data + j * elem_size,
    127116                                    elem_size);
    128                                 memcpy(INDEX(data, j, elem_size), slot, elem_size);
     117                                memcpy(data + j * elem_size, tmp, elem_size);
    129118                        } else
    130119                                break;
    131120                }
    132121               
    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);
     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);
    136125        } else
    137                 _gsort(data, cnt, elem_size, cmp, arg, slot);
     126                _bsort(data, cnt, elem_size, cmp, arg, tmp);
    138127}
    139128
    140 /** Gnome sort wrapper
     129/** Bubble sort wrapper
    141130 *
    142131 * This is only a wrapper that takes care of memory
    143132 * allocations for storing the slot element for generic
    144  * gnome sort algorithm.
     133 * bubble sort algorithm.
    145134 *
    146135 * @param data      Pointer to data to be sorted.
     
    153142 *
    154143 */
    155 bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
     144bool bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
    156145{
    157         uint8_t ibuf_slot[IBUF_SIZE];
    158         void *slot;
     146        void *slot = (void *) malloc(elem_size);
     147        if (!slot)
     148                return false;
    159149       
    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;
     150        _bsort(data, cnt, elem_size, cmp, arg, slot);
    166151       
    167         _gsort(data, cnt, elem_size, cmp, arg, slot);
    168        
    169         if (elem_size > IBUF_SIZE)
    170                 free(slot);
     152        free(slot);
    171153       
    172154        return true;
     
    190172bool qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
    191173{
    192         uint8_t ibuf_slot[IBUF_SIZE];
    193         uint8_t ibuf_pivot[IBUF_SIZE];
    194         void *slot;
    195         void *pivot;
     174        void *tmp = (void *) malloc(elem_size);
     175        if (!tmp)
     176                return false;
    196177       
    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;
     178        void *pivot = (void *) malloc(elem_size);
     179        if (!pivot) {
     180                free(tmp);
     181                return false;
    210182        }
    211183       
    212         _qsort(data, cnt, elem_size, cmp, arg, slot, pivot);
     184        _qsort(data, cnt, elem_size, cmp, arg, tmp, pivot);
    213185       
    214         if (elem_size > IBUF_SIZE) {
    215                 free(pivot);
    216                 free(slot);
    217         }
     186        free(pivot);
     187        free(tmp);
    218188       
    219189        return true;
  • uspace/lib/c/include/sort.h

    re2ea4ab1 r4d1be48  
    4141typedef int (* sort_cmp_t)(void *, void *, void *);
    4242
    43 extern bool gsort(void *, size_t, size_t, sort_cmp_t, void *);
     43extern bool bsort(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.