Changes in / [90ed058:eee047c] in mainline
- Files:
-
- 1 deleted
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/Makefile
r90ed058 reee047c 160 160 CFLAGS = $(GCC_CFLAGS) 161 161 DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) 162 INSTRUMENTATION = -finstrument-functions163 162 endif 164 163 … … 166 165 CFLAGS = $(GCC_CFLAGS) 167 166 DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) 168 INSTRUMENTATION = -finstrument-functions169 167 endif 170 168 … … 172 170 CFLAGS = $(ICC_CFLAGS) 173 171 DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) 174 INSTRUMENTATION =175 172 endif 176 173 … … 179 176 DEFS += $(CONFIG_DEFS) 180 177 DEPEND_DEFS = $(DEFS) 181 INSTRUMENTATION =182 178 endif 183 179 … … 185 181 CFLAGS = $(CLANG_CFLAGS) 186 182 DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) 187 INSTRUMENTATION =188 183 endif 189 184 … … 207 202 generic/src/debug/stacktrace.c \ 208 203 generic/src/debug/panic.c \ 209 generic/src/debug/debug.c \210 204 generic/src/interrupt/interrupt.c \ 211 205 generic/src/main/main.c \ … … 361 355 endif 362 356 363 ## Sources where instrumentation is enabled364 #365 366 ifeq ($(CONFIG_LOG),y)367 INSTRUMENTED_SOURCES = \368 generic/src/cpu/cpu.c \369 generic/src/main/kinit.c370 endif371 372 357 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) 373 358 ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES))) … … 429 414 430 415 %.o: %.c $(DEPEND) 431 $(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 $@ $< 432 417 ifeq ($(PRECHECK),y) 433 418 $(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) -
kernel/arch/amd64/src/boot/boot.S
r90ed058 reee047c 1 /* 2 *Copyright (c) 2005 Ondrej Palkovsky3 *Copyright (c) 2006 Martin Decky4 *Copyright (c) 2008 Jakub Jermar5 *All rights reserved.6 * 7 *Redistribution and use in source and binary forms, with or without8 *modification, are permitted provided that the following conditions9 *are met:10 * 11 *- Redistributions of source code must retain the above copyright12 *notice, this list of conditions and the following disclaimer.13 *- Redistributions in binary form must reproduce the above copyright14 *notice, this list of conditions and the following disclaimer in the15 *documentation and/or other materials provided with the distribution.16 *- The name of the author may not be used to endorse or promote products17 *derived from this software without specific prior written permission.18 * 19 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR20 *IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES21 *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, BUT24 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,25 *DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY26 *THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT27 *(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF28 *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 # 30 30 31 31 #include <arch/boot/boot.h> … … 37 37 #include <arch/cpuid.h> 38 38 39 #define START_STACK 39 #define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE) 40 40 41 41 .section K_TEXT_START, "ax" 42 42 43 43 .code32 44 45 .macro pm_error msg46 movl \msg, %esi47 jmp pm_error_halt48 .endm49 50 .macro pm_status msg51 #ifdef CONFIG_EGA52 pushl %esi53 movl \msg, %esi54 call pm_early_puts55 popl %esi56 #endif57 .endm58 59 .macro pm2_status msg60 #ifndef CONFIG_FB61 pm_status \msg62 #endif63 .endm64 65 44 .align 4 66 45 .global multiboot_image_start … … 68 47 .long MULTIBOOT_HEADER_MAGIC 69 48 .long MULTIBOOT_HEADER_FLAGS 70 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) /* checksum */49 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum 71 50 .long multiboot_header 72 51 .long unmapped_ktext_start … … 77 56 multiboot_image_start: 78 57 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 87 61 movw $gdtselector(KDATA_DES), %cx 88 62 movw %cx, %es 89 movw %cx, %ds 63 movw %cx, %ds # kernel data + stack 90 64 movw %cx, %ss 91 65 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 96 71 movw $gdtselector(UDATA_DES), %cx 97 72 movw %cx, %fs … … 101 76 multiboot_meeting_point: 102 77 103 /* Save GRUB arguments */ 104 movl %eax, grub_eax 78 movl %eax, grub_eax # save parameters from GRUB 105 79 movl %ebx, grub_ebx 106 80 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 # 108 85 109 86 movl $(INTEL_CPUID_EXTENDED), %eax … … 112 89 ja extended_cpuid_supported 113 90 114 pm_error $err_extended_cpuid 91 movl $extended_cpuid_msg, %esi 92 jmp error_halt 115 93 116 94 extended_cpuid_supported: … … 121 99 jc long_mode_supported 122 100 123 pm_error $err_long_mode 101 movl $long_mode_msg, %esi 102 jmp error_halt 124 103 125 104 long_mode_supported: … … 128 107 jc noexecute_supported 129 108 130 pm_error $err_noexecute 109 movl $noexecute_msg, %esi 110 jmp error_halt 131 111 132 112 noexecute_supported: … … 137 117 jc fx_supported 138 118 139 pm_error $err_fx 119 movl $fx_msg, %esi 120 jmp error_halt 140 121 141 122 fx_supported: … … 144 125 jc sse2_supported 145 126 146 pm_error $err_sse2 127 movl $sse2_msg, %esi 128 jmp error_halt 147 129 148 130 sse2_supported: 149 131 150 132 #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 # 163 138 164 139 movl %cr4, %eax … … 166 141 movl %eax, %cr4 167 142 168 /* Set up paging tables */ 143 # set up paging tables 144 169 145 leal ptl_0, %eax 170 146 movl %eax, %cr3 171 147 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 179 157 movl %cr0, %eax 180 158 btsl $31, %eax 181 159 movl %eax, %cr0 182 160 183 /* At this point we are in compatibility mode */ 161 # at this point we are in compatibility mode 162 184 163 jmpl $gdtselector(KTEXT_DES), $start64 185 164 186 /** Print string to EGA display (in light red) and halt. 187 * 188 * Should be executed from 32 bit protected mode with paging 189 * turned off. Stack is not required. This routine is used even 190 * if CONFIG_EGA is not enabled. Since we are going to halt the 191 * CPU anyway, it is always better to at least try to print 192 * some hints. 193 * 194 * @param %esi NULL-terminated string to print. 195 * 196 */ 197 pm_error_halt: 198 movl $0xb8000, %edi /* base of EGA text mode memory */ 165 .code64 166 start64: 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 193 error_halt: 194 movl $0xb8000, %edi # base of EGA text mode memory 199 195 xorl %eax, %eax 200 196 201 /* Read bits 8 - 15 of the cursor address */ 202 movw $0x3d4, %dx 197 movw $0x3d4, %dx # read bits 8 - 15 of the cursor address 203 198 movb $0xe, %al 204 199 outb %al, %dx … … 208 203 shl $8, %ax 209 204 210 /* Read bits 0 - 7 of the cursor address */ 211 movw $0x3d4, %dx 205 movw $0x3d4, %dx # read bits 0 - 7 of the cursor address 212 206 movb $0xf, %al 213 207 outb %al, %dx … … 216 210 inb %dx, %al 217 211 218 /* Sanity check for the cursor on screen */ 219 cmp $2000, %ax 220 jb err_cursor_ok 221 222 movw $1998, %ax 223 224 err_cursor_ok: 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: 225 218 226 219 movw %ax, %bx … … 228 221 addl %eax, %edi 229 222 230 err_ploop: 223 movw $0x0c00, %ax # black background, light red foreground 224 225 ploop: 231 226 lodsb 232 233 227 cmp $0, %al 234 je err_ploop_end 235 236 movb $0x0c, %ah /* black background, light red foreground */ 228 je ploop_end 237 229 stosw 238 239 /* Sanity check for the cursor on the last line */240 230 inc %bx 241 cmp $2000, %bx 242 jb err_ploop 243 244 /* Scroll the screen (24 rows) */ 245 movl %esi, %edx 246 movl $0xb80a0, %esi 247 movl $0xb8000, %edi 248 movl $1920, %ecx 249 rep movsw 250 251 /* Clear the 24th row */ 252 xorl %eax, %eax 253 movl $80, %ecx 254 rep stosw 255 256 /* Go to row 24 */ 257 movl %edx, %esi 258 movl $0xb8f00, %edi 259 movw $1920, %bx 260 261 jmp err_ploop 262 err_ploop_end: 263 264 /* Write bits 8 - 15 of the cursor address */ 265 movw $0x3d4, %dx 231 jmp ploop 232 ploop_end: 233 234 movw $0x3d4, %dx # write bits 8 - 15 of the cursor address 266 235 movb $0xe, %al 267 236 outb %al, %dx … … 271 240 outb %al, %dx 272 241 273 /* Write bits 0 - 7 of the cursor address */ 274 movw $0x3d4, %dx 242 movw $0x3d4, %dx # write bits 0 - 7 of the cursor address 275 243 movb $0xf, %al 276 244 outb %al, %dx … … 285 253 jmp hlt1 286 254 287 /** Print string to EGA display (in light green).288 *289 * Should be called from 32 bit protected mode with paging290 * turned off. A stack space of at least 24 bytes is required,291 * but the function does not establish a stack frame.292 *293 * Macros such as pm_status and pm2_status take care that294 * this function is used only when CONFIG_EGA is enabled295 * and CONFIG_FB is disabled.296 *297 * @param %esi NULL-terminated string to print.298 *299 */300 pm_early_puts:301 pushl %eax302 pushl %ebx303 pushl %ecx304 pushl %edx305 pushl %edi306 307 movl $0xb8000, %edi /* base of EGA text mode memory */308 xorl %eax, %eax309 310 /* Read bits 8 - 15 of the cursor address */311 movw $0x3d4, %dx312 movb $0xe, %al313 outb %al, %dx314 315 movw $0x3d5, %dx316 inb %dx, %al317 shl $8, %ax318 319 /* Read bits 0 - 7 of the cursor address */320 movw $0x3d4, %dx321 movb $0xf, %al322 outb %al, %dx323 324 movw $0x3d5, %dx325 inb %dx, %al326 327 /* Sanity check for the cursor on screen */328 cmp $2000, %ax329 jb pm_puts_cursor_ok330 331 movw $1998, %ax332 333 pm_puts_cursor_ok:334 335 movw %ax, %bx336 shl $1, %eax337 addl %eax, %edi338 339 pm_puts_ploop:340 lodsb341 342 cmp $0, %al343 je pm_puts_ploop_end344 345 movb $0x0a, %ah /* black background, light green foreground */346 stosw347 348 /* Sanity check for the cursor on the last line */349 inc %bx350 cmp $2000, %bx351 jb pm_puts_ploop352 353 /* Scroll the screen (24 rows) */354 movl %esi, %edx355 movl $0xb80a0, %esi356 movl $0xb8000, %edi357 movl $1920, %ecx358 rep movsw359 360 /* Clear the 24th row */361 xorl %eax, %eax362 movl $80, %ecx363 rep stosw364 365 /* Go to row 24 */366 movl %edx, %esi367 movl $0xb8f00, %edi368 movw $1920, %bx369 370 jmp pm_puts_ploop371 pm_puts_ploop_end:372 373 /* Write bits 8 - 15 of the cursor address */374 movw $0x3d4, %dx375 movb $0xe, %al376 outb %al, %dx377 378 movw $0x3d5, %dx379 movb %bh, %al380 outb %al, %dx381 382 /* Write bits 0 - 7 of the cursor address */383 movw $0x3d4, %dx384 movb $0xf, %al385 outb %al, %dx386 387 movw $0x3d5, %dx388 movb %bl, %al389 outb %al, %dx390 391 popl %edi392 popl %edx393 popl %ecx394 popl %ebx395 popl %eax396 397 ret398 399 .code64400 401 .macro long_status msg402 pushq %rdi403 movq \msg, %rdi404 call early_puts405 popq %rdi406 .endm407 408 start64:409 410 /*411 * Long mode.412 */413 414 movq $(PA2KA(START_STACK)), %rsp415 416 /* Create the first stack frame */417 pushq $0418 movq %rsp, %rbp419 420 long_status $status_long421 422 /* Call arch_pre_main(grub_eax, grub_ebx) */423 xorq %rdi, %rdi424 movl grub_eax, %edi425 xorq %rsi, %rsi426 movl grub_ebx, %esi427 428 movabsq $arch_pre_main, %rax429 callq *%rax430 431 long_status $status_main432 433 /* Call main_bsp() */434 movabsq $main_bsp, %rax435 call *%rax436 437 /* Not reached */438 cli439 hlt0:440 hlt441 jmp hlt0442 443 /** Print string to EGA display.444 *445 * Should be called from long mode (with paging enabled446 * and stack established). This function is ABI compliant447 * (without red-zone).448 *449 * If CONFIG_EGA is undefined or CONFIG_FB is defined450 * then this function does nothing.451 *452 * @param %rdi NULL-terminated string to print.453 *454 */455 early_puts:456 457 #if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))458 459 /* Prologue, save preserved registers */460 pushq %rbp461 movq %rsp, %rbp462 pushq %rbx463 464 movq %rdi, %rsi465 movq $(PA2KA(0xb8000)), %rdi /* base of EGA text mode memory */466 xorq %rax, %rax467 468 /* Read bits 8 - 15 of the cursor address */469 movw $0x3d4, %dx470 movb $0xe, %al471 outb %al, %dx472 473 movw $0x3d5, %dx474 inb %dx, %al475 shl $8, %ax476 477 /* Read bits 0 - 7 of the cursor address */478 movw $0x3d4, %dx479 movb $0xf, %al480 outb %al, %dx481 482 movw $0x3d5, %dx483 inb %dx, %al484 485 /* Sanity check for the cursor on screen */486 cmp $2000, %ax487 jb early_puts_cursor_ok488 489 movw $1998, %ax490 491 early_puts_cursor_ok:492 493 movw %ax, %bx494 shl $1, %rax495 addq %rax, %rdi496 497 early_puts_ploop:498 lodsb499 500 cmp $0, %al501 je early_puts_ploop_end502 503 movb $0x0e, %ah /* black background, yellow foreground */504 stosw505 506 /* Sanity check for the cursor on the last line */507 inc %bx508 cmp $2000, %bx509 jb early_puts_ploop510 511 /* Scroll the screen (24 rows) */512 movq %rsi, %rdx513 movq $(PA2KA(0xb80a0)), %rsi514 movq $(PA2KA(0xb8000)), %rdi515 movq $1920, %rcx516 rep movsw517 518 /* Clear the 24th row */519 xorq %rax, %rax520 movq $80, %rcx521 rep stosw522 523 /* Go to row 24 */524 movq %rdx, %rsi525 movq $(PA2KA(0xb8f00)), %rdi526 movw $1920, %bx527 528 jmp early_puts_ploop529 early_puts_ploop_end:530 531 /* Write bits 8 - 15 of the cursor address */532 movw $0x3d4, %dx533 movb $0xe, %al534 outb %al, %dx535 536 movw $0x3d5, %dx537 movb %bh, %al538 outb %al, %dx539 540 /* Write bits 0 - 7 of the cursor address */541 movw $0x3d4, %dx542 movb $0xf, %al543 outb %al, %dx544 545 movw $0x3d5, %dx546 movb %bl, %al547 outb %al, %dx548 549 /* Epilogue, restore preserved registers */550 popq %rbx551 leave552 553 #endif554 555 ret556 557 255 #include "vesa_real.inc" 558 256 559 257 .section K_INI_PTLS, "aw", @progbits 560 258 561 /** Generate initial page table contents. 562 * 563 * @param cnt Number of entries to generate. Must be multiple of 8. 564 * @param g Number of GB that will be added to the mapping. 565 * 566 */ 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 # 567 264 .macro ptl2gen cnt g 568 265 .if \cnt … … 579 276 .endm 580 277 581 /* Page table for pages in the 1st gigabyte. */ 278 # Page table for pages in the 1st gigabyte. 582 279 .align 4096 583 280 ptl_2_0g: 584 281 ptl2gen 512 0 585 282 586 /* Page table for pages in the 2nd gigabyte. */ 283 # Page table for pages in the 2nd gigabyte. 587 284 .align 4096 588 285 ptl_2_1g: 589 286 ptl2gen 512 1 590 287 591 /* Page table for pages in the 3rd gigabyte. */ 288 # Page table for pages in the 3rd gigabyte. 592 289 .align 4096 593 290 ptl_2_2g: 594 291 ptl2gen 512 2 595 292 596 /* Page table for pages in the 4th gigabyte. */ 293 # Page table for pages in the 4th gigabyte. 597 294 .align 4096 598 295 ptl_2_3g: 599 296 ptl2gen 512 3 600 297 601 /* Page table for pages in the 5th gigabyte. */ 298 # Page table for pages in the 5th gigabyte. 602 299 .align 4096 603 300 ptl_2_4g: 604 301 ptl2gen 512 3 605 302 606 /* Page table for pages in the 6th gigabyte. */ 303 # Page table for pages in the 6th gigabyte. 607 304 .align 4096 608 305 ptl_2_5g: 609 306 ptl2gen 512 3 610 307 611 /* Page table for pages in the 7th gigabyte. */ 308 # Page table for pages in the 7th gigabyte. 612 309 .align 4096 613 310 ptl_2_6g: 614 311 ptl2gen 512 3 615 312 616 /* Page table for pages in the 8th gigabyte. */ 313 # Page table for pages in the 8th gigabyte. 617 314 .align 4096 618 315 ptl_2_7g: … … 621 318 .align 4096 622 319 ptl_1: 623 /* Identity mapping for [0; 8G) */320 # Identity mapping for [0; 8G) 624 321 .quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT) 625 322 .quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT) … … 653 350 .long 0 654 351 655 e rr_extended_cpuid:352 extended_cpuid_msg: 656 353 .asciz "Error: Extended CPUID not supported -- CPU is not 64-bit. System halted." 657 err_long_mode:354 long_mode_msg: 658 355 .asciz "Error: 64-bit long mode not supported. System halted." 659 err_noexecute:356 noexecute_msg: 660 357 .asciz "Error: No-execute pages not supported. System halted." 661 err_fx:358 fx_msg: 662 359 .asciz "Error: FXSAVE/FXRESTORE instructions not supported. System halted." 663 err_sse2:360 sse2_msg: 664 361 .asciz "Error: SSE2 instructions not supported. System halted." 665 666 status_prot:667 .asciz "[prot] "668 status_vesa_copy:669 .asciz "[vesa_copy] "670 status_grub_cmdline:671 .asciz "[grub_cmdline] "672 status_vesa_real:673 .asciz "[vesa_real] "674 status_prot2:675 .asciz "[prot2] "676 status_long:677 .asciz "[long] "678 status_main:679 .asciz "[main] " -
kernel/arch/amd64/src/boot/vesa_ret.inc
r90ed058 reee047c 1 1 .code32 2 2 vesa_init_protected: 3 cld4 5 /* Initialize stack pointer */6 movl $START_STACK, %esp7 8 /* Kernel data + stack */9 3 movw $gdtselector(KDATA_DES), %cx 10 4 movw %cx, %es 11 movw %cx, %ds 5 movw %cx, %ds # kernel data + stack 12 6 movw %cx, %ss 13 7 14 /*15 *Simics seems to remove hidden part of GS on entering user mode16 *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 # 18 12 19 13 movw $gdtselector(UDATA_DES), %cx … … 21 15 movw %cx, %gs 22 16 17 movl $START_STACK, %esp # initialize stack pointer 18 23 19 jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point -
kernel/arch/ia32/include/smp/apic.h
r90ed058 reee047c 347 347 348 348 extern uint32_t apic_id_mask; 349 extern uint8_t bsp_l_apic;350 349 351 350 extern void apic_init(void); … … 356 355 extern int l_apic_send_init_ipi(uint8_t); 357 356 extern void l_apic_debug(void); 357 extern uint8_t l_apic_id(void); 358 358 359 359 extern uint32_t io_apic_read(uint8_t); -
kernel/arch/ia32/src/boot/boot.S
r90ed058 reee047c 1 /* 2 * Copyright (c) 2001Jakub Jermar3 * Copyright (c) 2005Martin Decky4 *All rights reserved.5 * 6 *Redistribution and use in source and binary forms, with or without7 *modification, are permitted provided that the following conditions8 *are met:9 * 10 *- Redistributions of source code must retain the above copyright11 *notice, this list of conditions and the following disclaimer.12 *- Redistributions in binary form must reproduce the above copyright13 *notice, this list of conditions and the following disclaimer in the14 *documentation and/or other materials provided with the distribution.15 *- The name of the author may not be used to endorse or promote products16 *derived from this software without specific prior written permission.17 * 18 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR19 *IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES20 *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, BUT23 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,24 *DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY25 *THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT26 *(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF27 *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 # 29 29 30 30 #include <arch/boot/boot.h> … … 34 34 #include <arch/cpuid.h> 35 35 36 #define START_STACK 36 #define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE) 37 37 38 38 .section K_TEXT_START, "ax" 39 39 40 40 .code32 41 42 .macro pm_error msg43 movl \msg, %esi44 jmp pm_error_halt45 .endm46 47 .macro pm_status msg48 #ifdef CONFIG_EGA49 pushl %esi50 movl \msg, %esi51 call pm_early_puts52 popl %esi53 #endif54 .endm55 56 .macro pm2_status msg57 pushl \msg58 call early_puts59 .endm60 61 41 .align 4 62 42 .global multiboot_image_start … … 64 44 .long MULTIBOOT_HEADER_MAGIC 65 45 .long MULTIBOOT_HEADER_FLAGS 66 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) /* checksum */46 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum 67 47 .long multiboot_header 68 48 .long unmapped_ktext_start … … 73 53 multiboot_image_start: 74 54 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 83 58 movw $gdtselector(KDATA_DES), %cx 84 59 movw %cx, %es 85 60 movw %cx, %fs 86 61 movw %cx, %gs 87 movw %cx, %ds 62 movw %cx, %ds # kernel data + stack 88 63 movw %cx, %ss 89 64 … … 91 66 multiboot_meeting_point: 92 67 93 /* Save GRUB arguments */ 94 movl %eax, grub_eax 68 movl %eax, grub_eax # save parameters from GRUB 95 69 movl %ebx, grub_ebx 96 97 pm_status $status_prot98 70 99 71 movl $(INTEL_CPUID_LEVEL), %eax 100 72 cpuid 101 cmp $0x0, %eax /* any function > 0? */73 cmp $0x0, %eax # any function > 0? 102 74 jbe pse_unsupported 103 75 … … 108 80 109 81 pse_unsupported: 110 111 pm_error $err_pse82 movl $pse_msg, %esi 83 jmp error_halt 112 84 113 85 pse_supported: 114 86 115 87 #include "vesa_prot.inc" 116 117 /* Map kernel and turn paging on */88 89 # map kernel and turn paging on 118 90 call map_kernel 119 91 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) 127 93 pushl grub_ebx 128 94 pushl grub_eax 129 95 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 134 101 call main_bsp 135 102 136 /* Not reached */103 # not reached 137 104 cli 138 105 hlt0: … … 140 107 jmp hlt0 141 108 142 /** Setup mapping for the kernel.143 *144 * Setup mapping for both the unmapped and mapped sections145 * of the kernel. For simplicity, we map the entire 4G space.146 *147 */148 109 .global map_kernel 149 110 map_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 # 150 115 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 153 118 movl %ecx, %cr4 154 119 … … 161 126 movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax 162 127 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 167 130 addl $(4 * 1024 * 1024), %ebx 168 131 … … 174 137 175 138 movl %cr0, %ebx 176 orl $(1 << 31), %ebx /* paging on */139 orl $(1 << 31), %ebx # turn paging on 177 140 movl %ebx, %cr0 178 141 ret 179 142 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 144 error_halt: 145 movl $0xb8000, %edi # base of EGA text mode memory 193 146 xorl %eax, %eax 194 147 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 197 149 movb $0xe, %al 198 150 outb %al, %dx … … 202 154 shl $8, %ax 203 155 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 206 157 movb $0xf, %al 207 158 outb %al, %dx … … 210 161 inb %dx, %al 211 162 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: 219 169 220 170 movw %ax, %bx … … 222 172 addl %eax, %edi 223 173 224 err_ploop: 174 movw $0x0c00, %ax # black background, light red foreground 175 176 ploop: 225 177 lodsb 226 227 178 cmp $0, %al 228 je err_ploop_end 229 230 movb $0x0c, %ah /* black background, light red foreground */ 179 je ploop_end 231 180 stosw 232 233 /* Sanity check for the cursor on the last line */234 181 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 260 186 movb $0xe, %al 261 187 outb %al, %dx … … 265 191 outb %al, %dx 266 192 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 269 194 movb $0xf, %al 270 195 outb %al, %dx … … 279 204 jmp hlt1 280 205 281 /** Print string to EGA display (in light green).282 *283 * Should be called from 32 bit protected mode with paging284 * 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 function288 * 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 %eax295 pushl %ebx296 pushl %ecx297 pushl %edx298 pushl %edi299 300 movl $0xb8000, %edi /* base of EGA text mode memory */301 xorl %eax, %eax302 303 /* Read bits 8 - 15 of the cursor address */304 movw $0x3d4, %dx305 movb $0xe, %al306 outb %al, %dx307 308 movw $0x3d5, %dx309 inb %dx, %al310 shl $8, %ax311 312 /* Read bits 0 - 7 of the cursor address */313 movw $0x3d4, %dx314 movb $0xf, %al315 outb %al, %dx316 317 movw $0x3d5, %dx318 inb %dx, %al319 320 /* Sanity check for the cursor on screen */321 cmp $2000, %ax322 jb pm_puts_cursor_ok323 324 movw $1998, %ax325 326 pm_puts_cursor_ok:327 328 movw %ax, %bx329 shl $1, %eax330 addl %eax, %edi331 332 pm_puts_ploop:333 lodsb334 335 cmp $0, %al336 je pm_puts_ploop_end337 338 movb $0x0a, %ah /* black background, light green foreground */339 stosw340 341 /* Sanity check for the cursor on the last line */342 inc %bx343 cmp $2000, %bx344 jb pm_puts_ploop345 346 /* Scroll the screen (24 rows) */347 movl %esi, %edx348 movl $0xb80a0, %esi349 movl $0xb8000, %edi350 movl $1920, %ecx351 rep movsw352 353 /* Clear the 24th row */354 xorl %eax, %eax355 movl $80, %ecx356 rep stosw357 358 /* Go to row 24 */359 movl %edx, %esi360 movl $0xb8f00, %edi361 movw $1920, %bx362 363 jmp pm_puts_ploop364 pm_puts_ploop_end:365 366 /* Write bits 8 - 15 of the cursor address */367 movw $0x3d4, %dx368 movb $0xe, %al369 outb %al, %dx370 371 movw $0x3d5, %dx372 movb %bh, %al373 outb %al, %dx374 375 /* Write bits 0 - 7 of the cursor address */376 movw $0x3d4, %dx377 movb $0xf, %al378 outb %al, %dx379 380 movw $0x3d5, %dx381 movb %bl, %al382 outb %al, %dx383 384 popl %edi385 popl %edx386 popl %ecx387 popl %ebx388 popl %eax389 390 ret391 392 /** Print string to EGA display.393 *394 * Should be called from 32 bit protected mode (with paging395 * enabled and stack established). This function is ABI compliant.396 *397 * If CONFIG_EGA is undefined or CONFIG_FB is defined398 * 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 %ebp409 movl %esp, %ebp410 pushl %ebx411 pushl %esi412 pushl %edi413 414 movl 0x08(%ebp), %esi415 movl $(PA2KA(0xb8000)), %edi /* base of EGA text mode memory */416 xorl %eax, %eax417 418 /* Read bits 8 - 15 of the cursor address */419 movw $0x3d4, %dx420 movb $0xe, %al421 outb %al, %dx422 423 movw $0x3d5, %dx424 inb %dx, %al425 shl $8, %ax426 427 /* Read bits 0 - 7 of the cursor address */428 movw $0x3d4, %dx429 movb $0xf, %al430 outb %al, %dx431 432 movw $0x3d5, %dx433 inb %dx, %al434 435 /* Sanity check for the cursor on screen */436 cmp $2000, %ax437 jb early_puts_cursor_ok438 439 movw $1998, %ax440 441 early_puts_cursor_ok:442 443 movw %ax, %bx444 shl $1, %eax445 addl %eax, %edi446 447 early_puts_ploop:448 lodsb449 450 cmp $0, %al451 je early_puts_ploop_end452 453 movb $0x0e, %ah /* black background, yellow foreground */454 stosw455 456 /* Sanity check for the cursor on the last line */457 inc %bx458 cmp $2000, %bx459 jb early_puts_ploop460 461 /* Scroll the screen (24 rows) */462 movl %esi, %edx463 movl $(PA2KA(0xb80a0)), %esi464 movl $(PA2KA(0xb8000)), %edi465 movl $1920, %ecx466 rep movsw467 468 /* Clear the 24th row */469 xorl %eax, %eax470 movl $80, %ecx471 rep stosw472 473 /* Go to row 24 */474 movl %edx, %esi475 movl $(PA2KA(0xb8f00)), %edi476 movw $1920, %bx477 478 jmp early_puts_ploop479 early_puts_ploop_end:480 481 /* Write bits 8 - 15 of the cursor address */482 movw $0x3d4, %dx483 movb $0xe, %al484 outb %al, %dx485 486 movw $0x3d5, %dx487 movb %bh, %al488 outb %al, %dx489 490 /* Write bits 0 - 7 of the cursor address */491 movw $0x3d4, %dx492 movb $0xf, %al493 outb %al, %dx494 495 movw $0x3d5, %dx496 movb %bl, %al497 outb %al, %dx498 499 /* Epilogue, restore preserved registers */500 popl %edi501 popl %esi502 popl %ebx503 leave504 505 #endif506 507 ret508 509 206 #include "vesa_real.inc" 510 207 … … 521 218 .long 0 522 219 523 err_pse:220 pse_msg: 524 221 .asciz "Page Size Extension not supported. System halted." 525 222 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
r90ed058 reee047c 5 5 #define MBINFO_OFFSET_CMDLINE 16 6 6 7 /* Copy real mode VESA initialization code */ 8 9 pm_status $status_vesa_copy 7 # copy real mode VESA initialization code 10 8 11 9 mov $vesa_init, %esi … … 14 12 rep movsb 15 13 16 /* Check for GRUB command line */ 17 18 pm_status $status_grub_cmdline 14 # check for GRUB command line 19 15 20 16 mov grub_eax, %eax … … 27 23 jnc no_cmdline 28 24 29 /* Skip the kernel path in command line */25 # skip the kernel path in command line 30 26 31 27 mov MBINFO_OFFSET_CMDLINE(%ebx), %esi … … 56 52 space_loop_done: 57 53 58 /* Copy at most 23 characters from command line */54 # copy at most 23 characters from command line 59 55 60 56 mov $VESA_INIT_SEGMENT << 4, %edi … … 72 68 cmd_loop_done: 73 69 74 /* Zero termination */70 # zero termination 75 71 76 72 xor %eax, %eax … … 79 75 no_cmdline: 80 76 81 /* Jump to the real mode */ 82 83 pm_status $status_vesa_real 77 # jump to the real mode 84 78 85 79 mov $VESA_INIT_SEGMENT << 4, %edi … … 87 81 88 82 vesa_meeting_point: 89 /* Returned back to protected mode */83 # returned back to protected mode 90 84 91 85 mov %ax, KA2PA(vesa_scanline) -
kernel/arch/ia32/src/boot/vesa_real.inc
r90ed058 reee047c 31 31 vesa_init: 32 32 jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init 33 33 34 34 .code16 35 35 vesa_init_real: … … 55 55 pushl %eax 56 56 57 /* Parse default mode string */57 # parse default mode string 58 58 59 59 mov $default_mode - vesa_init, %di … … 65 65 mov (%di), %al 66 66 67 /* Check for digit */67 # check for digit 68 68 69 69 cmp $'0', %al … … 75 75 sub $'0', %al 76 76 77 /* Multiply default_width by 10 and add digit */77 # multiply default_width by 10 and add digit 78 78 79 79 mov default_width - vesa_init, %bx … … 96 96 mov (%di), %al 97 97 98 /* Check for digit */98 # check for digit 99 99 100 100 cmp $'0', %al … … 106 106 sub $'0', %al 107 107 108 /* Multiply default_height by 10 and add digit */108 # multiply default_height by 10 and add digit 109 109 110 110 mov default_height - vesa_init, %bx … … 127 127 mov (%di), %al 128 128 129 /* Check for digit */129 # check for digit 130 130 131 131 cmp $'0', %al … … 137 137 sub $'0', %al 138 138 139 /* Multiply default_bpp by 10 and add digit */139 # multiply default_bpp by 10 and add digit 140 140 141 141 mov default_bpp - vesa_init, %bx … … 167 167 168 168 next_mode: 169 /* Try next mode */ 170 169 # try next mode 171 170 mov %gs:(%si), %cx 172 171 cmp $VESA_END_OF_MODES, %cx … … 187 186 jne no_mode 188 187 189 /* 190 * Check for proper attributes (supported, 191 * color, graphics, linear framebuffer). 192 */ 188 # check for proper attributes (supported, color, graphics, linear framebuffer) 193 189 194 190 mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax … … 197 193 jne next_mode 198 194 199 /* Check for proper resolution */195 # check for proper resolution 200 196 201 197 mov default_width - vesa_init, %ax … … 207 203 jne next_mode 208 204 209 /* Check for proper bpp */205 # check for proper bpp 210 206 211 207 mov default_bpp - vesa_init, %al … … 217 213 jne next_mode 218 214 219 /* For 24 bpp modes accept also 32 bit bpp */215 # for 24 bpp modes accept also 32 bit bpp 220 216 221 217 mov $32, %al … … 234 230 jnz no_mode 235 231 236 /* Set 3:2:3 VGA palette */232 # set 3:2:3 VGA palette 237 233 238 234 mov VESA_MODE_BPP_OFFSET(%di), %al … … 245 241 mov $0x100, %ecx 246 242 247 /* Test if VGA compatible registers are present */ 248 bt $5, %ax 243 bt $5, %ax # test if VGA compatible registers are present 249 244 jnc vga_compat 250 245 251 /* Use VESA routine to set the palette */ 252 246 # try VESA routine to set palette 253 247 mov $VESA_SET_PALETTE, %ax 254 248 xor %bl, %bl … … 260 254 261 255 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 266 258 movb $0xff, %al 267 259 outb %al, %dx 268 260 269 movw $0x3c8, %dx /* first index to set */261 movw $0x3c8, %dx # first index to set 270 262 xor %al, %al 271 263 outb %al, %dx 272 264 273 movw $0x3c9, %dx /* data port */265 movw $0x3c9, %dx # data port 274 266 275 267 vga_loop: … … 292 284 vga_not_set: 293 285 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 302 292 303 293 mov VESA_MODE_BPP_OFFSET(%di), %al … … 338 328 339 329 no_mode: 340 341 /* No prefered mode found */ 342 330 # no prefered mode found 343 331 mov $0x111, %cx 344 332 push %di … … 351 339 cmp $VESA_OK, %al 352 340 jnz text_mode 353 jz set_mode /* force relative jump */341 jz set_mode # force relative jump 354 342 355 343 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) 359 345 mov $0x0003, %ax 360 346 int $0x10 361 347 mov $0xffffffff, %edi 362 348 xor %ax, %ax 363 jz vesa_leave_real /* force relative jump */349 jz vesa_leave_real # force relative jump 364 350 365 351 vga323: -
kernel/arch/ia32/src/boot/vesa_ret.inc
r90ed058 reee047c 1 1 .code32 2 2 vesa_init_protected: 3 cld4 5 /* Initialize stack pointer */6 movl $START_STACK, %esp7 8 /* Kernel data + stack */9 3 movw $gdtselector(KDATA_DES), %cx 10 4 movw %cx, %es 11 5 movw %cx, %fs 12 6 movw %cx, %gs 13 movw %cx, %ds 7 movw %cx, %ds # kernel data + stack 14 8 movw %cx, %ss 15 9 10 movl $START_STACK, %esp # initialize stack pointer 11 16 12 jmpl $gdtselector(KTEXT_DES), $vesa_meeting_point -
kernel/arch/ia32/src/smp/apic.c
r90ed058 reee047c 76 76 77 77 uint32_t apic_id_mask = 0; 78 uint8_t bsp_l_apic = 0;79 80 78 static irq_t l_apic_timer_irq; 81 79 … … 156 154 } 157 155 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 171 156 /** Initialize APIC on BSP. */ 172 157 void apic_init(void) … … 223 208 l_apic_init(); 224 209 l_apic_debug(); 225 226 bsp_l_apic = l_apic_id();227 210 } 228 211 … … 477 460 { 478 461 #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()); 481 463 482 464 lvt_tm_t tm; 483 465 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]); 487 467 488 468 lvt_lint_t lint; 489 469 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]); 500 473 501 474 lvt_error_t error; 502 475 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]); 505 477 #endif 478 } 479 480 /** Get Local APIC ID. 481 * 482 * @return Local APIC ID. 483 * 484 */ 485 uint8_t l_apic_id(void) 486 { 487 l_apic_id_t idreg; 488 489 idreg.value = l_apic[L_APIC_ID]; 490 return idreg.apic_id; 506 491 } 507 492 -
kernel/arch/ia32/src/smp/mps.c
r90ed058 reee047c 72 72 static size_t l_intr_entry_cnt = 0; 73 73 74 static uint8_t mps_cpu_apic_id(size_t i)74 static uint8_t get_cpu_apic_id(size_t i) 75 75 { 76 76 ASSERT(i < processor_entry_cnt); … … 79 79 } 80 80 81 static bool mps_cpu_enabled(size_t i)81 static bool is_cpu_enabled(size_t i) 82 82 { 83 83 ASSERT(i < processor_entry_cnt); … … 85 85 /* 86 86 * FIXME: The current local APIC driver limits usable 87 * CPUIDs to 8.87 * APIC IDs to 8. 88 88 * 89 89 */ 90 if ( i> 7)90 if (get_cpu_apic_id(i) > 7) 91 91 return false; 92 92 … … 94 94 } 95 95 96 static bool mps_cpu_bootstrap(size_t i)96 static bool is_bsp(size_t i) 97 97 { 98 98 ASSERT(i < processor_entry_cnt); … … 118 118 */ 119 119 struct 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, 123 123 .irq_to_pin = mps_irq_to_pin 124 124 }; -
kernel/arch/ia32/src/smp/smp.c
r90ed058 reee047c 62 62 void smp_init(void) 63 63 { 64 uintptr_t l_apic_address; 65 uintptr_t io_apic_address; 66 64 67 if (acpi_madt) { 65 68 acpi_madt_parse(); … … 72 75 } 73 76 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 74 87 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; 77 97 } 78 98 } … … 113 133 apic_init(); 114 134 135 uint8_t apic = l_apic_id(); 136 115 137 for (i = 0; i < config.cpu_count; i++) { 116 138 /* … … 126 148 continue; 127 149 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); 131 153 continue; 132 154 } -
kernel/genarch/src/acpi/madt.c
r90ed058 reee047c 95 95 /* 96 96 * FIXME: The current local APIC driver limits usable 97 * CPUIDs to 8.97 * APIC IDs to 8. 98 98 * 99 99 */ 100 if ( i> 7)100 if (madt_cpu_apic_id(i) > 7) 101 101 return false; 102 102 … … 111 111 return ((struct madt_l_apic *) 112 112 madt_entries_index[madt_l_apic_entry_index + i])->apic_id == 113 bsp_l_apic;113 l_apic_id(); 114 114 } 115 115 … … 131 131 }; 132 132 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;133 static int madt_cmp(void *a, void *b) 134 { 135 uint8_t typea = ((struct madt_apic_header *) a)->type; 136 uint8_t typeb = ((struct madt_apic_header *) b)->type; 137 137 138 138 if (typea > typeb) … … 147 147 static void madt_l_apic_entry(struct madt_l_apic *la, size_t i) 148 148 { 149 if ( madt_l_apic_entry_cnt == 0)149 if (!madt_l_apic_entry_cnt++) 150 150 madt_l_apic_entry_index = i; 151 152 madt_l_apic_entry_cnt++;153 151 154 152 if (!(la->flags & 0x1)) { … … 162 160 static void madt_io_apic_entry(struct madt_io_apic *ioa, size_t i) 163 161 { 164 if ( madt_io_apic_entry_cnt == 0) {162 if (!madt_io_apic_entry_cnt++) { 165 163 /* Remember index of the first io apic entry */ 166 164 madt_io_apic_entry_index = i; … … 169 167 /* Currently not supported */ 170 168 } 171 172 madt_io_apic_entry_cnt++;173 169 } 174 170 … … 194 190 /* Count MADT entries */ 195 191 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; 197 193 hdr = (struct madt_apic_header *) (((uint8_t *) hdr) + hdr->length)) 198 194 madt_entries_index_cnt++; … … 200 196 /* Create MADT APIC entries index array */ 201 197 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 **), 203 199 FRAME_ATOMIC); 204 200 if (!madt_entries_index) … … 207 203 size_t i = 0; 208 204 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; 214 208 215 209 /* 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); 219 212 220 213 /* Parse MADT entries */ -
kernel/generic/include/debug.h
r90ed058 reee047c 93 93 #define LOG(format, ...) \ 94 94 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__); \ 98 97 } while (0) 99 98 100 extern void __cyg_profile_func_enter(void *, void *); 101 extern void __cyg_profile_func_exit(void *, void *); 99 /** Extensive logging execute macro 100 * 101 * If CONFIG_LOG is set, the LOG_EXEC() macro 102 * will print an information about calling a given 103 * function and call it. 104 * 105 */ 106 #define LOG_EXEC(fnc) \ 107 do { \ 108 printf("%s->%s() at %s:%u: " #fnc "\n", symtab_fmt_name_lookup(CALLER), \ 109 __func__, __FILE__, __LINE__); \ 110 fnc; \ 111 } while (0) 102 112 103 113 #else /* CONFIG_LOG */ 104 114 105 115 #define LOG(format, ...) 116 #define LOG_EXEC(fnc) fnc 106 117 107 #endif /* CONF IG_LOG */118 #endif /* CONFOG_LOG */ 108 119 109 120 #endif -
kernel/generic/include/sort.h
r90ed058 reee047c 38 38 #include <typedefs.h> 39 39 40 typedef int (* sort_cmp_t)(void *, void *, void *); 40 /* 41 * sorting routines 42 */ 43 extern void bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b)); 44 extern void qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b)); 41 45 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 */ 49 extern int int_cmp(void * a, void * b); 50 extern int uint32_t_cmp(void * a, void * b); 51 extern int uint16_t_cmp(void * a, void * b); 52 extern int uint8_t_cmp(void * a, void * b); 44 53 45 54 #endif -
kernel/generic/src/lib/sort.c
r90ed058 reee047c 27 27 */ 28 28 29 /** @addtogroup generic 29 /** @addtogroup generic 30 30 * @{ 31 31 */ … … 33 33 /** 34 34 * @file 35 * @brief 35 * @brief Sorting functions. 36 36 * 37 37 * 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 42 41 #include <mm/slab.h> 43 42 #include <memstr.h> 44 43 #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 48 void _qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot); 49 void _bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot); 50 51 /** Quicksort wrapper 52 * 53 * This is only a wrapper that takes care of memory allocations for storing 54 * the pivot and temporary elements for generic quicksort algorithm. 55 * 56 * This function _can_ sleep 57 * 58 * @param data Pointer to data to be sorted. 59 * @param n Number of elements to be sorted. 60 * @param e_size Size of one element. 61 * @param cmp Comparator function. 62 * 63 */ 64 void qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b)) 65 { 66 uint8_t buf_tmp[EBUFSIZE]; 67 uint8_t buf_pivot[EBUFSIZE]; 68 void * tmp = buf_tmp; 69 void * pivot = buf_pivot; 70 71 if (e_size > EBUFSIZE) { 72 pivot = (void *) malloc(e_size, 0); 73 tmp = (void *) malloc(e_size, 0); 74 } 75 76 _qsort(data, n, e_size, cmp, tmp, pivot); 77 77 78 while (i < cnt) { 79 if ((i > 0) && 80 (cmp(INDEX(data, i, elem_size), 81 INDEX(data, i - 1, elem_size), arg) == -1)) { 82 memcpy(slot, INDEX(data, i, elem_size), elem_size); 83 memcpy(INDEX(data, i, elem_size), INDEX(data, i - 1, elem_size), 84 elem_size); 85 memcpy(INDEX(data, i - 1, elem_size), slot, elem_size); 86 printf("exch: %u %u\n", i - 1, i); 87 i--; 88 } else 89 i++; 78 if (e_size > EBUFSIZE) { 79 free(tmp); 80 free(pivot); 90 81 } 91 82 } … … 93 84 /** Quicksort 94 85 * 95 * Apply generic quicksort algorithm on supplied data, 96 * using pre-allocated buffers. 97 * 98 * @param data Pointer to data to be sorted. 99 * @param cnt Number of elements to be sorted. 100 * @param elem_size Size of one element. 101 * @param cmp Comparator function. 102 * @param arg 3rd argument passed to cmp. 103 * @param slot Pointer to scratch memory buffer 104 * elem_size bytes long. 105 * @param pivot Pointer to scratch memory buffer 106 * elem_size bytes long. 107 * 108 */ 109 static void _qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, 110 void *arg, void *slot, void *pivot) 111 { 112 if (cnt > 4) { 113 size_t i = 0; 114 size_t j = cnt - 1; 115 116 memcpy(pivot, data, elem_size); 117 118 while (true) { 119 while ((cmp(INDEX(data, i, elem_size), pivot, arg) < 0) && (i < cnt)) 86 * Apply generic quicksort algorithm on supplied data, using pre-allocated buffers. 87 * 88 * @param data Pointer to data to be sorted. 89 * @param n Number of elements to be sorted. 90 * @param e_size Size of one element. 91 * @param cmp Comparator function. 92 * @param tmp Pointer to scratch memory buffer e_size bytes long. 93 * @param pivot Pointer to scratch memory buffer e_size bytes long. 94 * 95 */ 96 void _qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot) 97 { 98 if (n > 4) { 99 unsigned int i = 0, j = n - 1; 100 101 memcpy(pivot, data, e_size); 102 103 while (1) { 104 while ((cmp(data + i * e_size, pivot) < 0) && (i < n)) 120 105 i++; 121 122 while ((cmp(INDEX(data, j, elem_size), pivot, arg) >= 0) && (j > 0)) 106 while ((cmp(data + j * e_size, pivot) >= 0) && (j > 0)) 123 107 j--; 124 108 125 109 if (i < j) { 126 memcpy(slot, INDEX(data, i, elem_size), elem_size); 127 memcpy(INDEX(data, i, elem_size), INDEX(data, j, elem_size), 128 elem_size); 129 memcpy(INDEX(data, j, elem_size), slot, elem_size); 130 } else 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 { 131 114 break; 115 } 132 116 } 133 134 _qsort(data, j + 1, elem_size, cmp, arg, slot, pivot); 135 _qsort(INDEX(data, j + 1, elem_size), cnt - j - 1, elem_size, 136 cmp, arg, slot, pivot); 137 } else 138 _gsort(data, cnt, elem_size, cmp, arg, slot); 139 } 140 141 /** Gnome sort wrapper 142 * 143 * This is only a wrapper that takes care of memory 144 * allocations for storing the slot element for generic 145 * gnome sort algorithm. 146 * 147 * This function can sleep. 148 * 149 * @param data Pointer to data to be sorted. 150 * @param cnt Number of elements to be sorted. 151 * @param elem_size Size of one element. 152 * @param cmp Comparator function. 153 * @param arg 3rd argument passed to cmp. 154 * 155 * @return True if sorting succeeded. 156 * 157 */ 158 bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg) 159 { 160 uint8_t ibuf_slot[IBUF_SIZE]; 161 void *slot; 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 */ 136 void bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b)) 137 { 138 uint8_t buf_slot[EBUFSIZE]; 139 void * slot = buf_slot; 162 140 163 if (elem_size > IBUF_SIZE) { 164 slot = (void *) malloc(elem_size, 0); 165 if (!slot) 166 return false; 167 } else 168 slot = (void *) ibuf_slot; 141 if (e_size > EBUFSIZE) { 142 slot = (void *) malloc(e_size, 0); 143 } 144 145 _bubblesort(data, n, e_size, cmp, slot); 169 146 170 _gsort(data, cnt, elem_size, cmp, arg, slot); 171 172 if (elem_size > IBUF_SIZE) 147 if (e_size > EBUFSIZE) { 173 148 free(slot); 174 175 return true; 176 } 177 178 /** Quicksort wrapper 179 * 180 * This is only a wrapper that takes care of memory 181 * allocations for storing the pivot and temporary elements 182 * for generic quicksort algorithm. 183 * 184 * This function can sleep. 185 * 186 * @param data Pointer to data to be sorted. 187 * @param cnt Number of elements to be sorted. 188 * @param elem_size Size of one element. 189 * @param cmp Comparator function. 190 * @param arg 3rd argument passed to cmp. 191 * 192 * @return True if sorting succeeded. 193 * 194 */ 195 bool qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg) 196 { 197 uint8_t ibuf_slot[IBUF_SIZE]; 198 uint8_t ibuf_pivot[IBUF_SIZE]; 199 void *slot; 200 void *pivot; 201 202 if (elem_size > IBUF_SIZE) { 203 slot = (void *) malloc(elem_size, 0); 204 if (!slot) 205 return false; 206 207 pivot = (void *) malloc(elem_size, 0); 208 if (!pivot) { 209 free(slot); 210 return false; 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 */ 163 void _bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot) 164 { 165 bool done = false; 166 void * p; 167 168 while (!done) { 169 done = true; 170 for (p = data; p < data + e_size * (n - 1); p = p + e_size) { 171 if (cmp(p, p + e_size) == 1) { 172 memcpy(slot, p, e_size); 173 memcpy(p, p + e_size, e_size); 174 memcpy(p + e_size, slot, e_size); 175 done = false; 176 } 211 177 } 212 } else { 213 slot = (void *) ibuf_slot; 214 pivot = (void *) ibuf_pivot; 215 } 216 217 _qsort(data, cnt, elem_size, cmp, arg, slot, pivot); 218 219 if (elem_size > IBUF_SIZE) { 220 free(pivot); 221 free(slot); 222 } 223 224 return true; 178 } 179 180 } 181 182 /* 183 * Comparator returns 1 if a > b, 0 if a == b, -1 if a < b 184 */ 185 int int_cmp(void * a, void * b) 186 { 187 return (* (int *) a > * (int*)b) ? 1 : (*(int *)a < * (int *)b) ? -1 : 0; 188 } 189 190 int uint8_t_cmp(void * a, void * b) 191 { 192 return (* (uint8_t *) a > * (uint8_t *)b) ? 1 : (*(uint8_t *)a < * (uint8_t *)b) ? -1 : 0; 193 } 194 195 int uint16_t_cmp(void * a, void * b) 196 { 197 return (* (uint16_t *) a > * (uint16_t *)b) ? 1 : (*(uint16_t *)a < * (uint16_t *)b) ? -1 : 0; 198 } 199 200 int uint32_t_cmp(void * a, void * b) 201 { 202 return (* (uint32_t *) a > * (uint32_t *)b) ? 1 : (*(uint32_t *)a < * (uint32_t *)b) ? -1 : 0; 225 203 } 226 204 -
kernel/generic/src/main/main.c
r90ed058 reee047c 104 104 105 105 /** Lowest safe stack virtual address. */ 106 uintptr_t stack_safe = 0; 106 uintptr_t stack_safe = 0; 107 107 108 108 /* … … 113 113 */ 114 114 static void main_bsp_separated_stack(void); 115 116 115 #ifdef CONFIG_SMP 117 116 static void main_ap_separated_stack(void); 118 117 #endif 119 118 120 #define CONFIG_STACK_SIZE 119 #define CONFIG_STACK_SIZE ((1 << STACK_FRAMES) * STACK_SIZE) 121 120 122 121 /** Main kernel routine for bootstrap CPU. … … 152 151 init.tasks[i].size, config.stack_size); 153 152 } 154 153 155 154 /* Avoid placing stack on top of boot allocations. */ 156 155 if (ballocs.size) { … … 171 170 } 172 171 172 173 173 /** Main kernel routine for bootstrap CPU using new stack. 174 174 * … … 176 176 * 177 177 */ 178 void main_bsp_separated_stack(void) 178 void main_bsp_separated_stack(void) 179 179 { 180 180 /* Keep this the first thing. */ … … 194 194 * commands. 195 195 */ 196 kconsole_init();196 LOG_EXEC(kconsole_init()); 197 197 #endif 198 198 … … 201 201 * starts adding its own handlers 202 202 */ 203 exc_init();203 LOG_EXEC(exc_init()); 204 204 205 205 /* 206 206 * Memory management subsystems initialization. 207 207 */ 208 arch_pre_mm_init();209 frame_init();208 LOG_EXEC(arch_pre_mm_init()); 209 LOG_EXEC(frame_init()); 210 210 211 211 /* 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()); 223 223 224 224 /* Slab must be initialized after we know the number of processors. */ 225 slab_enable_cpucache();225 LOG_EXEC(slab_enable_cpucache()); 226 226 227 227 printf("Detected %" PRIs " CPU(s), %" PRIu64" MiB free memory\n", 228 228 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()); 239 239 240 240 if (init.cnt > 0) { … … 247 247 printf("No init binaries found.\n"); 248 248 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()); 253 253 254 254 /* … … 266 266 if (!kinit_thread) 267 267 panic("Cannot create kinit thread."); 268 thread_ready(kinit_thread);268 LOG_EXEC(thread_ready(kinit_thread)); 269 269 270 270 /* … … 276 276 } 277 277 278 278 279 #ifdef CONFIG_SMP 279 280 280 /** Main kernel routine for application CPUs. 281 281 * … … 296 296 */ 297 297 config.cpu_active++; 298 298 299 299 /* 300 300 * The THE structure is well defined because ctx.sp is used as stack. … … 311 311 calibrate_delay_loop(); 312 312 arch_post_cpu_init(); 313 313 314 314 the_copy(THE, (the_t *) CPU->stack); 315 315 316 316 /* 317 317 * If we woke kmp up before we left the kernel stack, we could … … 326 326 } 327 327 328 328 329 /** Main kernel routine for application CPUs using new stack. 329 330 * … … 337 338 */ 338 339 timeout_init(); 339 340 340 341 waitq_wakeup(&ap_completion_wq, WAKEUP_FIRST); 341 342 scheduler(); 342 343 /* not reached */ 343 344 } 344 345 345 #endif /* CONFIG_SMP */ 346 346 -
uspace/lib/c/generic/sort.c
r90ed058 reee047c 36 36 * 37 37 * 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). 39 39 * 40 40 */ … … 44 44 #include <malloc.h> 45 45 46 /** Immediate buffer size.46 /** Bubble sort 47 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, 48 * Apply generic bubble sort algorithm on supplied data, 62 49 * using pre-allocated buffer. 63 50 * … … 71 58 * 72 59 */ 73 static void _ gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,60 static void _bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, 74 61 void *arg, void *slot) 75 62 { 76 size_t i = 0; 63 bool done = false; 64 void *tmp; 77 65 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 } 89 78 } 90 79 } … … 100 89 * @param cmp Comparator function. 101 90 * @param arg 3rd argument passed to cmp. 102 * @param slotPointer to scratch memory buffer91 * @param tmp Pointer to scratch memory buffer 103 92 * elem_size bytes long. 104 93 * @param pivot Pointer to scratch memory buffer … … 107 96 */ 108 97 static 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) 110 99 { 111 100 if (cnt > 4) { … … 116 105 117 106 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)) 119 108 i++; 120 109 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)) 122 111 j--; 123 112 124 113 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, 127 116 elem_size); 128 memcpy( INDEX(data, j, elem_size), slot, elem_size);117 memcpy(data + j * elem_size, tmp, elem_size); 129 118 } else 130 119 break; 131 120 } 132 121 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); 136 125 } else 137 _ gsort(data, cnt, elem_size, cmp, arg, slot);126 _bsort(data, cnt, elem_size, cmp, arg, tmp); 138 127 } 139 128 140 /** Gnome sort wrapper129 /** Bubble sort wrapper 141 130 * 142 131 * This is only a wrapper that takes care of memory 143 132 * allocations for storing the slot element for generic 144 * gnome sort algorithm.133 * bubble sort algorithm. 145 134 * 146 135 * @param data Pointer to data to be sorted. … … 153 142 * 154 143 */ 155 bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)144 bool bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg) 156 145 { 157 uint8_t ibuf_slot[IBUF_SIZE]; 158 void *slot; 146 void *slot = (void *) malloc(elem_size); 147 if (!slot) 148 return false; 159 149 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); 166 151 167 _gsort(data, cnt, elem_size, cmp, arg, slot); 168 169 if (elem_size > IBUF_SIZE) 170 free(slot); 152 free(slot); 171 153 172 154 return true; … … 190 172 bool qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg) 191 173 { 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; 196 177 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; 210 182 } 211 183 212 _qsort(data, cnt, elem_size, cmp, arg, slot, pivot);184 _qsort(data, cnt, elem_size, cmp, arg, tmp, pivot); 213 185 214 if (elem_size > IBUF_SIZE) { 215 free(pivot); 216 free(slot); 217 } 186 free(pivot); 187 free(tmp); 218 188 219 189 return true; -
uspace/lib/c/include/sort.h
r90ed058 reee047c 41 41 typedef int (* sort_cmp_t)(void *, void *, void *); 42 42 43 extern bool gsort(void *, size_t, size_t, sort_cmp_t, void *);43 extern bool bsort(void *, size_t, size_t, sort_cmp_t, void *); 44 44 extern bool qsort(void *, size_t, size_t, sort_cmp_t, void *); 45 45
Note:
See TracChangeset
for help on using the changeset viewer.