Changeset 04803bf in mainline for kernel/arch/ia32
- Timestamp:
- 2011-03-21T22:00:17Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 143932e3
- Parents:
- b50b5af2 (diff), 7308e84 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- kernel/arch/ia32
- Files:
-
- 2 added
- 61 edited
- 1 moved
-
Makefile.inc (modified) (4 diffs)
-
_link.ld.in (modified) (2 diffs)
-
include/asm.h (modified) (23 diffs)
-
include/atomic.h (modified) (7 diffs)
-
include/barrier.h (modified) (2 diffs)
-
include/bios/bios.h (modified) (2 diffs)
-
include/boot/boot.h (modified) (1 diff)
-
include/boot/memmap.h (modified) (2 diffs)
-
include/context.h (modified) (3 diffs)
-
include/context_offset.h (modified) (4 diffs)
-
include/cpu.h (modified) (4 diffs)
-
include/cpuid.h (modified) (2 diffs)
-
include/cycle.h (modified) (2 diffs)
-
include/ddi/ddi.h (modified) (1 diff)
-
include/drivers/i8254.h (modified) (1 diff)
-
include/drivers/i8259.h (modified) (2 diffs)
-
include/drivers/vesa.h (modified) (1 diff)
-
include/faddr.h (modified) (2 diffs)
-
include/fpu_context.h (modified) (2 diffs)
-
include/interrupt.h (modified) (2 diffs)
-
include/istate.h (moved) (moved from kernel/generic/include/synch/rwlock.h ) (2 diffs)
-
include/memstr.h (modified) (2 diffs)
-
include/mm/as.h (modified) (3 diffs)
-
include/mm/asid.h (modified) (2 diffs)
-
include/mm/frame.h (modified) (1 diff)
-
include/mm/page.h (modified) (9 diffs)
-
include/pm.h (modified) (5 diffs)
-
include/proc/task.h (modified) (1 diff)
-
include/proc/thread.h (modified) (1 diff)
-
include/smp/ap.h (modified) (1 diff)
-
include/smp/apic.h (modified) (10 diffs)
-
include/smp/mps.h (modified) (6 diffs)
-
include/smp/smp.h (modified) (2 diffs)
-
include/types.h (modified) (3 diffs)
-
src/asm.S (modified) (6 diffs)
-
src/bios/bios.c (modified) (3 diffs)
-
src/boot/boot.S (modified) (15 diffs)
-
src/boot/memmap.c (modified) (1 diff)
-
src/boot/vesa_prot.inc (modified) (7 diffs)
-
src/boot/vesa_real.inc (modified) (19 diffs)
-
src/boot/vesa_ret.inc (modified) (1 diff)
-
src/cpu/cpu.c (modified) (8 diffs)
-
src/ddi/ddi.c (modified) (6 diffs)
-
src/debug/stacktrace.c (added)
-
src/debug/stacktrace_asm.S (added)
-
src/drivers/i8254.c (modified) (6 diffs)
-
src/drivers/i8259.c (modified) (6 diffs)
-
src/drivers/vesa.c (modified) (2 diffs)
-
src/ia32.c (modified) (8 diffs)
-
src/interrupt.c (modified) (9 diffs)
-
src/mm/as.c (modified) (1 diff)
-
src/mm/frame.c (modified) (9 diffs)
-
src/mm/page.c (modified) (6 diffs)
-
src/mm/tlb.c (modified) (2 diffs)
-
src/pm.c (modified) (5 diffs)
-
src/proc/scheduler.c (modified) (2 diffs)
-
src/proc/task.c (modified) (1 diff)
-
src/smp/ap.S (modified) (1 diff)
-
src/smp/apic.c (modified) (37 diffs)
-
src/smp/ipi.c (modified) (1 diff)
-
src/smp/mps.c (modified) (8 diffs)
-
src/smp/smp.c (modified) (8 diffs)
-
src/syscall.c (modified) (3 diffs)
-
src/userspace.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/Makefile.inc
rb50b5af2 r04803bf 27 27 # 28 28 29 ## Toolchain configuration30 #31 32 29 BFD_NAME = elf32-i386 33 30 BFD_ARCH = i386 34 31 BFD = binary 35 TARGET = i686-pc-linux-gnu 36 TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686 32 CLANG_ARCH = i386 37 33 38 34 BITS = 32 … … 43 39 ICC_CFLAGS += $(CMN1) 44 40 SUNCC_CFLAGS += $(CMN1) 41 CLANG_CFLAGS += $(CMN1) 45 42 46 43 ## Accepted CPUs … … 51 48 SUNCC_CFLAGS += -xarch=ssea 52 49 endif 50 53 51 ifeq ($(PROCESSOR),athlon_mp) 54 52 CMN2 = -march=athlon-mp 55 53 SUNCC_CFLAGS += xarch=ssea 56 54 endif 55 57 56 ifeq ($(PROCESSOR),pentium3) 58 57 CMN2 = -march=pentium3 59 58 SUNCC_CFLAGS += -xarch=sse 60 59 endif 60 61 61 ifeq ($(PROCESSOR),pentium4) 62 62 CMN2 = -march=pentium4 63 63 SUNCC_CFLAGS += -xarch=sse2 64 64 endif 65 65 66 ifeq ($(PROCESSOR),core) 66 67 CMN2 = -march=prescott … … 71 72 GCC_CFLAGS += $(CMN2) 72 73 ICC_CFLAGS += $(CMN2) 74 CLANG_CFLAGS += $(CMN2) 73 75 74 76 ARCH_SOURCES = \ 75 77 arch/$(KARCH)/src/context.S \ 76 arch/$(KARCH)/src/debug/panic.s \ 78 arch/$(KARCH)/src/debug/stacktrace.c \ 79 arch/$(KARCH)/src/debug/stacktrace_asm.S \ 77 80 arch/$(KARCH)/src/delay.s \ 78 81 arch/$(KARCH)/src/asm.S \ -
kernel/arch/ia32/_link.ld.in
rb50b5af2 r04803bf 42 42 hardcoded_unmapped_kdata_size = .; 43 43 LONG(unmapped_kdata_end - unmapped_kdata_start); 44 . = ALIGN(8); 44 45 symbol_table = .; 45 46 *(symtab.*); /* Symbol table, must be LAST symbol! */ … … 48 49 } 49 50 51 #ifdef CONFIG_LINE_DEBUG 52 .comment 0 : { *(.comment); } 53 .debug_abbrev 0 : { *(.debug_abbrev); } 54 .debug_aranges 0 : { *(.debug_aranges); } 55 .debug_info 0 : { *(.debug_info); } 56 .debug_line 0 : { *(.debug_line); } 57 .debug_loc 0 : { *(.debug_loc); } 58 .debug_pubnames 0 : { *(.debug_pubnames); } 59 .debug_pubtypes 0 : { *(.debug_pubtypes); } 60 .debug_ranges 0 : { *(.debug_ranges); } 61 .debug_str 0 : { *(.debug_str); } 62 #endif 63 50 64 /DISCARD/ : { 51 *(.note.GNU-stack); 52 *(.comment); 65 *(*); 53 66 } 54 67 -
kernel/arch/ia32/include/asm.h
rb50b5af2 r04803bf 38 38 39 39 #include <arch/pm.h> 40 #include <arch/ types.h>40 #include <arch/cpu.h> 41 41 #include <typedefs.h> 42 42 #include <config.h> 43 44 extern uint32_t interrupt_handler_size; 45 46 extern void paging_on(void); 47 48 extern void interrupt_handlers(void); 49 50 extern void enable_l_apic_in_msr(void); 51 52 53 extern void asm_delay_loop(uint32_t t); 54 extern void asm_fake_loop(uint32_t t); 55 43 #include <trace.h> 56 44 57 45 /** Halt CPU … … 60 48 * 61 49 */ 62 static inline void cpu_halt(void) 63 { 64 asm volatile ( 65 "0:\n" 66 " hlt\n" 67 " jmp 0b\n" 68 ); 69 } 70 71 static inline void cpu_sleep(void) 72 { 73 asm volatile ("hlt\n"); 74 } 75 76 #define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \ 50 NO_TRACE static inline __attribute__((noreturn)) void cpu_halt(void) 51 { 52 while (true) { 53 asm volatile ( 54 "hlt\n" 55 ); 56 } 57 } 58 59 NO_TRACE static inline void cpu_sleep(void) 60 { 61 asm volatile ( 62 "hlt\n" 63 ); 64 } 65 66 #define GEN_READ_REG(reg) NO_TRACE static inline sysarg_t read_ ##reg (void) \ 77 67 { \ 78 unative_t res; \68 sysarg_t res; \ 79 69 asm volatile ( \ 80 70 "movl %%" #reg ", %[res]" \ … … 84 74 } 85 75 86 #define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \76 #define GEN_WRITE_REG(reg) NO_TRACE static inline void write_ ##reg (sysarg_t regn) \ 87 77 { \ 88 78 asm volatile ( \ … … 119 109 * 120 110 */ 121 static inline void pio_write_8(ioport8_t *port, uint8_t val)111 NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t val) 122 112 { 123 113 asm volatile ( 124 114 "outb %b[val], %w[port]\n" 125 :: [val] "a" (val), [port] "d" (port) 115 :: [val] "a" (val), 116 [port] "d" (port) 126 117 ); 127 118 } … … 135 126 * 136 127 */ 137 static inline void pio_write_16(ioport16_t *port, uint16_t val)128 NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t val) 138 129 { 139 130 asm volatile ( 140 131 "outw %w[val], %w[port]\n" 141 :: [val] "a" (val), [port] "d" (port) 132 :: [val] "a" (val), 133 [port] "d" (port) 142 134 ); 143 135 } … … 151 143 * 152 144 */ 153 static inline void pio_write_32(ioport32_t *port, uint32_t val)145 NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t val) 154 146 { 155 147 asm volatile ( 156 148 "outl %[val], %w[port]\n" 157 :: [val] "a" (val), [port] "d" (port) 149 :: [val] "a" (val), 150 [port] "d" (port) 158 151 ); 159 152 } … … 167 160 * 168 161 */ 169 static inline uint8_t pio_read_8(ioport8_t *port)162 NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port) 170 163 { 171 164 uint8_t val; … … 188 181 * 189 182 */ 190 static inline uint16_t pio_read_16(ioport16_t *port)183 NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port) 191 184 { 192 185 uint16_t val; … … 209 202 * 210 203 */ 211 static inline uint32_t pio_read_32(ioport32_t *port)204 NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port) 212 205 { 213 206 uint32_t val; … … 230 223 * 231 224 */ 232 static inline ipl_t interrupts_enable(void)225 NO_TRACE static inline ipl_t interrupts_enable(void) 233 226 { 234 227 ipl_t v; … … 252 245 * 253 246 */ 254 static inline ipl_t interrupts_disable(void)247 NO_TRACE static inline ipl_t interrupts_disable(void) 255 248 { 256 249 ipl_t v; … … 273 266 * 274 267 */ 275 static inline void interrupts_restore(ipl_t ipl)268 NO_TRACE static inline void interrupts_restore(ipl_t ipl) 276 269 { 277 270 asm volatile ( … … 287 280 * 288 281 */ 289 static inline ipl_t interrupts_read(void)282 NO_TRACE static inline ipl_t interrupts_read(void) 290 283 { 291 284 ipl_t v; … … 300 293 } 301 294 295 /** Check interrupts state. 296 * 297 * @return True if interrupts are disabled. 298 * 299 */ 300 NO_TRACE static inline bool interrupts_disabled(void) 301 { 302 ipl_t v; 303 304 asm volatile ( 305 "pushf\n" 306 "popl %[v]\n" 307 : [v] "=r" (v) 308 ); 309 310 return ((v & EFLAGS_IF) == 0); 311 } 312 302 313 /** Write to MSR */ 303 static inline void write_msr(uint32_t msr, uint64_t value)314 NO_TRACE static inline void write_msr(uint32_t msr, uint64_t value) 304 315 { 305 316 asm volatile ( 306 317 "wrmsr" 307 :: "c" (msr), "a" ((uint32_t) (value)), 318 :: "c" (msr), 319 "a" ((uint32_t) (value)), 308 320 "d" ((uint32_t) (value >> 32)) 309 321 ); 310 322 } 311 323 312 static inline uint64_t read_msr(uint32_t msr)324 NO_TRACE static inline uint64_t read_msr(uint32_t msr) 313 325 { 314 326 uint32_t ax, dx; … … 316 328 asm volatile ( 317 329 "rdmsr" 318 : "=a" (ax), "=d" (dx) 330 : "=a" (ax), 331 "=d" (dx) 319 332 : "c" (msr) 320 333 ); … … 331 344 * 332 345 */ 333 static inline uintptr_t get_stack_base(void)346 NO_TRACE static inline uintptr_t get_stack_base(void) 334 347 { 335 348 uintptr_t v; … … 344 357 } 345 358 346 /** Return current IP address */347 static inline uintptr_t * get_ip()348 {349 uintptr_t *ip;350 351 asm volatile (352 "mov %%eip, %[ip]"353 : [ip] "=r" (ip)354 );355 356 return ip;357 }358 359 359 /** Invalidate TLB Entry. 360 360 * … … 362 362 * 363 363 */ 364 static inline void invlpg(uintptr_t addr)364 NO_TRACE static inline void invlpg(uintptr_t addr) 365 365 { 366 366 asm volatile ( 367 367 "invlpg %[addr]\n" 368 :: [addr] "m" (*( unative_t *) addr)368 :: [addr] "m" (*(sysarg_t *) addr) 369 369 ); 370 370 } … … 375 375 * 376 376 */ 377 static inline void gdtr_load(ptr_16_32_t *gdtr_reg)377 NO_TRACE static inline void gdtr_load(ptr_16_32_t *gdtr_reg) 378 378 { 379 379 asm volatile ( … … 388 388 * 389 389 */ 390 static inline void gdtr_store(ptr_16_32_t *gdtr_reg)390 NO_TRACE static inline void gdtr_store(ptr_16_32_t *gdtr_reg) 391 391 { 392 392 asm volatile ( 393 393 "sgdtl %[gdtr_reg]\n" 394 : : [gdtr_reg] "m" (*gdtr_reg)394 : [gdtr_reg] "=m" (*gdtr_reg) 395 395 ); 396 396 } … … 401 401 * 402 402 */ 403 static inline void idtr_load(ptr_16_32_t *idtr_reg)403 NO_TRACE static inline void idtr_load(ptr_16_32_t *idtr_reg) 404 404 { 405 405 asm volatile ( … … 414 414 * 415 415 */ 416 static inline void tr_load(uint16_t sel)416 NO_TRACE static inline void tr_load(uint16_t sel) 417 417 { 418 418 asm volatile ( … … 422 422 } 423 423 424 extern void paging_on(void); 425 extern void enable_l_apic_in_msr(void); 426 427 extern void asm_delay_loop(uint32_t); 428 extern void asm_fake_loop(uint32_t); 429 430 extern uintptr_t int_syscall; 431 432 extern uintptr_t int_0; 433 extern uintptr_t int_1; 434 extern uintptr_t int_2; 435 extern uintptr_t int_3; 436 extern uintptr_t int_4; 437 extern uintptr_t int_5; 438 extern uintptr_t int_6; 439 extern uintptr_t int_7; 440 extern uintptr_t int_8; 441 extern uintptr_t int_9; 442 extern uintptr_t int_10; 443 extern uintptr_t int_11; 444 extern uintptr_t int_12; 445 extern uintptr_t int_13; 446 extern uintptr_t int_14; 447 extern uintptr_t int_15; 448 extern uintptr_t int_16; 449 extern uintptr_t int_17; 450 extern uintptr_t int_18; 451 extern uintptr_t int_19; 452 extern uintptr_t int_20; 453 extern uintptr_t int_21; 454 extern uintptr_t int_22; 455 extern uintptr_t int_23; 456 extern uintptr_t int_24; 457 extern uintptr_t int_25; 458 extern uintptr_t int_26; 459 extern uintptr_t int_27; 460 extern uintptr_t int_28; 461 extern uintptr_t int_29; 462 extern uintptr_t int_30; 463 extern uintptr_t int_31; 464 extern uintptr_t int_32; 465 extern uintptr_t int_33; 466 extern uintptr_t int_34; 467 extern uintptr_t int_35; 468 extern uintptr_t int_36; 469 extern uintptr_t int_37; 470 extern uintptr_t int_38; 471 extern uintptr_t int_39; 472 extern uintptr_t int_40; 473 extern uintptr_t int_41; 474 extern uintptr_t int_42; 475 extern uintptr_t int_43; 476 extern uintptr_t int_44; 477 extern uintptr_t int_45; 478 extern uintptr_t int_46; 479 extern uintptr_t int_47; 480 extern uintptr_t int_48; 481 extern uintptr_t int_49; 482 extern uintptr_t int_50; 483 extern uintptr_t int_51; 484 extern uintptr_t int_52; 485 extern uintptr_t int_53; 486 extern uintptr_t int_54; 487 extern uintptr_t int_55; 488 extern uintptr_t int_56; 489 extern uintptr_t int_57; 490 extern uintptr_t int_58; 491 extern uintptr_t int_59; 492 extern uintptr_t int_60; 493 extern uintptr_t int_61; 494 extern uintptr_t int_62; 495 extern uintptr_t int_63; 496 424 497 #endif 425 498 -
kernel/arch/ia32/include/atomic.h
rb50b5af2 r04803bf 36 36 #define KERN_ia32_ATOMIC_H_ 37 37 38 #include < arch/types.h>38 #include <typedefs.h> 39 39 #include <arch/barrier.h> 40 40 #include <preemption.h> 41 #include <trace.h> 41 42 42 static inline void atomic_inc(atomic_t *val) { 43 NO_TRACE static inline void atomic_inc(atomic_t *val) 44 { 43 45 #ifdef CONFIG_SMP 44 46 asm volatile ( … … 54 56 } 55 57 56 static inline void atomic_dec(atomic_t *val) { 58 NO_TRACE static inline void atomic_dec(atomic_t *val) 59 { 57 60 #ifdef CONFIG_SMP 58 61 asm volatile ( … … 68 71 } 69 72 70 static inline long atomic_postinc(atomic_t *val) 73 NO_TRACE static inline atomic_count_t atomic_postinc(atomic_t *val) 71 74 { 72 longr = 1;75 atomic_count_t r = 1; 73 76 74 77 asm volatile ( 75 78 "lock xaddl %[r], %[count]\n" 76 : [count] "+m" (val->count), [r] "+r" (r) 79 : [count] "+m" (val->count), 80 [r] "+r" (r) 77 81 ); 78 82 … … 80 84 } 81 85 82 static inline long atomic_postdec(atomic_t *val) 86 NO_TRACE static inline atomic_count_t atomic_postdec(atomic_t *val) 83 87 { 84 longr = -1;88 atomic_count_t r = -1; 85 89 86 90 asm volatile ( 87 91 "lock xaddl %[r], %[count]\n" 88 : [count] "+m" (val->count), [r] "+r"(r) 92 : [count] "+m" (val->count), 93 [r] "+r" (r) 89 94 ); 90 95 … … 95 100 #define atomic_predec(val) (atomic_postdec(val) - 1) 96 101 97 static inline uint32_t test_and_set(atomic_t *val) { 98 uint32_t v; 102 NO_TRACE static inline atomic_count_t test_and_set(atomic_t *val) 103 { 104 atomic_count_t v = 1; 99 105 100 106 asm volatile ( 101 "movl $1, %[v]\n"102 107 "xchgl %[v], %[count]\n" 103 : [v] "=r" (v), [count] "+m" (val->count) 108 : [v] "+r" (v), 109 [count] "+m" (val->count) 104 110 ); 105 111 … … 108 114 109 115 /** ia32 specific fast spinlock */ 110 static inline void atomic_lock_arch(atomic_t *val)116 NO_TRACE static inline void atomic_lock_arch(atomic_t *val) 111 117 { 112 uint32_t tmp;118 atomic_count_t tmp; 113 119 114 120 preemption_disable(); … … 124 130 "testl %[tmp], %[tmp]\n" 125 131 "jnz 0b\n" 126 : [count] "+m" (val->count), [tmp] "=&r" (tmp) 132 : [count] "+m" (val->count), 133 [tmp] "=&r" (tmp) 127 134 ); 135 128 136 /* 129 137 * Prevent critical section code from bleeding out this way up. -
kernel/arch/ia32/include/barrier.h
rb50b5af2 r04803bf 36 36 #define KERN_ia32_BARRIER_H_ 37 37 38 #include <trace.h> 39 38 40 /* 39 41 * NOTE: … … 50 52 #define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") 51 53 52 static inline void cpuid_serialization(void)54 NO_TRACE static inline void cpuid_serialization(void) 53 55 { 54 56 #ifndef __IN_SHARED_LIBC__ -
kernel/arch/ia32/include/bios/bios.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia32_BIOS_H_ 37 37 38 #include <arch/types.h> 39 40 #define BIOS_EBDA_PTR 0x40e 38 #include <typedefs.h> 41 39 42 40 extern uintptr_t ebda; -
kernel/arch/ia32/include/boot/boot.h
rb50b5af2 r04803bf 38 38 #define BOOT_OFFSET 0x108000 39 39 #define AP_BOOT_OFFSET 0x8000 40 #define BOOT_STACK_SIZE 0x 40040 #define BOOT_STACK_SIZE 0x0400 41 41 42 42 #define MULTIBOOT_HEADER_MAGIC 0x1BADB002 -
kernel/arch/ia32/include/boot/memmap.h
rb50b5af2 r04803bf 61 61 #ifndef __ASM__ 62 62 63 #include < arch/types.h>63 #include <typedefs.h> 64 64 65 65 typedef struct { … … 70 70 71 71 extern e820memmap_t e820table[MEMMAP_E820_MAX_RECORDS]; 72 extern uint8_t e820counter; 72 extern uint8_t e820counter; 73 73 74 74 #endif -
kernel/arch/ia32/include/context.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 37 37 38 38 #ifdef KERNEL 39 #include <arch/types.h>40 39 41 #define STACK_ITEM_SIZE 4 40 #include <typedefs.h> 41 42 #define STACK_ITEM_SIZE 4 42 43 43 44 /* … … 47 48 * One item is put onto stack to support get_stack_base(). 48 49 */ 49 #define SP_DELTA (8 + STACK_ITEM_SIZE) 50 #define SP_DELTA (8 + STACK_ITEM_SIZE) 51 52 #define context_set(c, _pc, stack, size) \ 53 do { \ 54 (c)->pc = (uintptr_t) (_pc); \ 55 (c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA; \ 56 (c)->ebp = 0; \ 57 } while (0) 50 58 51 59 #endif /* KERNEL */ -
kernel/arch/ia32/include/context_offset.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia32_CONTEXT_OFFSET_H_ 37 37 38 #define OFFSET_SP 0x039 #define OFFSET_PC 0x440 #define OFFSET_EBX 0x841 #define OFFSET_ESI 0xC42 #define OFFSET_EDI 0x1043 #define OFFSET_EBP 0x1438 #define OFFSET_SP 0x00 39 #define OFFSET_PC 0x04 40 #define OFFSET_EBX 0x08 41 #define OFFSET_ESI 0x0C 42 #define OFFSET_EDI 0x10 43 #define OFFSET_EBP 0x14 44 44 45 #ifdef KERNEL 46 # define OFFSET_IPL0x1845 #ifdef KERNEL 46 #define OFFSET_IPL 0x18 47 47 #else 48 # define OFFSET_TLS0x1848 #define OFFSET_TLS 0x18 49 49 #endif 50 50 51 #ifdef __ASM__ 51 52 52 #ifdef __ASM__ 53 54 # ctx: address of the structure with saved context 53 # ctx: address of the structure with saved context 55 54 # pc: return address 56 55 57 56 .macro CONTEXT_SAVE_ARCH_CORE ctx:req pc:req 58 movl %esp,OFFSET_SP(\ctx) # %esp -> ctx->sp 57 movl %esp,OFFSET_SP(\ctx) # %esp -> ctx->sp 59 58 movl \pc,OFFSET_PC(\ctx) # %eip -> ctx->pc 60 movl %ebx,OFFSET_EBX(\ctx) # %ebx -> ctx->ebx 61 movl %esi,OFFSET_ESI(\ctx) # %esi -> ctx->esi 62 movl %edi,OFFSET_EDI(\ctx) # %edi -> ctx->edi 63 movl %ebp,OFFSET_EBP(\ctx) # %ebp -> ctx->ebp 59 movl %ebx,OFFSET_EBX(\ctx) # %ebx -> ctx->ebx 60 movl %esi,OFFSET_ESI(\ctx) # %esi -> ctx->esi 61 movl %edi,OFFSET_EDI(\ctx) # %edi -> ctx->edi 62 movl %ebp,OFFSET_EBP(\ctx) # %ebp -> ctx->ebp 64 63 .endm 65 64 66 # ctx: address of the structure with saved context 65 # ctx: address of the structure with saved context 67 66 68 67 .macro CONTEXT_RESTORE_ARCH_CORE ctx:req pc:req … … 75 74 .endm 76 75 77 #endif /* __ASM__ */ 76 #endif /* __ASM__ */ 78 77 79 78 #endif … … 81 80 /** @} 82 81 */ 83 -
kernel/arch/ia32/include/cpu.h
rb50b5af2 r04803bf 37 37 38 38 #define EFLAGS_IF (1 << 9) 39 #define EFLAGS_DF (1 << 10) 40 #define EFLAGS_NT (1 << 14) 39 41 #define EFLAGS_RF (1 << 16) 40 42 … … 42 44 43 45 /* Support for SYSENTER and SYSEXIT */ 44 #define IA32_MSR_SYSENTER_CS 0x17445 #define IA32_MSR_SYSENTER_ESP 0x17546 #define IA32_MSR_SYSENTER_EIP 0x17646 #define IA32_MSR_SYSENTER_CS 0x174U 47 #define IA32_MSR_SYSENTER_ESP 0x175U 48 #define IA32_MSR_SYSENTER_EIP 0x176U 47 49 48 50 #ifndef __ASM__ … … 50 52 #include <arch/pm.h> 51 53 #include <arch/asm.h> 54 #include <arch/cpuid.h> 52 55 53 56 typedef struct { … … 56 59 unsigned int model; 57 60 unsigned int stepping; 61 cpuid_feature_info fi; 62 58 63 tss_t *tss; 59 64 -
kernel/arch/ia32/include/cpuid.h
rb50b5af2 r04803bf 43 43 #ifndef __ASM__ 44 44 45 #include < arch/types.h>45 #include <typedefs.h> 46 46 47 47 typedef struct { … … 63 63 64 64 struct __cpuid_feature_info { 65 unsigned : 23; 65 unsigned : 11; 66 unsigned sep : 1; 67 unsigned : 11; 66 68 unsigned mmx : 1; 67 69 unsigned fxsr : 1; -
kernel/arch/ia32/include/cycle.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia32_CYCLE_H_ 37 37 38 static inline uint64_t get_cycle(void) 38 #include <trace.h> 39 40 NO_TRACE static inline uint64_t get_cycle(void) 39 41 { 40 42 uint64_t v; -
kernel/arch/ia32/include/ddi/ddi.h
rb50b5af2 r04803bf 32 32 /** 33 33 * @file 34 * @brief ia32 specific DDI declarations and macros.34 * @brief ia32 specific DDI declarations and macros. 35 35 */ 36 36 -
kernel/arch/ia32/include/drivers/i8254.h
rb50b5af2 r04803bf 36 36 #define KERN_ia32_I8254_H_ 37 37 38 #include <arch/types.h>39 40 38 extern void i8254_init(void); 41 39 extern void i8254_calibrate_delay_loop(void); -
kernel/arch/ia32/include/drivers/i8259.h
rb50b5af2 r04803bf 36 36 #define KERN_ia32_I8259_H_ 37 37 38 #include < arch/types.h>38 #include <typedefs.h> 39 39 #include <arch/interrupt.h> 40 40 41 #define PIC_PIC0PORT1 ((ioport8_t *) 0x20 )42 #define PIC_PIC0PORT2 ((ioport8_t *) 0x21 )43 #define PIC_PIC1PORT1 ((ioport8_t *) 0xa0 )44 #define PIC_PIC1PORT2 ((ioport8_t *) 0xa1 )41 #define PIC_PIC0PORT1 ((ioport8_t *) 0x20U) 42 #define PIC_PIC0PORT2 ((ioport8_t *) 0x21U) 43 #define PIC_PIC1PORT1 ((ioport8_t *) 0xa0U) 44 #define PIC_PIC1PORT2 ((ioport8_t *) 0xa1U) 45 45 46 46 #define PIC_NEEDICW4 (1 << 0) … … 48 48 49 49 extern void i8259_init(void); 50 extern void pic_enable_irqs(uint16_t irqmask);51 extern void pic_disable_irqs(uint16_t irqmask);50 extern void pic_enable_irqs(uint16_t); 51 extern void pic_disable_irqs(uint16_t); 52 52 extern void pic_eoi(void); 53 53 -
kernel/arch/ia32/include/drivers/vesa.h
rb50b5af2 r04803bf 36 36 #define KERN_ia32_VESA_H_ 37 37 38 #include < arch/types.h>38 #include <typedefs.h> 39 39 40 40 extern bool vesa_init(void); -
kernel/arch/ia32/include/faddr.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia32_FADDR_H_ 37 37 38 #include < arch/types.h>38 #include <typedefs.h> 39 39 40 #define FADDR(fptr) ((uintptr_t) (fptr))40 #define FADDR(fptr) ((uintptr_t) (fptr)) 41 41 42 42 #endif -
kernel/arch/ia32/include/fpu_context.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia32_FPU_CONTEXT_H_ 37 37 38 #include < arch/types.h>38 #include <typedefs.h> 39 39 40 #define FPU_CONTEXT_ALIGN 16 41 42 void fpu_fxsr(void); 43 void fpu_fsr(void); 44 40 #define FPU_CONTEXT_ALIGN 16 45 41 46 42 typedef struct { 47 uint8_t fpu[512]; /* FXSAVE & FXRSTOR storage area */43 uint8_t fpu[512]; /* FXSAVE & FXRSTOR storage area */ 48 44 } fpu_context_t; 45 46 extern void fpu_fxsr(void); 47 extern void fpu_fsr(void); 49 48 50 49 #endif -
kernel/arch/ia32/include/interrupt.h
rb50b5af2 r04803bf 36 36 #define KERN_ia32_INTERRUPT_H_ 37 37 38 #include <arch/types.h> 38 #include <typedefs.h> 39 #include <arch/istate.h> 39 40 #include <arch/pm.h> 40 41 41 #define IVT_ITEMS IDT_ITEMS42 #define IVT_FIRST 042 #define IVT_ITEMS IDT_ITEMS 43 #define IVT_FIRST 0 43 44 44 #define EXC_COUNT 3245 #define IRQ_COUNT 1645 #define EXC_COUNT 32 46 #define IRQ_COUNT 16 46 47 47 #define IVT_EXCBASE 048 #define IVT_IRQBASE (IVT_EXCBASE + EXC_COUNT)49 #define IVT_FREEBASE (IVT_IRQBASE + IRQ_COUNT)48 #define IVT_EXCBASE 0 49 #define IVT_IRQBASE (IVT_EXCBASE + EXC_COUNT) 50 #define IVT_FREEBASE (IVT_IRQBASE + IRQ_COUNT) 50 51 51 #define IRQ_CLK 0 52 #define IRQ_KBD 1 53 #define IRQ_PIC1 2 54 #define IRQ_PIC_SPUR 7 55 #define IRQ_MOUSE 12 52 #define IRQ_CLK 0 53 #define IRQ_KBD 1 54 #define IRQ_PIC1 2 55 #define IRQ_PIC_SPUR 7 56 #define IRQ_MOUSE 12 57 #define IRQ_NE2000 5 56 58 57 /* this one must have four least significant bits set to ones */58 #define VECTOR_APIC_SPUR (IVT_ITEMS - 1)59 /* This one must have four least significant bits set to ones */ 60 #define VECTOR_APIC_SPUR (IVT_ITEMS - 1) 59 61 60 62 #if (((VECTOR_APIC_SPUR + 1) % 16) || VECTOR_APIC_SPUR >= IVT_ITEMS) … … 62 64 #endif 63 65 64 #define VECTOR_DEBUG 165 #define VECTOR_CLK (IVT_IRQBASE + IRQ_CLK)66 #define VECTOR_PIC_SPUR (IVT_IRQBASE + IRQ_PIC_SPUR)67 #define VECTOR_SYSCALL IVT_FREEBASE68 #define VECTOR_TLB_SHOOTDOWN_IPI (IVT_FREEBASE + 1)69 #define VECTOR_DEBUG_IPI (IVT_FREEBASE + 2)66 #define VECTOR_DEBUG 1 67 #define VECTOR_CLK (IVT_IRQBASE + IRQ_CLK) 68 #define VECTOR_PIC_SPUR (IVT_IRQBASE + IRQ_PIC_SPUR) 69 #define VECTOR_SYSCALL IVT_FREEBASE 70 #define VECTOR_TLB_SHOOTDOWN_IPI (IVT_FREEBASE + 1) 71 #define VECTOR_DEBUG_IPI (IVT_FREEBASE + 2) 70 72 71 typedef struct { 72 uint32_t eax;73 uint32_t ecx;74 uint32_t edx;73 extern void (* disable_irqs_function)(uint16_t); 74 extern void (* enable_irqs_function)(uint16_t); 75 extern void (* eoi_function)(void); 76 extern const char *irqs_info; 75 77 76 uint32_t gs;77 uint32_t fs;78 uint32_t es;79 uint32_t ds;80 81 uint32_t error_word;82 uint32_t eip;83 uint32_t cs;84 uint32_t eflags;85 uint32_t stack[];86 } istate_t;87 88 /** Return true if exception happened while in userspace */89 static inline int istate_from_uspace(istate_t *istate)90 {91 return !(istate->eip & 0x80000000);92 }93 94 static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)95 {96 istate->eip = retaddr;97 }98 99 static inline unative_t istate_get_pc(istate_t *istate)100 {101 return istate->eip;102 }103 104 extern void (* disable_irqs_function)(uint16_t irqmask);105 extern void (* enable_irqs_function)(uint16_t irqmask);106 extern void (* eoi_function)(void);107 108 extern void decode_istate(istate_t *istate);109 78 extern void interrupt_init(void); 110 extern void trap_virtual_enable_irqs(uint16_t irqmask);111 extern void trap_virtual_disable_irqs(uint16_t irqmask);79 extern void trap_virtual_enable_irqs(uint16_t); 80 extern void trap_virtual_disable_irqs(uint16_t); 112 81 113 82 #endif -
kernel/arch/ia32/include/istate.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup sync29 /** @addtogroup ia32interrupt 30 30 * @{ 31 31 */ … … 33 33 */ 34 34 35 #ifndef KERN_ RWLOCK_H_36 #define KERN_ RWLOCK_H_35 #ifndef KERN_ia32_ISTATE_H_ 36 #define KERN_ia32_ISTATE_H_ 37 37 38 #include <arch/types.h> 39 #include <synch/mutex.h> 40 #include <synch/synch.h> 41 #include <synch/spinlock.h> 38 #ifdef KERNEL 42 39 43 typedef enum { 44 RWLOCK_NONE, 45 RWLOCK_READER, 46 RWLOCK_WRITER 47 } rwlock_type_t; 40 #include <typedefs.h> 41 #include <trace.h> 48 42 49 typedef struct { 50 SPINLOCK_DECLARE(lock); 51 /** 52 * Mutex for writers, readers can bypass it if readers_in is positive. 43 #else /* KERNEL */ 44 45 #include <sys/types.h> 46 47 #define NO_TRACE 48 49 #endif /* KERNEL */ 50 51 typedef struct istate { 52 /* 53 * The strange order of the GPRs is given by the requirement to use the 54 * istate structure for both regular interrupts and exceptions as well 55 * as for syscall handlers which use this order as an optimization. 53 56 */ 54 mutex_t exclusive; 55 /** Number of readers in critical section. */ 56 size_t readers_in; 57 } rwlock_t; 57 uint32_t edx; 58 uint32_t ecx; 59 uint32_t ebx; 60 uint32_t esi; 61 uint32_t edi; 62 uint32_t ebp; 63 uint32_t eax; 64 65 uint32_t ebp_frame; /* imitation of frame pointer linkage */ 66 uint32_t eip_frame; /* imitation of return address linkage */ 67 68 uint32_t gs; 69 uint32_t fs; 70 uint32_t es; 71 uint32_t ds; 72 73 uint32_t error_word; /* real or fake error word */ 74 uint32_t eip; 75 uint32_t cs; 76 uint32_t eflags; 77 uint32_t esp; /* only if istate_t is from uspace */ 78 uint32_t ss; /* only if istate_t is from uspace */ 79 } istate_t; 58 80 59 #define rwlock_write_lock(rwl) \ 60 _rwlock_write_lock_timeout((rwl), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE) 61 #define rwlock_read_lock(rwl) \ 62 _rwlock_read_lock_timeout((rwl), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE) 63 #define rwlock_write_trylock(rwl) \ 64 _rwlock_write_lock_timeout((rwl), SYNCH_NO_TIMEOUT, \ 65 SYNCH_FLAGS_NON_BLOCKING) 66 #define rwlock_read_trylock(rwl) \ 67 _rwlock_read_lock_timeout((rwl), SYNCH_NO_TIMEOUT, \ 68 SYNCH_FLAGS_NON_BLOCKING) 69 #define rwlock_write_lock_timeout(rwl, usec) \ 70 _rwlock_write_lock_timeout((rwl), (usec), SYNCH_FLAGS_NONE) 71 #define rwlock_read_lock_timeout(rwl, usec) \ 72 _rwlock_read_lock_timeout((rwl), (usec), SYNCH_FLAGS_NONE) 81 /** Return true if exception happened while in userspace */ 82 NO_TRACE static inline int istate_from_uspace(istate_t *istate) 83 { 84 return !(istate->eip & UINT32_C(0x80000000)); 85 } 73 86 74 extern void rwlock_initialize(rwlock_t *rwl); 75 extern void rwlock_read_unlock(rwlock_t *rwl); 76 extern void rwlock_write_unlock(rwlock_t *rwl); 77 extern int _rwlock_read_lock_timeout(rwlock_t *rwl, uint32_t usec, int flags); 78 extern int _rwlock_write_lock_timeout(rwlock_t *rwl, uint32_t usec, int flags); 87 NO_TRACE static inline void istate_set_retaddr(istate_t *istate, 88 uintptr_t retaddr) 89 { 90 istate->eip = retaddr; 91 } 92 93 NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate) 94 { 95 return istate->eip; 96 } 97 98 NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate) 99 { 100 return istate->ebp; 101 } 79 102 80 103 #endif -
kernel/arch/ia32/include/memstr.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 38 38 #define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) 39 39 40 extern void memsetw(void *dst, size_t cnt, uint16_t x); 41 extern void memsetb(void *dst, size_t cnt, uint8_t x); 42 43 extern int memcmp(const void *a, const void *b, size_t cnt); 40 extern void memsetw(void *, size_t, uint16_t); 41 extern void memsetb(void *, size_t, uint8_t); 44 42 45 43 #endif -
kernel/arch/ia32/include/mm/as.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32mm 29 /** @addtogroup ia32mm 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia32_AS_H_ 37 37 38 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 038 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0 39 39 40 #define KERNEL_ADDRESS_SPACE_START_ARCH ((unsigned long)0x80000000)41 #define KERNEL_ADDRESS_SPACE_END_ARCH ((unsigned long)0xffffffff)42 #define USER_ADDRESS_SPACE_START_ARCH ((unsigned long)0x00000000)43 #define USER_ADDRESS_SPACE_END_ARCH ((unsigned long)0x7fffffff)40 #define KERNEL_ADDRESS_SPACE_START_ARCH UINT32_C(0x80000000) 41 #define KERNEL_ADDRESS_SPACE_END_ARCH UINT32_C(0xffffffff) 42 #define USER_ADDRESS_SPACE_START_ARCH UINT32_C(0x00000000) 43 #define USER_ADDRESS_SPACE_END_ARCH UINT32_C(0x7fffffff) 44 44 45 #define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH - (PAGE_SIZE - 1))45 #define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH - (PAGE_SIZE - 1)) 46 46 47 47 typedef struct { … … 50 50 #include <genarch/mm/as_pt.h> 51 51 52 #define as_constructor_arch(as, flags) (as != as)53 #define as_destructor_arch(as) (as != as)54 #define as_create_arch(as, flags) (as != as)52 #define as_constructor_arch(as, flags) (as != as) 53 #define as_destructor_arch(as) (as != as) 54 #define as_create_arch(as, flags) (as != as) 55 55 #define as_install_arch(as) 56 56 #define as_deinstall_arch(as) -
kernel/arch/ia32/include/mm/asid.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32mm 29 /** @addtogroup ia32mm 30 30 * @{ 31 31 */ … … 43 43 #define KERN_ia32_ASID_H_ 44 44 45 #include < arch/types.h>45 #include <typedefs.h> 46 46 47 47 typedef int32_t asid_t; 48 48 49 #define ASID_MAX_ARCH 349 #define ASID_MAX_ARCH 3 50 50 51 #define asid_get() (ASID_START + 1)51 #define asid_get() (ASID_START + 1) 52 52 #define asid_put(asid) 53 53 -
kernel/arch/ia32/include/mm/frame.h
rb50b5af2 r04803bf 42 42 #ifndef __ASM__ 43 43 44 #include < arch/types.h>44 #include <typedefs.h> 45 45 46 46 extern uintptr_t last_frame; -
kernel/arch/ia32/include/mm/page.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32mm 29 /** @addtogroup ia32mm 30 30 * @{ 31 31 */ … … 37 37 38 38 #include <arch/mm/frame.h> 39 40 #define PAGE_WIDTH FRAME_WIDTH 41 #define PAGE_SIZE FRAME_SIZE 39 #include <trace.h> 40 41 #define PAGE_WIDTH FRAME_WIDTH 42 #define PAGE_SIZE FRAME_SIZE 42 43 43 44 #ifdef KERNEL 44 45 45 46 #ifndef __ASM__ 46 # define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) 47 # define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) 48 #else 49 # define KA2PA(x) ((x) - 0x80000000) 50 # define PA2KA(x) ((x) + 0x80000000) 51 #endif 47 48 #define KA2PA(x) (((uintptr_t) (x)) - UINT32_C(0x80000000)) 49 #define PA2KA(x) (((uintptr_t) (x)) + UINT32_C(0x80000000)) 50 51 #else /* __ASM__ */ 52 53 #define KA2PA(x) ((x) - 0x80000000) 54 #define PA2KA(x) ((x) + 0x80000000) 55 56 #endif /* __ASM__ */ 52 57 53 58 /* … … 57 62 58 63 /* Number of entries in each level. */ 59 #define PTL0_ENTRIES_ARCH 102460 #define PTL1_ENTRIES_ARCH 061 #define PTL2_ENTRIES_ARCH 062 #define PTL3_ENTRIES_ARCH 102464 #define PTL0_ENTRIES_ARCH 1024 65 #define PTL1_ENTRIES_ARCH 0 66 #define PTL2_ENTRIES_ARCH 0 67 #define PTL3_ENTRIES_ARCH 1024 63 68 64 69 /* Page table sizes for each level. */ 65 #define PTL0_SIZE_ARCH ONE_FRAME66 #define PTL1_SIZE_ARCH 067 #define PTL2_SIZE_ARCH 068 #define PTL3_SIZE_ARCH ONE_FRAME70 #define PTL0_SIZE_ARCH ONE_FRAME 71 #define PTL1_SIZE_ARCH 0 72 #define PTL2_SIZE_ARCH 0 73 #define PTL3_SIZE_ARCH ONE_FRAME 69 74 70 75 /* Macros calculating indices for each level. */ 71 #define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff)72 #define PTL1_INDEX_ARCH(vaddr) 073 #define PTL2_INDEX_ARCH(vaddr) 074 #define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff)76 #define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ffU) 77 #define PTL1_INDEX_ARCH(vaddr) 0 78 #define PTL2_INDEX_ARCH(vaddr) 0 79 #define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ffU) 75 80 76 81 /* Get PTE address accessors for each level. */ … … 105 110 106 111 /* Set PTE flags accessors for each level. */ 107 #define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \112 #define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \ 108 113 set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x)) 109 114 #define SET_PTL2_FLAGS_ARCH(ptl1, i, x) … … 121 126 #define PTE_WRITABLE_ARCH(p) \ 122 127 ((p)->writeable != 0) 123 #define PTE_EXECUTABLE_ARCH(p) 1128 #define PTE_EXECUTABLE_ARCH(p) 1 124 129 125 130 #ifndef __ASM__ … … 127 132 #include <mm/mm.h> 128 133 #include <arch/interrupt.h> 129 #include <arch/types.h>130 134 #include <typedefs.h> 131 135 … … 144 148 145 149 /** When bit on this position is 1, a reserved bit was set in page directory. */ 146 #define PFERR_CODE_RSVD (1 << 3) 147 148 static inline int get_pt_flags(pte_t *pt, size_t i) 150 #define PFERR_CODE_RSVD (1 << 3) 151 152 /** Page Table Entry. */ 153 typedef struct { 154 unsigned present : 1; 155 unsigned writeable : 1; 156 unsigned uaccessible : 1; 157 unsigned page_write_through : 1; 158 unsigned page_cache_disable : 1; 159 unsigned accessed : 1; 160 unsigned dirty : 1; 161 unsigned pat : 1; 162 unsigned global : 1; 163 unsigned soft_valid : 1; /**< Valid content even if the present bit is not set. */ 164 unsigned avl : 2; 165 unsigned frame_address : 20; 166 } __attribute__ ((packed)) pte_t; 167 168 NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i) 149 169 { 150 170 pte_t *p = &pt[i]; … … 159 179 } 160 180 161 static inline void set_pt_flags(pte_t *pt, size_t i, int flags)181 NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags) 162 182 { 163 183 pte_t *p = &pt[i]; … … 177 197 178 198 extern void page_arch_init(void); 179 extern void page_fault( int n, istate_t *istate);199 extern void page_fault(unsigned int, istate_t *); 180 200 181 201 #endif /* __ASM__ */ -
kernel/arch/ia32/include/pm.h
rb50b5af2 r04803bf 58 58 #endif /* CONFIG_FB */ 59 59 60 #define gdtselector(des) ((des) << 3)60 #define GDT_SELECTOR(des) ((des) << 3) 61 61 62 62 #define PL_KERNEL 0 … … 67 67 #define AR_CODE (3 << 3) 68 68 #define AR_WRITABLE (1 << 1) 69 #define AR_INTERRUPT (0x0e) 70 #define AR_TSS (0x09) 69 #define AR_INTERRUPT (0xe) 70 #define AR_TRAP (0xf) 71 #define AR_TSS (0x9) 71 72 72 73 #define DPL_KERNEL (PL_KERNEL << 5) … … 74 75 75 76 #define TSS_BASIC_SIZE 104 76 #define TSS_IOMAP_SIZE ( 16 * 1024 + 1) /* 16K for bitmap + 1 terminating byte for convenience */77 #define TSS_IOMAP_SIZE (8 * 1024 + 1) /* 8K for bitmap + 1 terminating byte for convenience */ 77 78 78 79 #define IO_PORTS (64 * 1024) … … 80 81 #ifndef __ASM__ 81 82 82 #include < arch/types.h>83 #include <typedefs.h> 83 84 #include <arch/context.h> 84 85 … … 152 153 153 154 extern ptr_16_32_t gdtr; 154 extern ptr_16_32_t bootstrap_gdtr;155 155 extern ptr_16_32_t protected_ap_gdtr; 156 156 extern tss_t *tss_p; -
kernel/arch/ia32/include/proc/task.h
rb50b5af2 r04803bf 36 36 #define KERN_ia32_TASK_H_ 37 37 38 #include < arch/types.h>38 #include <typedefs.h> 39 39 #include <adt/bitmap.h> 40 40 -
kernel/arch/ia32/include/proc/thread.h
rb50b5af2 r04803bf 36 36 #define KERN_ia32_THREAD_H_ 37 37 38 #include < arch/types.h>38 #include <typedefs.h> 39 39 40 40 typedef struct { 41 unative_t tls;41 sysarg_t tls; 42 42 } thread_arch_t; 43 43 44 #define thr_constructor_arch(t )45 #define thr_destructor_arch(t )44 #define thr_constructor_arch(thr) 45 #define thr_destructor_arch(thr) 46 46 47 47 #endif -
kernel/arch/ia32/include/smp/ap.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ -
kernel/arch/ia32/include/smp/apic.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia32_APIC_H_ 37 37 38 #include < arch/types.h>38 #include <typedefs.h> 39 39 #include <cpu.h> 40 40 41 #define FIXED (0<<0)42 #define LOPRI (1<<0)43 44 #define APIC_ID_COUNT 1641 #define FIXED (0 << 0) 42 #define LOPRI (1 << 0) 43 44 #define APIC_ID_COUNT 16 45 45 46 46 /* local APIC macros */ 47 #define IPI_INIT 048 #define IPI_STARTUP 047 #define IPI_INIT 0 48 #define IPI_STARTUP 0 49 49 50 50 /** Delivery modes. */ 51 #define DELMOD_FIXED 0x052 #define DELMOD_LOWPRI 0x153 #define DELMOD_SMI 0x251 #define DELMOD_FIXED 0x0U 52 #define DELMOD_LOWPRI 0x1U 53 #define DELMOD_SMI 0x2U 54 54 /* 0x3 reserved */ 55 #define DELMOD_NMI 0x456 #define DELMOD_INIT 0x557 #define DELMOD_STARTUP 0x658 #define DELMOD_EXTINT 0x755 #define DELMOD_NMI 0x4U 56 #define DELMOD_INIT 0x5U 57 #define DELMOD_STARTUP 0x6U 58 #define DELMOD_EXTINT 0x7U 59 59 60 60 /** Destination modes. */ 61 #define DESTMOD_PHYS 0x062 #define DESTMOD_LOGIC 0x161 #define DESTMOD_PHYS 0x0U 62 #define DESTMOD_LOGIC 0x1U 63 63 64 64 /** Trigger Modes. */ 65 #define TRIGMOD_EDGE 0x066 #define TRIGMOD_LEVEL 0x165 #define TRIGMOD_EDGE 0x0U 66 #define TRIGMOD_LEVEL 0x1U 67 67 68 68 /** Levels. */ 69 #define LEVEL_DEASSERT 0x070 #define LEVEL_ASSERT 0x169 #define LEVEL_DEASSERT 0x0U 70 #define LEVEL_ASSERT 0x1U 71 71 72 72 /** Destination Shorthands. */ 73 #define SHORTHAND_NONE 0x074 #define SHORTHAND_SELF 0x175 #define SHORTHAND_ALL_INCL 0x276 #define SHORTHAND_ALL_EXCL 0x373 #define SHORTHAND_NONE 0x0U 74 #define SHORTHAND_SELF 0x1U 75 #define SHORTHAND_ALL_INCL 0x2U 76 #define SHORTHAND_ALL_EXCL 0x3U 77 77 78 78 /** Interrupt Input Pin Polarities. */ 79 #define POLARITY_HIGH 0x080 #define POLARITY_LOW 0x179 #define POLARITY_HIGH 0x0U 80 #define POLARITY_LOW 0x1U 81 81 82 82 /** Divide Values. (Bit 2 is always 0) */ 83 #define DIVIDE_2 0x084 #define DIVIDE_4 0x185 #define DIVIDE_8 0x286 #define DIVIDE_16 0x387 #define DIVIDE_32 0x888 #define DIVIDE_64 0x989 #define DIVIDE_128 0xa90 #define DIVIDE_1 0xb83 #define DIVIDE_2 0x0U 84 #define DIVIDE_4 0x1U 85 #define DIVIDE_8 0x2U 86 #define DIVIDE_16 0x3U 87 #define DIVIDE_32 0x8U 88 #define DIVIDE_64 0x9U 89 #define DIVIDE_128 0xaU 90 #define DIVIDE_1 0xbU 91 91 92 92 /** Timer Modes. */ 93 #define TIMER_ONESHOT 0x094 #define TIMER_PERIODIC 0x193 #define TIMER_ONESHOT 0x0U 94 #define TIMER_PERIODIC 0x1U 95 95 96 96 /** Delivery status. */ 97 #define DELIVS_IDLE 0x098 #define DELIVS_PENDING 0x197 #define DELIVS_IDLE 0x0U 98 #define DELIVS_PENDING 0x1U 99 99 100 100 /** Destination masks. */ 101 #define DEST_ALL 0xff101 #define DEST_ALL 0xffU 102 102 103 103 /** Dest format models. */ 104 #define MODEL_FLAT 0xf105 #define MODEL_CLUSTER 0x0104 #define MODEL_FLAT 0xfU 105 #define MODEL_CLUSTER 0x0U 106 106 107 107 /** Interrupt Command Register. */ 108 #define ICRlo (0x300 / sizeof(uint32_t)) 109 #define ICRhi (0x310 / sizeof(uint32_t)) 108 #define ICRlo (0x300U / sizeof(uint32_t)) 109 #define ICRhi (0x310U / sizeof(uint32_t)) 110 110 111 typedef struct { 111 112 union { 112 113 uint32_t lo; 113 114 struct { 114 uint8_t vector; /**< Interrupt Vector. */115 unsigned delmod : 3;/**< Delivery Mode. */116 unsigned destmod : 1;/**< Destination Mode. */117 unsigned delivs : 1;/**< Delivery status (RO). */118 unsigned : 1;/**< Reserved. */119 unsigned level : 1;/**< Level. */120 unsigned trigger_mode : 1;/**< Trigger Mode. */121 unsigned : 2;/**< Reserved. */122 unsigned shorthand : 2;/**< Destination Shorthand. */123 unsigned : 12;/**< Reserved. */115 uint8_t vector; /**< Interrupt Vector. */ 116 unsigned int delmod : 3; /**< Delivery Mode. */ 117 unsigned int destmod : 1; /**< Destination Mode. */ 118 unsigned int delivs : 1; /**< Delivery status (RO). */ 119 unsigned int : 1; /**< Reserved. */ 120 unsigned int level : 1; /**< Level. */ 121 unsigned int trigger_mode : 1; /**< Trigger Mode. */ 122 unsigned int : 2; /**< Reserved. */ 123 unsigned int shorthand : 2; /**< Destination Shorthand. */ 124 unsigned int : 12; /**< Reserved. */ 124 125 } __attribute__ ((packed)); 125 126 }; … … 127 128 uint32_t hi; 128 129 struct { 129 unsigned : 24;/**< Reserved. */130 uint8_t dest; /**< Destination field. */130 unsigned int : 24; /**< Reserved. */ 131 uint8_t dest; /**< Destination field. */ 131 132 } __attribute__ ((packed)); 132 133 }; … … 134 135 135 136 /* End Of Interrupt. */ 136 #define EOI (0x0b0/ sizeof(uint32_t))137 #define EOI (0x0b0U / sizeof(uint32_t)) 137 138 138 139 /** Error Status Register. */ 139 #define ESR (0x280 / sizeof(uint32_t)) 140 #define ESR (0x280U / sizeof(uint32_t)) 141 140 142 typedef union { 141 143 uint32_t value; 142 144 uint8_t err_bitmap; 143 145 struct { 144 unsigned send_checksum_error : 1;145 unsigned receive_checksum_error : 1;146 unsigned send_accept_error : 1;147 unsigned receive_accept_error : 1;148 unsigned : 1;149 unsigned send_illegal_vector : 1;150 unsigned received_illegal_vector : 1;151 unsigned i llegal_register_address : 1;152 unsigned : 24;146 unsigned int send_checksum_error : 1; 147 unsigned int receive_checksum_error : 1; 148 unsigned int send_accept_error : 1; 149 unsigned int receive_accept_error : 1; 150 unsigned int : 1; 151 unsigned int send_illegal_vector : 1; 152 unsigned int received_illegal_vector : 1; 153 unsigned int illegal_register_address : 1; 154 unsigned int : 24; 153 155 } __attribute__ ((packed)); 154 156 } esr_t; 155 157 156 158 /* Task Priority Register */ 157 #define TPR (0x080 / sizeof(uint32_t)) 158 typedef union { 159 uint32_t value; 160 struct { 161 unsigned pri_sc : 4; /**< Task Priority Sub-Class. */ 162 unsigned pri : 4; /**< Task Priority. */ 159 #define TPR (0x080U / sizeof(uint32_t)) 160 161 typedef union { 162 uint32_t value; 163 struct { 164 unsigned int pri_sc : 4; /**< Task Priority Sub-Class. */ 165 unsigned int pri : 4; /**< Task Priority. */ 163 166 } __attribute__ ((packed)); 164 167 } tpr_t; 165 168 166 169 /** Spurious-Interrupt Vector Register. */ 167 #define SVR (0x0f0 / sizeof(uint32_t)) 168 typedef union { 169 uint32_t value; 170 struct { 171 uint8_t vector; /**< Spurious Vector. */ 172 unsigned lapic_enabled : 1; /**< APIC Software Enable/Disable. */ 173 unsigned focus_checking : 1; /**< Focus Processor Checking. */ 174 unsigned : 22; /**< Reserved. */ 170 #define SVR (0x0f0U / sizeof(uint32_t)) 171 172 typedef union { 173 uint32_t value; 174 struct { 175 uint8_t vector; /**< Spurious Vector. */ 176 unsigned int lapic_enabled : 1; /**< APIC Software Enable/Disable. */ 177 unsigned int focus_checking : 1; /**< Focus Processor Checking. */ 178 unsigned int : 22; /**< Reserved. */ 175 179 } __attribute__ ((packed)); 176 180 } svr_t; 177 181 178 182 /** Time Divide Configuration Register. */ 179 #define TDCR (0x3e0 / sizeof(uint32_t)) 180 typedef union { 181 uint32_t value; 182 struct { 183 unsigned div_value : 4; /**< Divide Value, bit 2 is always 0. */ 184 unsigned : 28; /**< Reserved. */ 183 #define TDCR (0x3e0U / sizeof(uint32_t)) 184 185 typedef union { 186 uint32_t value; 187 struct { 188 unsigned int div_value : 4; /**< Divide Value, bit 2 is always 0. */ 189 unsigned int : 28; /**< Reserved. */ 185 190 } __attribute__ ((packed)); 186 191 } tdcr_t; 187 192 188 193 /* Initial Count Register for Timer */ 189 #define ICRT (0x380/ sizeof(uint32_t))194 #define ICRT (0x380U / sizeof(uint32_t)) 190 195 191 196 /* Current Count Register for Timer */ 192 #define CCRT (0x390/ sizeof(uint32_t))197 #define CCRT (0x390U / sizeof(uint32_t)) 193 198 194 199 /** LVT Timer register. */ 195 #define LVT_Tm (0x320 / sizeof(uint32_t)) 196 typedef union { 197 uint32_t value; 198 struct { 199 uint8_t vector; /**< Local Timer Interrupt vector. */ 200 unsigned : 4; /**< Reserved. */ 201 unsigned delivs : 1; /**< Delivery status (RO). */ 202 unsigned : 3; /**< Reserved. */ 203 unsigned masked : 1; /**< Interrupt Mask. */ 204 unsigned mode : 1; /**< Timer Mode. */ 205 unsigned : 14; /**< Reserved. */ 200 #define LVT_Tm (0x320U / sizeof(uint32_t)) 201 202 typedef union { 203 uint32_t value; 204 struct { 205 uint8_t vector; /**< Local Timer Interrupt vector. */ 206 unsigned int : 4; /**< Reserved. */ 207 unsigned int delivs : 1; /**< Delivery status (RO). */ 208 unsigned int : 3; /**< Reserved. */ 209 unsigned int masked : 1; /**< Interrupt Mask. */ 210 unsigned int mode : 1; /**< Timer Mode. */ 211 unsigned int : 14; /**< Reserved. */ 206 212 } __attribute__ ((packed)); 207 213 } lvt_tm_t; 208 214 209 215 /** LVT LINT registers. */ 210 #define LVT_LINT0 (0x350 / sizeof(uint32_t)) 211 #define LVT_LINT1 (0x360 / sizeof(uint32_t)) 212 typedef union { 213 uint32_t value; 214 struct { 215 uint8_t vector; /**< LINT Interrupt vector. */ 216 unsigned delmod : 3; /**< Delivery Mode. */ 217 unsigned : 1; /**< Reserved. */ 218 unsigned delivs : 1; /**< Delivery status (RO). */ 219 unsigned intpol : 1; /**< Interrupt Input Pin Polarity. */ 220 unsigned irr : 1; /**< Remote IRR (RO). */ 221 unsigned trigger_mode : 1; /**< Trigger Mode. */ 222 unsigned masked : 1; /**< Interrupt Mask. */ 223 unsigned : 15; /**< Reserved. */ 216 #define LVT_LINT0 (0x350U / sizeof(uint32_t)) 217 #define LVT_LINT1 (0x360U / sizeof(uint32_t)) 218 219 typedef union { 220 uint32_t value; 221 struct { 222 uint8_t vector; /**< LINT Interrupt vector. */ 223 unsigned int delmod : 3; /**< Delivery Mode. */ 224 unsigned int : 1; /**< Reserved. */ 225 unsigned int delivs : 1; /**< Delivery status (RO). */ 226 unsigned int intpol : 1; /**< Interrupt Input Pin Polarity. */ 227 unsigned int irr : 1; /**< Remote IRR (RO). */ 228 unsigned int trigger_mode : 1; /**< Trigger Mode. */ 229 unsigned int masked : 1; /**< Interrupt Mask. */ 230 unsigned int : 15; /**< Reserved. */ 224 231 } __attribute__ ((packed)); 225 232 } lvt_lint_t; 226 233 227 234 /** LVT Error register. */ 228 #define LVT_Err (0x370 / sizeof(uint32_t)) 229 typedef union { 230 uint32_t value; 231 struct { 232 uint8_t vector; /**< Local Timer Interrupt vector. */ 233 unsigned : 4; /**< Reserved. */ 234 unsigned delivs : 1; /**< Delivery status (RO). */ 235 unsigned : 3; /**< Reserved. */ 236 unsigned masked : 1; /**< Interrupt Mask. */ 237 unsigned : 15; /**< Reserved. */ 235 #define LVT_Err (0x370U / sizeof(uint32_t)) 236 237 typedef union { 238 uint32_t value; 239 struct { 240 uint8_t vector; /**< Local Timer Interrupt vector. */ 241 unsigned int : 4; /**< Reserved. */ 242 unsigned int delivs : 1; /**< Delivery status (RO). */ 243 unsigned int : 3; /**< Reserved. */ 244 unsigned int masked : 1; /**< Interrupt Mask. */ 245 unsigned int : 15; /**< Reserved. */ 238 246 } __attribute__ ((packed)); 239 247 } lvt_error_t; 240 248 241 249 /** Local APIC ID Register. */ 242 #define L_APIC_ID (0x020 / sizeof(uint32_t)) 243 typedef union { 244 uint32_t value; 245 struct { 246 unsigned : 24; /**< Reserved. */ 247 uint8_t apic_id; /**< Local APIC ID. */ 250 #define L_APIC_ID (0x020U / sizeof(uint32_t)) 251 252 typedef union { 253 uint32_t value; 254 struct { 255 unsigned int : 24; /**< Reserved. */ 256 uint8_t apic_id; /**< Local APIC ID. */ 248 257 } __attribute__ ((packed)); 249 258 } l_apic_id_t; 250 259 251 260 /** Local APIC Version Register */ 252 #define LAVR (0x030 / sizeof(uint32_t)) 253 #define LAVR_Mask 0xff 254 #define is_local_apic(x) (((x) & LAVR_Mask & 0xf0) == 0x1) 255 #define is_82489DX_apic(x) ((((x) & LAVR_Mask & 0xf0) == 0x0)) 256 #define is_local_xapic(x) (((x) & LAVR_Mask) == 0x14) 261 #define LAVR (0x030U / sizeof(uint32_t)) 262 #define LAVR_Mask 0xffU 263 264 #define is_local_apic(x) (((x) & LAVR_Mask & 0xf0U) == 0x1U) 265 #define is_82489DX_apic(x) ((((x) & LAVR_Mask & 0xf0U) == 0x0U)) 266 #define is_local_xapic(x) (((x) & LAVR_Mask) == 0x14U) 257 267 258 268 /** Logical Destination Register. */ 259 #define LDR (0x0d0 / sizeof(uint32_t)) 260 typedef union { 261 uint32_t value; 262 struct { 263 unsigned : 24; /**< Reserved. */ 264 uint8_t id; /**< Logical APIC ID. */ 269 #define LDR (0x0d0U / sizeof(uint32_t)) 270 271 typedef union { 272 uint32_t value; 273 struct { 274 unsigned int : 24; /**< Reserved. */ 275 uint8_t id; /**< Logical APIC ID. */ 265 276 } __attribute__ ((packed)); 266 277 } ldr_t; 267 278 268 279 /** Destination Format Register. */ 269 #define DFR (0x0e0 / sizeof(uint32_t)) 270 typedef union { 271 uint32_t value; 272 struct { 273 unsigned : 28; /**< Reserved, all ones. */ 274 unsigned model : 4; /**< Model. */ 280 #define DFR (0x0e0U / sizeof(uint32_t)) 281 282 typedef union { 283 uint32_t value; 284 struct { 285 unsigned int : 28; /**< Reserved, all ones. */ 286 unsigned int model : 4; /**< Model. */ 275 287 } __attribute__ ((packed)); 276 288 } dfr_t; 277 289 278 290 /* IO APIC */ 279 #define IOREGSEL (0x00/ sizeof(uint32_t))280 #define IOWIN (0x10/ sizeof(uint32_t))281 282 #define IOAPICID 0x00283 #define IOAPICVER 0x01284 #define IOAPICARB 0x02285 #define IOREDTBL 0x10291 #define IOREGSEL (0x00U / sizeof(uint32_t)) 292 #define IOWIN (0x10U / sizeof(uint32_t)) 293 294 #define IOAPICID 0x00U 295 #define IOAPICVER 0x01U 296 #define IOAPICARB 0x02U 297 #define IOREDTBL 0x10U 286 298 287 299 /** I/O Register Select Register. */ … … 289 301 uint32_t value; 290 302 struct { 291 uint8_t reg_addr; /**< APIC Register Address. */292 unsigned : 24;/**< Reserved. */303 uint8_t reg_addr; /**< APIC Register Address. */ 304 unsigned int : 24; /**< Reserved. */ 293 305 } __attribute__ ((packed)); 294 306 } io_regsel_t; … … 299 311 uint32_t lo; 300 312 struct { 301 uint8_t intvec; /**< Interrupt Vector. */302 unsigned delmod : 3;/**< Delivery Mode. */303 unsigned destmod : 1;/**< Destination mode. */304 unsigned delivs : 1;/**< Delivery status (RO). */305 unsigned int pol : 1;/**< Interrupt Input Pin Polarity. */306 unsigned i rr : 1;/**< Remote IRR (RO). */307 unsigned trigger_mode : 1;/**< Trigger Mode. */308 unsigned masked : 1;/**< Interrupt Mask. */309 unsigned : 15;/**< Reserved. */313 uint8_t intvec; /**< Interrupt Vector. */ 314 unsigned int delmod : 3; /**< Delivery Mode. */ 315 unsigned int destmod : 1; /**< Destination mode. */ 316 unsigned int delivs : 1; /**< Delivery status (RO). */ 317 unsigned int intpol : 1; /**< Interrupt Input Pin Polarity. */ 318 unsigned int irr : 1; /**< Remote IRR (RO). */ 319 unsigned int trigger_mode : 1; /**< Trigger Mode. */ 320 unsigned int masked : 1; /**< Interrupt Mask. */ 321 unsigned int : 15; /**< Reserved. */ 310 322 } __attribute__ ((packed)); 311 323 }; … … 313 325 uint32_t hi; 314 326 struct { 315 unsigned : 24;/**< Reserved. */316 uint8_t dest : 8; /**< Destination Field. */327 unsigned int : 24; /**< Reserved. */ 328 uint8_t dest : 8; /**< Destination Field. */ 317 329 } __attribute__ ((packed)); 318 330 }; … … 325 337 uint32_t value; 326 338 struct { 327 unsigned : 24;/**< Reserved. */328 unsigned apic_id : 4;/**< IO APIC ID. */329 unsigned : 4;/**< Reserved. */339 unsigned int : 24; /**< Reserved. */ 340 unsigned int apic_id : 4; /**< IO APIC ID. */ 341 unsigned int : 4; /**< Reserved. */ 330 342 } __attribute__ ((packed)); 331 343 } io_apic_id_t; … … 335 347 336 348 extern uint32_t apic_id_mask; 349 extern uint8_t bsp_l_apic; 337 350 338 351 extern void apic_init(void); … … 340 353 extern void l_apic_init(void); 341 354 extern void l_apic_eoi(void); 342 extern int l_apic_broadcast_custom_ipi(uint8_t vector);343 extern int l_apic_send_init_ipi(uint8_t apicid);355 extern int l_apic_broadcast_custom_ipi(uint8_t); 356 extern int l_apic_send_init_ipi(uint8_t); 344 357 extern void l_apic_debug(void); 345 extern uint8_t l_apic_id(void); 346 347 extern uint32_t io_apic_read(uint8_t address); 348 extern void io_apic_write(uint8_t address , uint32_t x); 349 extern void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t v, int flags); 350 extern void io_apic_disable_irqs(uint16_t irqmask); 351 extern void io_apic_enable_irqs(uint16_t irqmask); 358 359 extern uint32_t io_apic_read(uint8_t); 360 extern void io_apic_write(uint8_t, uint32_t); 361 extern void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t v, unsigned int); 362 extern void io_apic_disable_irqs(uint16_t); 363 extern void io_apic_enable_irqs(uint16_t); 352 364 353 365 #endif -
kernel/arch/ia32/include/smp/mps.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia32_MPS_H_ 37 37 38 #include < arch/types.h>38 #include <typedefs.h> 39 39 #include <synch/waitq.h> 40 40 #include <config.h> 41 41 #include <arch/smp/smp.h> 42 42 43 #define CT_EXT_ENTRY_TYPE 044 #define CT_EXT_ENTRY_LEN 143 #define CT_EXT_ENTRY_TYPE 0 44 #define CT_EXT_ENTRY_LEN 1 45 45 46 46 struct mps_fs { … … 70 70 uint16_t ext_table_length; 71 71 uint8_t ext_table_checksum; 72 uint8_t xxx;72 uint8_t reserved; 73 73 uint8_t base_table[0]; 74 74 } __attribute__ ((packed)); … … 81 81 uint8_t cpu_signature[4]; 82 82 uint32_t feature_flags; 83 uint32_t xxx[2];83 uint32_t reserved[2]; 84 84 } __attribute__ ((packed)); 85 85 … … 102 102 uint8_t intr_type; 103 103 uint8_t poel; 104 uint8_t xxx;104 uint8_t reserved; 105 105 uint8_t src_bus_id; 106 106 uint8_t src_bus_irq; … … 113 113 uint8_t intr_type; 114 114 uint8_t poel; 115 uint8_t xxx;115 uint8_t reserved; 116 116 uint8_t src_bus_id; 117 117 uint8_t src_bus_irq; -
kernel/arch/ia32/include/smp/smp.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia32_SMP_H_ 37 37 38 #include < arch/types.h>38 #include <typedefs.h> 39 39 40 40 /** SMP config opertaions interface. */ 41 41 struct smp_config_operations { 42 size_t (* cpu_count)(void); /**< Return number of detected processors. */ 43 bool (* cpu_enabled)(size_t i); /**< Check whether the processor of index i is enabled. */ 44 bool (*cpu_bootstrap)(size_t i); /**< Check whether the processor of index i is BSP. */ 45 uint8_t (*cpu_apic_id)(size_t i); /**< Return APIC ID of the processor of index i. */ 46 int (*irq_to_pin)(unsigned int irq); /**< Return mapping between irq and APIC pin. */ 42 /** Check whether a processor is enabled. */ 43 bool (* cpu_enabled)(size_t); 44 45 /** Check whether a processor is BSP. */ 46 bool (*cpu_bootstrap)(size_t); 47 48 /** Return APIC ID of a processor. */ 49 uint8_t (*cpu_apic_id)(size_t); 50 51 /** Return mapping between IRQ and APIC pin. */ 52 int (*irq_to_pin)(unsigned int); 47 53 }; 48 54 49 extern int smp_irq_to_pin(unsigned int irq);55 extern int smp_irq_to_pin(unsigned int); 50 56 51 57 #endif -
kernel/arch/ia32/include/types.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia32_TYPES_H_ 37 37 38 typedef signed char int8_t;39 typedef signed short int16_t;40 typedef signed long int32_t;41 typedef signed long long int64_t;42 43 typedef unsigned char uint8_t;44 typedef unsigned short uint16_t;45 typedef unsigned long uint32_t;46 typedef unsigned long long uint64_t;47 48 38 typedef uint32_t size_t; 49 39 … … 53 43 typedef uint32_t ipl_t; 54 44 55 typedef uint32_t unative_t;45 typedef uint32_t sysarg_t; 56 46 typedef int32_t native_t; 47 typedef uint32_t atomic_count_t; 57 48 58 49 typedef struct { 59 50 } fncptr_t; 60 51 61 #define PRIp "x" /**< Format for uintptr_t. */62 #define PRIs "u" /**< Format for size_t. */52 #define INTN_C(c) INT32_C(c) 53 #define UINTN_C(c) UINT32_C(c) 63 54 64 #define PRId8 "d" /**< Format for int8_t. */ 65 #define PRId16 "d" /**< Format for int16_t. */ 66 #define PRId32 "d" /**< Format for int32_t. */ 67 #define PRId64 "lld" /**< Format for int64_t. */ 68 #define PRIdn "d" /**< Format for native_t. */ 69 70 #define PRIu8 "u" /**< Format for uint8_t. */ 71 #define PRIu16 "u" /**< Format for uint16_t. */ 72 #define PRIu32 "u" /**< Format for uint32_t. */ 73 #define PRIu64 "llu" /**< Format for uint64_t. */ 74 #define PRIun "u" /**< Format for unative_t. */ 75 76 #define PRIx8 "x" /**< Format for hexadecimal (u)int8_t. */ 77 #define PRIx16 "x" /**< Format for hexadecimal (u)int16_t. */ 78 #define PRIx32 "x" /**< Format for hexadecimal (u)uint32_t. */ 79 #define PRIx64 "llx" /**< Format for hexadecimal (u)int64_t. */ 80 #define PRIxn "x" /**< Format for hexadecimal (u)native_t. */ 81 82 /** Page Table Entry. */ 83 typedef struct { 84 unsigned present : 1; 85 unsigned writeable : 1; 86 unsigned uaccessible : 1; 87 unsigned page_write_through : 1; 88 unsigned page_cache_disable : 1; 89 unsigned accessed : 1; 90 unsigned dirty : 1; 91 unsigned pat : 1; 92 unsigned global : 1; 93 unsigned soft_valid : 1; /**< Valid content even if the present bit is not set. */ 94 unsigned avl : 2; 95 unsigned frame_address : 20; 96 } __attribute__ ((packed)) pte_t; 55 #define PRIdn PRId32 /**< Format for native_t. */ 56 #define PRIun PRIu32 /**< Format for sysarg_t. */ 57 #define PRIxn PRIx32 /**< Format for hexadecimal sysarg_t. */ 58 #define PRIua PRIu32 /**< Format for atomic_count_t. */ 97 59 98 60 #endif -
kernel/arch/ia32/src/asm.S
rb50b5af2 r04803bf 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 1 /* 2 * Copyright (c) 2010 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 #include <arch/pm.h> 34 #include <arch/cpu.h> 35 #include <arch/mm/page.h> 34 36 35 37 .text 36 37 38 .global paging_on 38 39 .global enable_l_apic_in_msr 39 .global interrupt_handlers40 40 .global memsetb 41 41 .global memsetw … … 45 45 .global memcpy_to_uspace 46 46 .global memcpy_to_uspace_failover_address 47 48 49 # Wrapper for generic memsetb 47 .global early_putchar 48 49 /* Wrapper for generic memsetb */ 50 50 memsetb: 51 51 jmp _memsetb 52 52 53 # Wrapper for generic memsetw 53 /* Wrapper for generic memsetw */ 54 54 memsetw: 55 55 jmp _memsetw 56 56 57 58 #define MEMCPY_DST 4 59 #define MEMCPY_SRC 8 60 #define MEMCPY_SIZE 12 57 #define MEMCPY_DST 4 58 #define MEMCPY_SRC 8 59 #define MEMCPY_SIZE 12 61 60 62 61 /** Copy memory to/from userspace. … … 68 67 * or copy_to_uspace(). 69 68 * 70 * @param MEMCPY_DST(%esp) Destination address.71 * @param MEMCPY_SRC(%esp) Source address.72 * @param MEMCPY_SIZE(%esp) Size.69 * @param MEMCPY_DST(%esp) Destination address. 70 * @param MEMCPY_SRC(%esp) Source address. 71 * @param MEMCPY_SIZE(%esp) Size. 73 72 * 74 73 * @return MEMCPY_DST(%esp) on success and 0 on failure. 74 * 75 75 */ 76 76 memcpy: 77 77 memcpy_from_uspace: 78 78 memcpy_to_uspace: 79 movl %edi, %edx /* save %edi */80 movl %esi, %eax /* save %esi */79 movl %edi, %edx /* save %edi */ 80 movl %esi, %eax /* save %esi */ 81 81 82 82 movl MEMCPY_SIZE(%esp), %ecx 83 shrl $2, %ecx /* size / 4 */83 shrl $2, %ecx /* size / 4 */ 84 84 85 85 movl MEMCPY_DST(%esp), %edi 86 86 movl MEMCPY_SRC(%esp), %esi 87 87 88 rep movsl /* copy whole words */ 89 88 /* Copy whole words */ 89 rep movsl 90 90 91 movl MEMCPY_SIZE(%esp), %ecx 91 andl $3, %ecx /* size % 4 */92 andl $3, %ecx /* size % 4 */ 92 93 jz 0f 93 94 94 rep movsb /* copy the rest byte by byte */ 95 96 0: 97 movl %edx, %edi 98 movl %eax, %esi 99 movl MEMCPY_DST(%esp), %eax /* MEMCPY_DST(%esp), success */ 100 ret 101 95 /* Copy the rest byte by byte */ 96 rep movsb 97 98 0: 99 100 movl %edx, %edi 101 movl %eax, %esi 102 103 /* MEMCPY_DST(%esp), success */ 104 movl MEMCPY_DST(%esp), %eax 105 ret 106 102 107 /* 103 108 * We got here from as_page_fault() after the memory operations … … 108 113 movl %edx, %edi 109 114 movl %eax, %esi 110 xorl %eax, %eax /* return 0, failure */ 115 116 /* Return 0, failure */ 117 xorl %eax, %eax 111 118 ret 112 119 113 ## Turn paging on 114 # 115 # Enable paging and write-back caching in CR0. 116 # 120 /** Turn paging on 121 * 122 * Enable paging and write-back caching in CR0. 123 * 124 */ 117 125 paging_on: 118 126 movl %cr0, %edx 119 orl $(1 << 31), %edx # paging on 120 # clear Cache Disable and not Write Though 127 orl $(1 << 31), %edx /* paging on */ 128 129 /* Clear Cache Disable and not Write Though */ 121 130 andl $~((1 << 30) | (1 << 29)), %edx 122 movl %edx, %cr0131 movl %edx, %cr0 123 132 jmp 0f 124 0: 125 ret 126 127 128 ## Enable local APIC 129 # 130 # Enable local APIC in MSR. 131 # 133 134 0: 135 ret 136 137 /** Enable local APIC 138 * 139 * Enable local APIC in MSR. 140 * 141 */ 132 142 enable_l_apic_in_msr: 133 143 movl $0x1b, %ecx … … 138 148 ret 139 149 140 # Clear nested flag 141 # overwrites %ecx 142 .macro CLEAR_NT_FLAG 143 pushfl 144 pop %ecx 145 and $0xffffbfff, %ecx 146 push %ecx 147 popfl 148 .endm 150 #define ISTATE_OFFSET_EDX 0 151 #define ISTATE_OFFSET_ECX 4 152 #define ISTATE_OFFSET_EBX 8 153 #define ISTATE_OFFSET_ESI 12 154 #define ISTATE_OFFSET_EDI 16 155 #define ISTATE_OFFSET_EBP 20 156 #define ISTATE_OFFSET_EAX 24 157 #define ISTATE_OFFSET_EBP_FRAME 28 158 #define ISTATE_OFFSET_EIP_FRAME 32 159 #define ISTATE_OFFSET_GS 36 160 #define ISTATE_OFFSET_FS 40 161 #define ISTATE_OFFSET_ES 44 162 #define ISTATE_OFFSET_DS 48 163 #define ISTATE_OFFSET_ERROR_WORD 52 164 #define ISTATE_OFFSET_EIP 56 165 #define ISTATE_OFFSET_CS 60 166 #define ISTATE_OFFSET_EFLAGS 64 167 #define ISTATE_OFFSET_ESP 68 168 #define ISTATE_OFFSET_SS 72 169 170 /* 171 * Size of the istate structure without the hardware-saved part 172 * and without the error word. 173 */ 174 #define ISTATE_SOFT_SIZE 52 149 175 150 176 /* … … 159 185 .global sysenter_handler 160 186 sysenter_handler: 161 sti 162 pushl %ebp # remember user stack 163 pushl %edi # remember return user address 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 174 movw $16, %ax 187 188 /* 189 * Note that the space needed for the istate structure has been 190 * preallocated on the stack by before_thread_runs_arch(). 191 */ 192 193 /* 194 * Save the return address and the userspace stack in the istate 195 * structure on locations that would normally be taken by them. 196 */ 197 movl %ebp, ISTATE_OFFSET_ESP(%esp) 198 movl %edi, ISTATE_OFFSET_EIP(%esp) 199 200 /* 201 * Push syscall arguments onto the stack 202 */ 203 movl %eax, ISTATE_OFFSET_EAX(%esp) 204 movl %ebx, ISTATE_OFFSET_EBX(%esp) 205 movl %ecx, ISTATE_OFFSET_ECX(%esp) 206 movl %edx, ISTATE_OFFSET_EDX(%esp) 207 movl %esi, ISTATE_OFFSET_ESI(%esp) 208 movl %edi, ISTATE_OFFSET_EDI(%esp) /* observability; not needed */ 209 movl %ebp, ISTATE_OFFSET_EBP(%esp) /* observability; not needed */ 210 211 /* 212 * Fake up the stack trace linkage. 213 */ 214 movl %edi, ISTATE_OFFSET_EIP_FRAME(%esp) 215 movl $0, ISTATE_OFFSET_EBP_FRAME(%esp) 216 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp 217 218 /* 219 * Save TLS. 220 */ 221 movl %gs, %edx 222 movl %edx, ISTATE_OFFSET_GS(%esp) 223 224 /* 225 * Switch to kernel selectors. 226 */ 227 movw $(GDT_SELECTOR(KDATA_DES)), %ax 175 228 movw %ax, %ds 176 229 movw %ax, %es 177 230 231 /* 232 * Sanitize EFLAGS. 233 * 234 * SYSENTER does not clear the NT flag, which could thus proliferate 235 * from here to the IRET instruction via a context switch and result 236 * in crash. 237 * 238 * SYSENTER does not clear DF, which the ABI assumes to be cleared. 239 * 240 * SYSENTER clears IF, which we would like to be set for syscalls. 241 * 242 */ 243 pushl $(EFLAGS_IF) /* specify EFLAGS bits that we want to set */ 244 popfl /* set bits from the mask, clear or ignore others */ 245 246 call syscall_handler 247 248 /* 249 * Restore TLS. 250 */ 251 movl ISTATE_OFFSET_GS(%esp), %edx 252 movl %edx, %gs 253 254 /* 255 * Prepare return address and userspace stack for SYSEXIT. 256 */ 257 movl ISTATE_OFFSET_EIP(%esp), %edx 258 movl ISTATE_OFFSET_ESP(%esp), %ecx 259 260 sysexit /* return to userspace */ 261 262 /* 263 * This is the legacy syscall handler using the interrupt mechanism. 264 */ 265 .global int_syscall 266 int_syscall: 267 subl $(ISTATE_SOFT_SIZE + 4), %esp 268 269 /* 270 * Push syscall arguments onto the stack 271 * 272 * NOTE: The idea behind the order of arguments passed 273 * in registers is to use all scratch registers 274 * first and preserved registers next. An optimized 275 * libc syscall wrapper can make use of this setup. 276 * The istate structure is arranged in the way to support 277 * this idea. 278 * 279 */ 280 movl %eax, ISTATE_OFFSET_EAX(%esp) 281 movl %ebx, ISTATE_OFFSET_EBX(%esp) 282 movl %ecx, ISTATE_OFFSET_ECX(%esp) 283 movl %edx, ISTATE_OFFSET_EDX(%esp) 284 movl %edi, ISTATE_OFFSET_EDI(%esp) 285 movl %esi, ISTATE_OFFSET_ESI(%esp) 286 movl %ebp, ISTATE_OFFSET_EBP(%esp) 287 288 /* 289 * Save the selector registers. 290 */ 291 movl %gs, %ecx 292 movl %fs, %edx 293 294 movl %ecx, ISTATE_OFFSET_GS(%esp) 295 movl %edx, ISTATE_OFFSET_FS(%esp) 296 297 movl %es, %ecx 298 movl %ds, %edx 299 300 movl %ecx, ISTATE_OFFSET_ES(%esp) 301 movl %edx, ISTATE_OFFSET_DS(%esp) 302 303 /* 304 * Switch to kernel selectors. 305 */ 306 movl $(GDT_SELECTOR(KDATA_DES)), %eax 307 movl %eax, %ds 308 movl %eax, %es 309 310 movl $0, ISTATE_OFFSET_EBP_FRAME(%esp) 311 movl ISTATE_OFFSET_EIP(%esp), %eax 312 movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp) 313 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp 314 178 315 cld 316 317 /* Call syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) */ 179 318 call syscall_handler 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 ## Declare interrupt handlers 191 # 192 # Declare interrupt handlers for n interrupt 193 # vectors starting at vector i. 194 # 195 # The handlers setup data segment registers 196 # and call exc_dispatch(). 197 # 198 #define INTERRUPT_ALIGN 64 199 .macro handler i n 200 201 .ifeq \i - 0x30 # Syscall handler 202 pushl %ds 203 pushl %es 204 pushl %fs 205 pushl %gs 206 207 # 208 # Push syscall arguments onto the stack 209 # 210 # NOTE: The idea behind the order of arguments passed in registers is to 211 # use all scratch registers first and preserved registers next. 212 # An optimized libc syscall wrapper can make use of this setup. 213 # 214 pushl %eax 215 pushl %ebp 216 pushl %edi 217 pushl %esi 218 pushl %ebx 219 pushl %ecx 220 pushl %edx 221 222 # we must fill the data segment registers 223 movw $16, %ax 224 movw %ax, %ds 225 movw %ax, %es 226 227 cld 228 sti 229 # syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) 230 call syscall_handler 231 cli 232 addl $28, %esp # clean-up of parameters 233 234 popl %gs 235 popl %fs 236 popl %es 237 popl %ds 238 239 CLEAR_NT_FLAG 319 320 /* 321 * Restore the selector registers. 322 */ 323 movl ISTATE_OFFSET_GS(%esp), %ecx 324 movl ISTATE_OFFSET_FS(%esp), %edx 325 326 movl %ecx, %gs 327 movl %edx, %fs 328 329 movl ISTATE_OFFSET_ES(%esp), %ecx 330 movl ISTATE_OFFSET_DS(%esp), %edx 331 332 movl %ecx, %es 333 movl %edx, %ds 334 335 /* 336 * Restore the preserved registers the handler cloberred itself 337 * (i.e. EBP). 338 */ 339 movl ISTATE_OFFSET_EBP(%esp), %ebp 340 341 addl $(ISTATE_SOFT_SIZE + 4), %esp 240 342 iret 241 .else 242 /* 243 * This macro distinguishes between two versions of ia32 exceptions. 244 * One version has error word and the other does not have it. 245 * The latter version fakes the error word on the stack so that the 246 * handlers and istate_t can be the same for both types. 343 344 /** 345 * Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int 346 * has no error word and 1 means interrupt with error word 347 * 348 */ 349 #define ERROR_WORD_INTERRUPT_LIST 0x00027d00 350 351 .macro handler i 352 .global int_\i 353 int_\i: 354 /* 355 * This macro distinguishes between two versions of ia32 356 * exceptions. One version has error word and the other 357 * does not have it. The latter version fakes the error 358 * word on the stack so that the handlers and istate_t 359 * can be the same for both types. 247 360 */ 248 361 .iflt \i - 32 249 362 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST 250 /* 251 * With error word, do nothing363 /* 364 * Exception with error word. 252 365 */ 253 .else 254 /* 255 * Version without error word, 256 */ 257 subl $4, %esp 258 .endif 259 .else 260 /* 261 * Version without error word, 262 */ 263 subl $4, %esp 366 subl $ISTATE_SOFT_SIZE, %esp 367 .else 368 /* 369 * Exception without error word: fake up one 370 */ 371 subl $(ISTATE_SOFT_SIZE + 4), %esp 372 .endif 373 .else 374 /* 375 * Interrupt: fake up an error word 376 */ 377 subl $(ISTATE_SOFT_SIZE + 4), %esp 264 378 .endif 265 379 266 pushl %ds 267 pushl %es 268 pushl %fs 269 pushl %gs 270 271 pushl %edx 272 pushl %ecx 273 pushl %eax 274 275 # we must fill the data segment registers 276 movw $16, %ax 277 movw %ax, %ds 278 movw %ax, %es 279 380 /* 381 * Save the general purpose registers. 382 */ 383 movl %eax, ISTATE_OFFSET_EAX(%esp) 384 movl %ebx, ISTATE_OFFSET_EBX(%esp) 385 movl %ecx, ISTATE_OFFSET_ECX(%esp) 386 movl %edx, ISTATE_OFFSET_EDX(%esp) 387 movl %edi, ISTATE_OFFSET_EDI(%esp) 388 movl %esi, ISTATE_OFFSET_ESI(%esp) 389 movl %ebp, ISTATE_OFFSET_EBP(%esp) 390 391 /* 392 * Save the selector registers. 393 */ 394 movl %gs, %ecx 395 movl %fs, %edx 396 397 movl %ecx, ISTATE_OFFSET_GS(%esp) 398 movl %edx, ISTATE_OFFSET_FS(%esp) 399 400 movl %es, %ecx 401 movl %ds, %edx 402 403 movl %ecx, ISTATE_OFFSET_ES(%esp) 404 movl %edx, ISTATE_OFFSET_DS(%esp) 405 406 /* 407 * Switch to kernel selectors. 408 */ 409 movl $(GDT_SELECTOR(KDATA_DES)), %eax 410 movl %eax, %ds 411 movl %eax, %es 412 413 /* 414 * Imitate a regular stack frame linkage. 415 * Stop stack traces here if we came from userspace. 416 */ 417 xorl %eax, %eax 418 cmpl $(GDT_SELECTOR(KTEXT_DES)), ISTATE_OFFSET_CS(%esp) 419 cmovnzl %eax, %ebp 420 421 movl %ebp, ISTATE_OFFSET_EBP_FRAME(%esp) 422 movl ISTATE_OFFSET_EIP(%esp), %eax 423 movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp) 424 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp 425 280 426 cld 281 282 pushl %esp # *istate 283 pushl $(\i) # intnum 284 call exc_dispatch # excdispatch(intnum, *istate) 285 addl $8, %esp # Clear arguments from stack 286 287 CLEAR_NT_FLAG # Modifies %ecx 288 289 popl %eax 290 popl %ecx 291 popl %edx 292 293 popl %gs 294 popl %fs 295 popl %es 296 popl %ds 297 298 addl $4, %esp # Skip error word, no matter whether real or fake. 427 428 pushl %esp /* pass istate address */ 429 pushl $(\i) /* pass intnum */ 430 431 /* Call exc_dispatch(intnum, istate) */ 432 call exc_dispatch 433 434 addl $8, %esp /* clear arguments from the stack */ 435 436 /* 437 * Restore the selector registers. 438 */ 439 movl ISTATE_OFFSET_GS(%esp), %ecx 440 movl ISTATE_OFFSET_FS(%esp), %edx 441 442 movl %ecx, %gs 443 movl %edx, %fs 444 445 movl ISTATE_OFFSET_ES(%esp), %ecx 446 movl ISTATE_OFFSET_DS(%esp), %edx 447 448 movl %ecx, %es 449 movl %edx, %ds 450 451 /* 452 * Restore the scratch registers and the preserved 453 * registers the handler cloberred itself 454 * (i.e. EBP). 455 */ 456 movl ISTATE_OFFSET_EAX(%esp), %eax 457 movl ISTATE_OFFSET_ECX(%esp), %ecx 458 movl ISTATE_OFFSET_EDX(%esp), %edx 459 movl ISTATE_OFFSET_EBP(%esp), %ebp 460 461 addl $(ISTATE_SOFT_SIZE + 4), %esp 299 462 iret 300 .endif301 302 .align INTERRUPT_ALIGN303 .if (\n- \i) - 1304 handler "(\i + 1)", \n305 .endif306 463 .endm 307 464 308 # keep in sync with pm.h !!! 309 IDT_ITEMS = 64 310 .align INTERRUPT_ALIGN 465 #define LIST_0_63 \ 466 0, 1, 2, 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\ 467 28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,\ 468 53,54,55,56,57,58,59,60,61,62,63 469 311 470 interrupt_handlers: 312 h_start: 313 handler 0 IDT_ITEMS 314 h_end: 315 316 .data 317 .global interrupt_handler_size 318 319 interrupt_handler_size: .long (h_end - h_start) / IDT_ITEMS 471 .irp cnt, LIST_0_63 472 handler \cnt 473 .endr 474 475 /** Print Unicode character to EGA display. 476 * 477 * If CONFIG_EGA is undefined or CONFIG_FB is defined 478 * then this function does nothing. 479 * 480 * Since the EGA can only display Extended ASCII (usually 481 * ISO Latin 1) characters, some of the Unicode characters 482 * can be displayed in a wrong way. Only newline and backspace 483 * are interpreted, all other characters (even unprintable) are 484 * printed verbatim. 485 * 486 * @param %ebp+0x08 Unicode character to be printed. 487 * 488 */ 489 early_putchar: 490 491 #if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB))) 492 493 /* Prologue, save preserved registers */ 494 pushl %ebp 495 movl %esp, %ebp 496 pushl %ebx 497 pushl %esi 498 pushl %edi 499 500 movl $(PA2KA(0xb8000)), %edi /* base of EGA text mode memory */ 501 xorl %eax, %eax 502 503 /* Read bits 8 - 15 of the cursor address */ 504 movw $0x3d4, %dx 505 movb $0xe, %al 506 outb %al, %dx 507 508 movw $0x3d5, %dx 509 inb %dx, %al 510 shl $8, %ax 511 512 /* Read bits 0 - 7 of the cursor address */ 513 movw $0x3d4, %dx 514 movb $0xf, %al 515 outb %al, %dx 516 517 movw $0x3d5, %dx 518 inb %dx, %al 519 520 /* Sanity check for the cursor on screen */ 521 cmp $2000, %ax 522 jb early_putchar_cursor_ok 523 524 movw $1998, %ax 525 526 early_putchar_cursor_ok: 527 528 movw %ax, %bx 529 shl $1, %eax 530 addl %eax, %edi 531 532 movl 0x08(%ebp), %eax 533 534 cmp $0x0a, %al 535 jne early_putchar_backspace 536 537 /* Interpret newline */ 538 539 movw %bx, %ax /* %bx -> %dx:%ax */ 540 xorw %dx, %dx 541 542 movw $80, %cx 543 idivw %cx, %ax /* %dx = %bx % 80 */ 544 545 /* %bx <- %bx + 80 - (%bx % 80) */ 546 addw %cx, %bx 547 subw %dx, %bx 548 549 jmp early_putchar_skip 550 551 early_putchar_backspace: 552 553 cmp $0x08, %al 554 jne early_putchar_print 555 556 /* Interpret backspace */ 557 558 cmp $0x0000, %bx 559 je early_putchar_skip 560 561 dec %bx 562 jmp early_putchar_skip 563 564 early_putchar_print: 565 566 /* Print character */ 567 568 movb $0x0e, %ah /* black background, yellow foreground */ 569 stosw 570 inc %bx 571 572 early_putchar_skip: 573 574 /* Sanity check for the cursor on the last line */ 575 cmp $2000, %bx 576 jb early_putchar_no_scroll 577 578 /* Scroll the screen (24 rows) */ 579 movl $(PA2KA(0xb80a0)), %esi 580 movl $(PA2KA(0xb8000)), %edi 581 movl $960, %ecx 582 rep movsl 583 584 /* Clear the 24th row */ 585 xorl %eax, %eax 586 movl $40, %ecx 587 rep stosl 588 589 /* Go to row 24 */ 590 movw $1920, %bx 591 592 early_putchar_no_scroll: 593 594 /* Write bits 8 - 15 of the cursor address */ 595 movw $0x3d4, %dx 596 movb $0xe, %al 597 outb %al, %dx 598 599 movw $0x3d5, %dx 600 movb %bh, %al 601 outb %al, %dx 602 603 /* Write bits 0 - 7 of the cursor address */ 604 movw $0x3d4, %dx 605 movb $0xf, %al 606 outb %al, %dx 607 608 movw $0x3d5, %dx 609 movb %bl, %al 610 outb %al, %dx 611 612 /* Epilogue, restore preserved registers */ 613 popl %edi 614 popl %esi 615 popl %ebx 616 leave 617 618 #endif 619 620 ret 621 -
kernel/arch/ia32/src/bios/bios.c
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 34 34 35 35 #include <arch/bios/bios.h> 36 #include <arch/types.h> 36 #include <typedefs.h> 37 38 #define BIOS_EBDA_PTR 0x40eU 37 39 38 40 uintptr_t ebda = 0; … … 41 43 { 42 44 /* Copy the EBDA address out from BIOS Data Area */ 43 ebda = *((uint16_t *) BIOS_EBDA_PTR) * 0x10 ;45 ebda = *((uint16_t *) BIOS_EBDA_PTR) * 0x10U; 44 46 } 45 47 -
kernel/arch/ia32/src/boot/boot.S
rb50b5af2 r04803bf 1 # 2 # Copyright (c) 2001-2004Jakub Jermar3 # Copyright (c) 2005-2006Martin 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 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 */ 29 29 30 30 #include <arch/boot/boot.h> … … 34 34 #include <arch/cpuid.h> 35 35 36 #define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)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 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 41 61 .align 4 42 62 .global multiboot_image_start … … 44 64 .long MULTIBOOT_HEADER_MAGIC 45 65 .long MULTIBOOT_HEADER_FLAGS 46 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum66 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) /* checksum */ 47 67 .long multiboot_header 48 68 .long unmapped_ktext_start … … 53 73 multiboot_image_start: 54 74 cld 55 movl $START_STACK, %esp # initialize stack pointer 56 lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register 57 58 movw $gdtselector(KDATA_DES), %cx 75 76 /* Initialize stack pointer */ 77 movl $START_STACK, %esp 78 79 /* Initialize Global Descriptor Table register */ 80 lgdtl bootstrap_gdtr 81 82 /* Kernel data + stack */ 83 movw $GDT_SELECTOR(KDATA_DES), %cx 59 84 movw %cx, %es 60 85 movw %cx, %fs 61 86 movw %cx, %gs 62 movw %cx, %ds # kernel data + stack87 movw %cx, %ds 63 88 movw %cx, %ss 64 89 65 jmpl $ gdtselector(KTEXT_DES), $multiboot_meeting_point90 jmpl $GDT_SELECTOR(KTEXT_DES), $multiboot_meeting_point 66 91 multiboot_meeting_point: 67 92 68 movl %eax, grub_eax # save parameters from GRUB 93 /* Save GRUB arguments */ 94 movl %eax, grub_eax 69 95 movl %ebx, grub_ebx 96 97 pm_status $status_prot 70 98 71 99 movl $(INTEL_CPUID_LEVEL), %eax 72 100 cpuid 73 cmp $0x0, %eax # any function > 0?101 cmp $0x0, %eax /* any function > 0? */ 74 102 jbe pse_unsupported 75 103 … … 80 108 81 109 pse_unsupported: 82 movl $pse_msg, %esi83 jmp error_halt110 111 pm_error $err_pse 84 112 85 113 pse_supported: 86 114 87 bt $(INTEL_SEP), %edx88 jc sep_supported89 90 movl $sep_msg, %esi91 jmp error_halt92 93 sep_supported:94 95 115 #include "vesa_prot.inc" 96 97 # map kernel and turn paging on116 117 /* Map kernel and turn paging on */ 98 118 call map_kernel 99 119 100 # call arch_pre_main(grub_eax, grub_ebx) 120 /* Create the first stack frame */ 121 pushl $0 122 movl %esp, %ebp 123 124 pm2_status $status_prot2 125 126 /* Call arch_pre_main(grub_eax, grub_ebx) */ 101 127 pushl grub_ebx 102 128 pushl grub_eax 103 129 call arch_pre_main 104 130 131 pm2_status $status_main 132 133 /* Call main_bsp() */ 105 134 call main_bsp 106 135 107 # not reached136 /* Not reached */ 108 137 cli 109 138 hlt0: … … 111 140 jmp hlt0 112 141 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 */ 113 148 .global map_kernel 114 149 map_kernel: 115 #116 # Here we setup mapping for both the unmapped and mapped sections of the kernel.117 # For simplicity, we map the entire 4G space.118 #119 150 movl %cr4, %ecx 120 orl $(1 << 4), %ecx # turn PSE on121 andl $(~(1 << 5)), %ecx # turn PAE off151 orl $(1 << 4), %ecx /* PSE on */ 152 andl $(~(1 << 5)), %ecx /* PAE off */ 122 153 movl %ecx, %cr4 123 154 … … 130 161 movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax 131 162 orl %ebx, %eax 132 movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M 133 movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M 163 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */ 164 movl %eax, (%esi, %ecx, 4) 165 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */ 166 movl %eax, (%edi, %ecx, 4) 134 167 addl $(4 * 1024 * 1024), %ebx 135 168 … … 141 174 142 175 movl %cr0, %ebx 143 orl $(1 << 31), %ebx # turn paging on176 orl $(1 << 31), %ebx /* paging on */ 144 177 movl %ebx, %cr0 145 178 ret 146 179 147 # Print string from %esi to EGA display (in red) and halt 148 error_halt: 149 movl $0xb8000, %edi # base of EGA text mode memory 180 /** Print string to EGA display (in light red) and halt. 181 * 182 * Should be executed from 32 bit protected mode with paging 183 * turned off. Stack is not required. This routine is used even 184 * if CONFIG_EGA is not enabled. Since we are going to halt the 185 * CPU anyway, it is always better to at least try to print 186 * some hints. 187 * 188 * @param %esi NULL-terminated string to print. 189 * 190 */ 191 pm_error_halt: 192 movl $0xb8000, %edi /* base of EGA text mode memory */ 150 193 xorl %eax, %eax 151 194 152 movw $0x3d4, %dx # read bits 8 - 15 of the cursor address 195 /* Read bits 8 - 15 of the cursor address */ 196 movw $0x3d4, %dx 153 197 movb $0xe, %al 154 198 outb %al, %dx … … 158 202 shl $8, %ax 159 203 160 movw $0x3d4, %dx # read bits 0 - 7 of the cursor address 204 /* Read bits 0 - 7 of the cursor address */ 205 movw $0x3d4, %dx 161 206 movb $0xf, %al 162 207 outb %al, %dx … … 165 210 inb %dx, %al 166 211 167 cmp $1920, %ax 168 jbe cursor_ok 169 170 movw $1920, %ax # sanity check for the cursor on the last line 171 172 cursor_ok: 212 /* Sanity check for the cursor on screen */ 213 cmp $2000, %ax 214 jb err_cursor_ok 215 216 movw $1998, %ax 217 218 err_cursor_ok: 173 219 174 220 movw %ax, %bx … … 176 222 addl %eax, %edi 177 223 178 movw $0x0c00, %ax # black background, light red foreground 179 180 ploop: 224 err_ploop: 181 225 lodsb 226 182 227 cmp $0, %al 183 je ploop_end 228 je err_ploop_end 229 230 movb $0x0c, %ah /* black background, light red foreground */ 184 231 stosw 232 233 /* Sanity check for the cursor on the last line */ 185 234 inc %bx 186 jmp ploop 187 ploop_end: 188 189 movw $0x3d4, %dx # write bits 8 - 15 of the cursor address 235 cmp $2000, %bx 236 jb err_ploop 237 238 /* Scroll the screen (24 rows) */ 239 movl %esi, %edx 240 movl $0xb80a0, %esi 241 movl $0xb8000, %edi 242 movl $960, %ecx 243 rep movsl 244 245 /* Clear the 24th row */ 246 xorl %eax, %eax 247 movl $40, %ecx 248 rep stosl 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 190 260 movb $0xe, %al 191 261 outb %al, %dx … … 195 265 outb %al, %dx 196 266 197 movw $0x3d4, %dx # write bits 0 - 7 of the cursor address 267 /* Write bits 0 - 7 of the cursor address */ 268 movw $0x3d4, %dx 198 269 movb $0xf, %al 199 270 outb %al, %dx … … 208 279 jmp hlt1 209 280 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 $960, %ecx 351 rep movsl 352 353 /* Clear the 24th row */ 354 xorl %eax, %eax 355 movl $40, %ecx 356 rep stosl 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 $960, %ecx 466 rep movsl 467 468 /* Clear the 24th row */ 469 xorl %eax, %eax 470 movl $40, %ecx 471 rep stosl 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 210 509 #include "vesa_real.inc" 211 510 … … 216 515 .space 4096, 0 217 516 517 bootstrap_gdtr: 518 .word GDT_SELECTOR(GDT_ITEMS) 519 .long KA2PA(gdt) 520 218 521 grub_eax: 219 522 .long 0 … … 222 525 .long 0 223 526 224 pse_msg:527 err_pse: 225 528 .asciz "Page Size Extension not supported. System halted." 226 529 227 sep_msg: 228 .asciz "SYSENTER/SYSEXIT not supported. System halted." 530 status_prot: 531 .asciz "[prot] " 532 status_vesa_copy: 533 .asciz "[vesa_copy] " 534 status_grub_cmdline: 535 .asciz "[grub_cmdline] " 536 status_vesa_real: 537 .asciz "[vesa_real] " 538 status_prot2: 539 .asciz "[prot2] " 540 status_main: 541 .asciz "[main] " -
kernel/arch/ia32/src/boot/memmap.c
rb50b5af2 r04803bf 35 35 #include <arch/boot/memmap.h> 36 36 37 uint8_t e820counter = 0xff ;37 uint8_t e820counter = 0xffU; 38 38 e820memmap_t e820table[MEMMAP_E820_MAX_RECORDS]; 39 39 -
kernel/arch/ia32/src/boot/vesa_prot.inc
rb50b5af2 r04803bf 5 5 #define MBINFO_OFFSET_CMDLINE 16 6 6 7 # copy real mode VESA initialization code 7 /* Copy real mode VESA initialization code */ 8 9 pm_status $status_vesa_copy 8 10 9 11 mov $vesa_init, %esi … … 12 14 rep movsb 13 15 14 # check for GRUB command line 16 /* Check for GRUB command line */ 17 18 pm_status $status_grub_cmdline 15 19 16 20 mov grub_eax, %eax … … 23 27 jnc no_cmdline 24 28 25 # skip the kernel path in command line29 /* Skip the kernel path in command line */ 26 30 27 31 mov MBINFO_OFFSET_CMDLINE(%ebx), %esi … … 52 56 space_loop_done: 53 57 54 # copy at most 23 characters from command line58 /* Copy at most 23 characters from command line */ 55 59 56 60 mov $VESA_INIT_SEGMENT << 4, %edi … … 68 72 cmd_loop_done: 69 73 70 # zero termination74 /* Zero termination */ 71 75 72 76 xor %eax, %eax … … 75 79 no_cmdline: 76 80 77 # jump to the real mode 81 /* Jump to the real mode */ 82 83 pm_status $status_vesa_real 78 84 79 85 mov $VESA_INIT_SEGMENT << 4, %edi … … 81 87 82 88 vesa_meeting_point: 83 # returned back to protected mode89 /* Returned back to protected mode */ 84 90 85 91 mov %ax, KA2PA(vesa_scanline) -
kernel/arch/ia32/src/boot/vesa_real.inc
rb50b5af2 r04803bf 30 30 .code32 31 31 vesa_init: 32 jmp $ gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init33 32 jmp $GDT_SELECTOR(VESA_INIT_DES), $vesa_init_real - vesa_init 33 34 34 .code16 35 35 vesa_init_real: … … 55 55 pushl %eax 56 56 57 # parse default mode string57 /* Parse default mode string */ 58 58 59 59 mov $default_mode - vesa_init, %di … … 65 65 mov (%di), %al 66 66 67 # check for digit67 /* 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 digit77 /* 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 digit98 /* 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 digit108 /* 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 digit129 /* 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 digit139 /* 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 169 /* Try next mode */ 170 170 171 mov %gs:(%si), %cx 171 172 cmp $VESA_END_OF_MODES, %cx … … 186 187 jne no_mode 187 188 188 # check for proper attributes (supported, color, graphics, linear framebuffer) 189 /* 190 * Check for proper attributes (supported, 191 * color, graphics, linear framebuffer). 192 */ 189 193 190 194 mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax … … 193 197 jne next_mode 194 198 195 # check for proper resolution199 /* Check for proper resolution */ 196 200 197 201 mov default_width - vesa_init, %ax … … 203 207 jne next_mode 204 208 205 # check for proper bpp209 /* Check for proper bpp */ 206 210 207 211 mov default_bpp - vesa_init, %al … … 213 217 jne next_mode 214 218 215 # for 24 bpp modes accept also 32 bit bpp219 /* For 24 bpp modes accept also 32 bit bpp */ 216 220 217 221 mov $32, %al … … 230 234 jnz no_mode 231 235 232 # set 3:2:3 VGA palette236 /* Set 3:2:3 VGA palette */ 233 237 234 238 mov VESA_MODE_BPP_OFFSET(%di), %al … … 241 245 mov $0x100, %ecx 242 246 243 bt $5, %ax # test if VGA compatible registers are present 247 /* Test if VGA compatible registers are present */ 248 bt $5, %ax 244 249 jnc vga_compat 245 250 246 # try VESA routine to set palette 251 /* Use VESA routine to set the palette */ 252 247 253 mov $VESA_SET_PALETTE, %ax 248 254 xor %bl, %bl … … 254 260 255 261 vga_compat: 256 # try VGA registers to set palette 257 movw $0x3c6, %dx # set palette mask 262 263 /* Use VGA registers to set the palette */ 264 265 movw $0x3c6, %dx /* set palette mask */ 258 266 movb $0xff, %al 259 267 outb %al, %dx 260 268 261 movw $0x3c8, %dx # first index to set269 movw $0x3c8, %dx /* first index to set */ 262 270 xor %al, %al 263 271 outb %al, %dx 264 272 265 movw $0x3c9, %dx # data port273 movw $0x3c9, %dx /* data port */ 266 274 267 275 vga_loop: … … 284 292 vga_not_set: 285 293 286 # store mode parameters 287 # eax = bpp[8] scanline[16] 288 # ebx = width[16] height[16] 289 # edx = red_mask[8] red_pos[8] green_mask[8] green_pos[8] 290 # esi = blue_mask[8] blue_pos[8] 291 # edi = linear frame buffer 294 /* 295 * Store mode parameters: 296 * eax = bpp[8] scanline[16] 297 * ebx = width[16] height[16] 298 * edx = red_mask[8] red_pos[8] green_mask[8] green_pos[8] 299 * esi = blue_mask[8] blue_pos[8] 300 * edi = linear frame buffer 301 */ 292 302 293 303 mov VESA_MODE_BPP_OFFSET(%di), %al … … 325 335 vesa_leave_real2: 326 336 327 ljmpl $ gdtselector(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4)337 ljmpl $GDT_SELECTOR(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4) 328 338 329 339 no_mode: 330 # no prefered mode found 340 341 /* No prefered mode found */ 342 331 343 mov $0x111, %cx 332 344 push %di … … 339 351 cmp $VESA_OK, %al 340 352 jnz text_mode 341 jz set_mode # force relative jump353 jz set_mode /* force relative jump */ 342 354 343 355 text_mode: 344 # reset to EGA text mode (because of problems with VESA) 356 357 /* Reset to EGA text mode (because of problems with VESA) */ 358 345 359 mov $0x0003, %ax 346 360 int $0x10 347 361 mov $0xffffffff, %edi 348 362 xor %ax, %ax 349 jz vesa_leave_real # force relative jump363 jz vesa_leave_real /* force relative jump */ 350 364 351 365 vga323: -
kernel/arch/ia32/src/boot/vesa_ret.inc
rb50b5af2 r04803bf 1 1 .code32 2 2 vesa_init_protected: 3 movw $gdtselector(KDATA_DES), %cx 3 cld 4 5 /* Initialize stack pointer */ 6 movl $START_STACK, %esp 7 8 /* Kernel data + stack */ 9 movw $GDT_SELECTOR(KDATA_DES), %cx 4 10 movw %cx, %es 5 11 movw %cx, %fs 6 12 movw %cx, %gs 7 movw %cx, %ds # kernel data + stack13 movw %cx, %ds 8 14 movw %cx, %ss 9 15 10 movl $START_STACK, %esp # initialize stack pointer 11 12 jmpl $gdtselector(KTEXT_DES), $vesa_meeting_point 16 jmpl $GDT_SELECTOR(KTEXT_DES), $vesa_meeting_point -
kernel/arch/ia32/src/cpu/cpu.c
rb50b5af2 r04803bf 38 38 39 39 #include <arch.h> 40 #include < arch/types.h>40 #include <typedefs.h> 41 41 #include <print.h> 42 42 #include <fpu_context.h> … … 49 49 * Contains only non-MP-Specification specific SMP code. 50 50 */ 51 #define AMD_CPUID_EBX 0x6874754152 #define AMD_CPUID_ECX 0x444d416353 #define AMD_CPUID_EDX 0x69746e6551 #define AMD_CPUID_EBX UINT32_C(0x68747541) 52 #define AMD_CPUID_ECX UINT32_C(0x444d4163) 53 #define AMD_CPUID_EDX UINT32_C(0x69746e65) 54 54 55 #define INTEL_CPUID_EBX 0x756e654756 #define INTEL_CPUID_ECX 0x6c65746e57 #define INTEL_CPUID_EDX 0x49656e6955 #define INTEL_CPUID_EBX UINT32_C(0x756e6547) 56 #define INTEL_CPUID_ECX UINT32_C(0x6c65746e) 57 #define INTEL_CPUID_EDX UINT32_C(0x49656e69) 58 58 59 59 … … 64 64 }; 65 65 66 static c har *vendor_str[] = {66 static const char *vendor_str[] = { 67 67 "Unknown Vendor", 68 68 "AMD", … … 92 92 void cpu_arch_init(void) 93 93 { 94 cpuid_feature_info fi;95 94 cpuid_extended_feature_info efi; 96 95 cpu_info_t info; … … 102 101 CPU->fpu_owner = NULL; 103 102 104 cpuid( 1, &info);103 cpuid(INTEL_CPUID_STANDARD, &info); 105 104 106 fi.word = info.cpuid_edx;105 CPU->arch.fi.word = info.cpuid_edx; 107 106 efi.word = info.cpuid_ecx; 108 107 109 if ( fi.bits.fxsr)108 if (CPU->arch.fi.bits.fxsr) 110 109 fpu_fxsr(); 111 110 else 112 111 fpu_fsr(); 113 112 114 if ( fi.bits.sse) {113 if (CPU->arch.fi.bits.sse) { 115 114 asm volatile ( 116 115 "mov %%cr4, %[help]\n" … … 122 121 } 123 122 124 /* Setup fast SYSENTER/SYSEXIT syscalls */ 125 syscall_setup_cpu(); 123 if (CPU->arch.fi.bits.sep) { 124 /* Setup fast SYSENTER/SYSEXIT syscalls */ 125 syscall_setup_cpu(); 126 } 126 127 } 127 128 … … 132 133 CPU->arch.vendor = VendorUnknown; 133 134 if (has_cpuid()) { 134 cpuid( 0, &info);135 cpuid(INTEL_CPUID_LEVEL, &info); 135 136 136 137 /* … … 139 140 if ((info.cpuid_ebx == AMD_CPUID_EBX) 140 141 && (info.cpuid_ecx == AMD_CPUID_ECX) 141 && (info.cpuid_edx == AMD_CPUID_EDX))142 && (info.cpuid_edx == AMD_CPUID_EDX)) 142 143 CPU->arch.vendor = VendorAMD; 143 144 144 145 /* 145 146 * Check for Intel processor. 146 */ 147 */ 147 148 if ((info.cpuid_ebx == INTEL_CPUID_EBX) 148 149 && (info.cpuid_ecx == INTEL_CPUID_ECX) 149 && (info.cpuid_edx == INTEL_CPUID_EDX))150 && (info.cpuid_edx == INTEL_CPUID_EDX)) 150 151 CPU->arch.vendor = VendorIntel; 151 152 152 cpuid( 1, &info);153 CPU->arch.family = (info.cpuid_eax >> 8) & 0x0f ;154 CPU->arch.model = (info.cpuid_eax >> 4) & 0x0f ;155 CPU->arch.stepping = (info.cpuid_eax >> 0) & 0x0f ;153 cpuid(INTEL_CPUID_STANDARD, &info); 154 CPU->arch.family = (info.cpuid_eax >> 8) & 0x0fU; 155 CPU->arch.model = (info.cpuid_eax >> 4) & 0x0fU; 156 CPU->arch.stepping = (info.cpuid_eax >> 0) & 0x0fU; 156 157 } 157 158 } -
kernel/arch/ia32/src/ddi/ddi.c
rb50b5af2 r04803bf 36 36 #include <arch/ddi/ddi.h> 37 37 #include <proc/task.h> 38 #include < arch/types.h>38 #include <typedefs.h> 39 39 #include <adt/bitmap.h> 40 40 #include <mm/slab.h> … … 50 50 * Interrupts are disabled and task is locked. 51 51 * 52 * @param task Task.52 * @param task Task. 53 53 * @param ioaddr Startign I/O space address. 54 * @param size Size of the enabled I/O range.54 * @param size Size of the enabled I/O range. 55 55 * 56 56 * @return 0 on success or an error code from errno.h. 57 * 57 58 */ 58 59 int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size) 59 60 { 60 size_t bits; 61 62 bits = ioaddr + size; 61 size_t bits = ioaddr + size; 63 62 if (bits > IO_PORTS) 64 63 return ENOENT; 65 64 66 65 if (task->arch.iomap.bits < bits) { 67 bitmap_t oldiomap;68 uint8_t *newmap;69 70 66 /* 71 67 * The I/O permission bitmap is too small and needs to be grown. 72 68 */ 73 69 74 newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);70 uint8_t *newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC); 75 71 if (!newmap) 76 72 return ENOMEM; 77 73 74 bitmap_t oldiomap; 78 75 bitmap_initialize(&oldiomap, task->arch.iomap.map, 79 76 task->arch.iomap.bits); 80 77 bitmap_initialize(&task->arch.iomap, newmap, bits); 81 78 82 79 /* 83 80 * Mark the new range inaccessible. … … 85 82 bitmap_set_range(&task->arch.iomap, oldiomap.bits, 86 83 bits - oldiomap.bits); 87 84 88 85 /* 89 86 * In case there really existed smaller iomap, 90 87 * copy its contents and deallocate it. 91 */ 88 */ 92 89 if (oldiomap.bits) { 93 90 bitmap_copy(&task->arch.iomap, &oldiomap, … … 96 93 } 97 94 } 98 95 99 96 /* 100 97 * Enable the range and we are done. 101 98 */ 102 99 bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size); 103 100 104 101 /* 105 102 * Increment I/O Permission bitmap generation counter. 106 103 */ 107 104 task->arch.iomapver++; 108 105 109 106 return 0; 110 107 } … … 116 113 * 117 114 * Interrupts must be disabled prior this call. 115 * 118 116 */ 119 117 void io_perm_bitmap_install(void) 120 118 { 121 size_t bits;122 ptr_16_32_t cpugdtr;123 descriptor_t *gdt_p;124 size_t ver;125 126 119 /* First, copy the I/O Permission Bitmap. */ 127 spinlock_lock(&TASK->lock); 128 ver = TASK->arch.iomapver; 129 if ((bits = TASK->arch.iomap.bits)) { 120 irq_spinlock_lock(&TASK->lock, false); 121 size_t ver = TASK->arch.iomapver; 122 size_t bits = TASK->arch.iomap.bits; 123 if (bits) { 124 ASSERT(TASK->arch.iomap.map); 125 130 126 bitmap_t iomap; 131 task_t *task = TASK;132 133 ASSERT(TASK->arch.iomap.map);134 127 bitmap_initialize(&iomap, CPU->arch.tss->iomap, 135 128 TSS_IOMAP_SIZE * 8); 136 bitmap_copy(&iomap, &task->arch.iomap, task->arch.iomap.bits); 129 bitmap_copy(&iomap, &TASK->arch.iomap, bits); 130 131 /* 132 * Set the trailing bits in the last byte of the map to disable 133 * I/O access. 134 */ 135 bitmap_set_range(&iomap, bits, ALIGN_UP(bits, 8) - bits); 137 136 /* 138 137 * It is safe to set the trailing eight bits because of the 139 138 * extra convenience byte in TSS_IOMAP_SIZE. 140 139 */ 141 bitmap_set_range(&iomap, ALIGN_UP( TASK->arch.iomap.bits, 8), 8);140 bitmap_set_range(&iomap, ALIGN_UP(bits, 8), 8); 142 141 } 143 spinlock_unlock(&TASK->lock);144 142 irq_spinlock_unlock(&TASK->lock, false); 143 145 144 /* 146 145 * Second, adjust TSS segment limit. 147 146 * Take the extra ending byte with all bits set into account. 148 147 */ 148 ptr_16_32_t cpugdtr; 149 149 gdtr_store(&cpugdtr); 150 gdt_p = (descriptor_t *) cpugdtr.base; 150 151 descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base; 151 152 gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits)); 152 153 gdtr_load(&cpugdtr); 153 154 154 155 /* 155 156 * Before we load new TSS limit, the current TSS descriptor … … 157 158 */ 158 159 gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL; 159 tr_load( gdtselector(TSS_DES));160 tr_load(GDT_SELECTOR(TSS_DES)); 160 161 161 162 /* -
kernel/arch/ia32/src/drivers/i8254.c
rb50b5af2 r04803bf 37 37 */ 38 38 39 #include < arch/types.h>39 #include <typedefs.h> 40 40 #include <time/clock.h> 41 41 #include <time/delay.h> … … 54 54 #include <ddi/device.h> 55 55 56 #define CLK_PORT1 ((ioport8_t *)0x40)57 #define CLK_PORT4 ((ioport8_t *)0x43)56 #define CLK_PORT1 ((ioport8_t *) 0x40U) 57 #define CLK_PORT4 ((ioport8_t *) 0x43U) 58 58 59 #define CLK_CONST 1193180 60 #define MAGIC_NUMBER 1194 59 #define CLK_CONST 1193180 60 #define MAGIC_NUMBER 1194 61 62 #define LOOPS 150000 63 #define SHIFT 11 61 64 62 65 static irq_t i8254_irq; … … 75 78 * lock. We just release it, call clock() and then reacquire it again. 76 79 */ 77 spinlock_unlock(&irq->lock);80 irq_spinlock_unlock(&irq->lock, false); 78 81 clock(); 79 spinlock_lock(&irq->lock);82 irq_spinlock_lock(&irq->lock, false); 80 83 } 81 84 … … 102 105 } 103 106 104 #define LOOPS 150000105 #define SHIFT 11106 107 void i8254_calibrate_delay_loop(void) 107 108 { 108 uint64_t clk1, clk2;109 uint32_t t1, t2, o1, o2;110 uint8_t not_ok;111 112 113 109 /* 114 110 * One-shot timer. Count-down from 0xffff at 1193180Hz … … 118 114 pio_write_8(CLK_PORT1, 0xff); 119 115 pio_write_8(CLK_PORT1, 0xff); 120 116 117 uint8_t not_ok; 118 uint32_t t1; 119 uint32_t t2; 120 121 121 do { 122 122 /* will read both status and count */ … … 126 126 t1 |= pio_read_8(CLK_PORT1) << 8; 127 127 } while (not_ok); 128 128 129 129 asm_delay_loop(LOOPS); 130 130 131 131 pio_write_8(CLK_PORT4, 0xd2); 132 132 t2 = pio_read_8(CLK_PORT1); 133 133 t2 |= pio_read_8(CLK_PORT1) << 8; 134 134 135 135 /* 136 136 * We want to determine the overhead of the calibrating mechanism. 137 137 */ 138 138 pio_write_8(CLK_PORT4, 0xd2); 139 o1 = pio_read_8(CLK_PORT1);139 uint32_t o1 = pio_read_8(CLK_PORT1); 140 140 o1 |= pio_read_8(CLK_PORT1) << 8; 141 141 142 142 asm_fake_loop(LOOPS); 143 143 144 144 pio_write_8(CLK_PORT4, 0xd2); 145 o2 = pio_read_8(CLK_PORT1);145 uint32_t o2 = pio_read_8(CLK_PORT1); 146 146 o2 |= pio_read_8(CLK_PORT1) << 8; 147 147 148 148 CPU->delay_loop_const = 149 149 ((MAGIC_NUMBER * LOOPS) / 1000) / ((t1 - t2) - (o1 - o2)) + 150 150 (((MAGIC_NUMBER * LOOPS) / 1000) % ((t1 - t2) - (o1 - o2)) ? 1 : 0); 151 152 clk1 = get_cycle();151 152 uint64_t clk1 = get_cycle(); 153 153 delay(1 << SHIFT); 154 clk2 = get_cycle();154 uint64_t clk2 = get_cycle(); 155 155 156 156 CPU->frequency_mhz = (clk2 - clk1) >> SHIFT; 157 157 158 158 return; 159 159 } -
kernel/arch/ia32/src/drivers/i8259.c
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 39 39 #include <arch/drivers/i8259.h> 40 40 #include <cpu.h> 41 #include < arch/types.h>41 #include <typedefs.h> 42 42 #include <arch/asm.h> 43 43 #include <arch.h> … … 45 45 #include <interrupt.h> 46 46 47 static void pic_spurious( int n, istate_t *istate);47 static void pic_spurious(unsigned int n, istate_t *istate); 48 48 49 49 void i8259_init(void) … … 76 76 * Register interrupt handler for the PIC spurious interrupt. 77 77 */ 78 exc_register(VECTOR_PIC_SPUR, "pic_spurious", (iroutine) pic_spurious); 78 exc_register(VECTOR_PIC_SPUR, "pic_spurious", false, 79 (iroutine_t) pic_spurious); 79 80 80 81 /* … … 85 86 disable_irqs_function = pic_disable_irqs; 86 87 eoi_function = pic_eoi; 88 irqs_info = "i8259"; 87 89 88 90 pic_disable_irqs(0xffff); /* disable all irq's */ … … 120 122 void pic_eoi(void) 121 123 { 122 pio_write_8((ioport8_t *) 0x20, 0x20);123 pio_write_8((ioport8_t *) 0xa0, 0x20);124 pio_write_8((ioport8_t *) 0x20, 0x20); 125 pio_write_8((ioport8_t *) 0xa0, 0x20); 124 126 } 125 127 126 void pic_spurious( int n __attribute__((unused)), istate_t *istate __attribute__((unused)))128 void pic_spurious(unsigned int n __attribute__((unused)), istate_t *istate __attribute__((unused))) 127 129 { 128 130 #ifdef CONFIG_DEBUG -
kernel/arch/ia32/src/drivers/vesa.c
rb50b5af2 r04803bf 49 49 #include <synch/spinlock.h> 50 50 #include <arch/asm.h> 51 #include < arch/types.h>51 #include <typedefs.h> 52 52 #include <memstr.h> 53 53 #include <bitops.h> … … 70 70 bool vesa_init(void) 71 71 { 72 if ((vesa_width == 0xffff ) || (vesa_height == 0xffff))72 if ((vesa_width == 0xffffU) || (vesa_height == 0xffffU)) 73 73 return false; 74 74 -
kernel/arch/ia32/src/ia32.c
rb50b5af2 r04803bf 37 37 #include <arch.h> 38 38 39 #include < arch/types.h>39 #include <typedefs.h> 40 40 41 41 #include <arch/pm.h> … … 68 68 #include <sysinfo/sysinfo.h> 69 69 #include <arch/boot/boot.h> 70 #include <memstr.h> 70 71 71 72 #ifdef CONFIG_SMP … … 138 139 { 139 140 #ifdef CONFIG_SMP 140 if (config.cpu_active > 1) {141 if (config.cpu_active > 1) { 141 142 l_apic_init(); 142 143 l_apic_debug(); … … 156 157 void arch_post_smp_init(void) 157 158 { 159 /* Currently the only supported platform for ia32 is 'pc'. */ 160 static const char *platform = "pc"; 161 162 sysinfo_set_item_data("platform", NULL, (void *) platform, 163 str_size(platform)); 164 158 165 #ifdef CONFIG_PC_KBD 159 166 /* … … 169 176 i8042_wire(i8042_instance, kbrd); 170 177 trap_virtual_enable_irqs(1 << IRQ_KBD); 178 trap_virtual_enable_irqs(1 << IRQ_MOUSE); 171 179 } 172 180 } … … 176 184 * self-sufficient. 177 185 */ 178 sysinfo_set_item_val("kbd", NULL, true); 179 sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD); 180 sysinfo_set_item_val("kbd.address.physical", NULL, 186 sysinfo_set_item_val("i8042", NULL, true); 187 sysinfo_set_item_val("i8042.inr_a", NULL, IRQ_KBD); 188 sysinfo_set_item_val("i8042.inr_b", NULL, IRQ_MOUSE); 189 sysinfo_set_item_val("i8042.address.physical", NULL, 181 190 (uintptr_t) I8042_BASE); 182 sysinfo_set_item_val(" kbd.address.kernel", NULL,191 sysinfo_set_item_val("i8042.address.kernel", NULL, 183 192 (uintptr_t) I8042_BASE); 184 193 #endif 194 195 if (irqs_info != NULL) 196 sysinfo_set_item_val(irqs_info, NULL, true); 197 198 sysinfo_set_item_val("netif.ne2000.inr", NULL, IRQ_NE2000); 185 199 } 186 200 … … 202 216 * selector, and the descriptor->base is the correct address. 203 217 */ 204 unative_t sys_tls_set(unative_t addr)218 sysarg_t sys_tls_set(sysarg_t addr) 205 219 { 206 220 THREAD->arch.tls = addr; … … 231 245 } 232 246 247 void irq_initialize_arch(irq_t *irq) 248 { 249 (void) irq; 250 } 251 233 252 /** @} 234 253 */ -
kernel/arch/ia32/src/interrupt.c
rb50b5af2 r04803bf 53 53 #include <ddi/irq.h> 54 54 #include <symtab.h> 55 #include <stacktrace.h> 55 56 56 57 /* … … 61 62 void (* enable_irqs_function)(uint16_t irqmask) = NULL; 62 63 void (* eoi_function)(void) = NULL; 63 64 void decode_istate(istate_t *istate) 65 { 66 char *symbol; 67 68 symbol = symtab_fmt_name_lookup(istate->eip); 69 70 if (CPU) 71 printf("----------------EXCEPTION OCCURED (cpu%u)----------------\n", CPU->id); 72 else 73 printf("----------------EXCEPTION OCCURED----------------\n"); 74 75 printf("%%eip: %#lx (%s)\n", istate->eip, symbol); 76 printf("ERROR_WORD=%#lx\n", istate->error_word); 77 printf("%%cs=%#lx,flags=%#lx\n", istate->cs, istate->eflags); 78 printf("%%eax=%#lx, %%ecx=%#lx, %%edx=%#lx, %%esp=%p\n", istate->eax, istate->ecx, istate->edx, &istate->stack[0]); 79 printf("stack: %#lx, %#lx, %#lx, %#lx\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]); 80 printf(" %#lx, %#lx, %#lx, %#lx\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]); 64 const char *irqs_info = NULL; 65 66 void istate_decode(istate_t *istate) 67 { 68 printf("cs =%#0" PRIx32 "\teip=%p\t" 69 "efl=%#0" PRIx32 "\terr=%#0" PRIx32 "\n", 70 istate->cs, (void *) istate->eip, 71 istate->eflags, istate->error_word); 72 73 printf("ds =%#0" PRIx32 "\tes =%#0" PRIx32 "\t" 74 "fs =%#0" PRIx32 "\tgs =%#0" PRIx32 "\n", 75 istate->ds, istate->es, istate->fs, istate->gs); 76 77 if (istate_from_uspace(istate)) 78 printf("ss =%#0" PRIx32 "\n", istate->ss); 79 80 printf("eax=%#0" PRIx32 "\tebx=%#0" PRIx32 "\t" 81 "ecx=%#0" PRIx32 "\tedx=%#0" PRIx32 "\n", 82 istate->eax, istate->ebx, istate->ecx, istate->edx); 83 84 printf("esi=%p\tedi=%p\tebp=%p\tesp=%p\n", 85 (void *) istate->esi, (void *) istate->edi, 86 (void *) istate->ebp, 87 istate_from_uspace(istate) ? ((void *) istate->esp) : 88 &istate->esp); 81 89 } 82 90 … … 90 98 } 91 99 92 static void null_interrupt(int n, istate_t *istate) 93 { 94 fault_if_from_uspace(istate, "Unserviced interrupt: %d.", n); 95 96 decode_istate(istate); 97 panic("Unserviced interrupt: %d.", n); 100 static void null_interrupt(unsigned int n, istate_t *istate) 101 { 102 fault_if_from_uspace(istate, "Unserviced interrupt: %u.", n); 103 panic_badtrap(istate, n, "Unserviced interrupt: %u.", n); 104 } 105 106 static void de_fault(unsigned int n, istate_t *istate) 107 { 108 fault_if_from_uspace(istate, "Divide error."); 109 panic_badtrap(istate, n, "Divide error."); 98 110 } 99 111 100 112 /** General Protection Fault. */ 101 static void gp_fault( int n __attribute__((unused)), istate_t *istate)113 static void gp_fault(unsigned int n __attribute__((unused)), istate_t *istate) 102 114 { 103 115 if (TASK) { 104 size_t ver; 116 irq_spinlock_lock(&TASK->lock, false); 117 size_t ver = TASK->arch.iomapver; 118 irq_spinlock_unlock(&TASK->lock, false); 105 119 106 spinlock_lock(&TASK->lock);107 ver = TASK->arch.iomapver;108 spinlock_unlock(&TASK->lock);109 110 120 if (CPU->arch.iomapver_copy != ver) { 111 121 /* … … 121 131 fault_if_from_uspace(istate, "General protection fault."); 122 132 } 123 124 decode_istate(istate); 125 panic("General protection fault."); 126 } 127 128 static void ss_fault(int n __attribute__((unused)), istate_t *istate) 133 panic_badtrap(istate, n, "General protection fault."); 134 } 135 136 static void ss_fault(unsigned int n __attribute__((unused)), istate_t *istate) 129 137 { 130 138 fault_if_from_uspace(istate, "Stack fault."); 131 132 decode_istate(istate); 133 panic("Stack fault."); 134 } 135 136 static void simd_fp_exception(int n __attribute__((unused)), istate_t *istate) 139 panic_badtrap(istate, n, "Stack fault."); 140 } 141 142 static void simd_fp_exception(unsigned int n __attribute__((unused)), istate_t *istate) 137 143 { 138 144 uint32_t mxcsr; 139 asm (145 asm volatile ( 140 146 "stmxcsr %[mxcsr]\n" 141 147 : [mxcsr] "=m" (mxcsr) 142 148 ); 143 fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx.", 144 (unative_t) mxcsr); 145 146 decode_istate(istate); 147 printf("MXCSR: %#lx\n", mxcsr); 148 panic("SIMD FP exception(19)."); 149 } 150 151 static void nm_fault(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) 152 { 153 #ifdef CONFIG_FPU_LAZY 149 150 fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR=%#0" PRIx32 ".", 151 mxcsr); 152 panic_badtrap(istate, n, "SIMD FP exception"); 153 } 154 155 static void nm_fault(unsigned int n __attribute__((unused)), 156 istate_t *istate __attribute__((unused))) 157 { 158 #ifdef CONFIG_FPU_LAZY 154 159 scheduler_fpu_lazy_request(); 155 160 #else 156 161 fault_if_from_uspace(istate, "FPU fault."); 157 panic ("FPU fault.");162 panic_badtrap(istate, n, "FPU fault."); 158 163 #endif 159 164 } 160 165 161 166 #ifdef CONFIG_SMP 162 static void tlb_shootdown_ipi(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) 167 static void tlb_shootdown_ipi(unsigned int n __attribute__((unused)), 168 istate_t *istate __attribute__((unused))) 163 169 { 164 170 trap_virtual_eoi(); … … 168 174 169 175 /** Handler of IRQ exceptions */ 170 static void irq_interrupt( int n, istate_t *istate __attribute__((unused)))176 static void irq_interrupt(unsigned int n, istate_t *istate __attribute__((unused))) 171 177 { 172 178 ASSERT(n >= IVT_IRQBASE); 173 179 174 int inum = n - IVT_IRQBASE;180 unsigned int inum = n - IVT_IRQBASE; 175 181 bool ack = false; 176 182 ASSERT(inum < IRQ_COUNT); … … 182 188 * The IRQ handler was found. 183 189 */ 184 190 185 191 if (irq->preack) { 186 192 /* Send EOI before processing the interrupt */ … … 189 195 } 190 196 irq->handler(irq); 191 spinlock_unlock(&irq->lock);197 irq_spinlock_unlock(&irq->lock, false); 192 198 } else { 193 199 /* … … 195 201 */ 196 202 #ifdef CONFIG_DEBUG 197 printf("cpu%u: spurious interrupt (inum=% d)\n", CPU->id, inum);203 printf("cpu%u: spurious interrupt (inum=%u)\n", CPU->id, inum); 198 204 #endif 199 205 } … … 205 211 void interrupt_init(void) 206 212 { 207 int i;213 unsigned int i; 208 214 209 215 for (i = 0; i < IVT_ITEMS; i++) 210 exc_register(i, "null", (iroutine) null_interrupt);216 exc_register(i, "null", false, (iroutine_t) null_interrupt); 211 217 212 218 for (i = 0; i < IRQ_COUNT; i++) { 213 219 if ((i != IRQ_PIC_SPUR) && (i != IRQ_PIC1)) 214 exc_register(IVT_IRQBASE + i, "irq", (iroutine) irq_interrupt); 220 exc_register(IVT_IRQBASE + i, "irq", true, 221 (iroutine_t) irq_interrupt); 215 222 } 216 223 217 exc_register(7, "nm_fault", (iroutine) nm_fault); 218 exc_register(12, "ss_fault", (iroutine) ss_fault); 219 exc_register(13, "gp_fault", (iroutine) gp_fault); 220 exc_register(19, "simd_fp", (iroutine) simd_fp_exception); 224 exc_register(0, "de_fault", true, (iroutine_t) de_fault); 225 exc_register(7, "nm_fault", true, (iroutine_t) nm_fault); 226 exc_register(12, "ss_fault", true, (iroutine_t) ss_fault); 227 exc_register(13, "gp_fault", true, (iroutine_t) gp_fault); 228 exc_register(19, "simd_fp", true, (iroutine_t) simd_fp_exception); 221 229 222 230 #ifdef CONFIG_SMP 223 exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", (iroutine) tlb_shootdown_ipi); 231 exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", true, 232 (iroutine_t) tlb_shootdown_ipi); 224 233 #endif 225 234 } -
kernel/arch/ia32/src/mm/as.c
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32mm 29 /** @addtogroup ia32mm 30 30 * @{ 31 31 */ -
kernel/arch/ia32/src/mm/frame.c
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32mm 29 /** @addtogroup ia32mm 30 30 * @{ 31 31 */ … … 44 44 #include <align.h> 45 45 #include <macros.h> 46 47 46 #include <print.h> 47 48 #define PHYSMEM_LIMIT32 UINT64_C(0x07c000000) 49 #define PHYSMEM_LIMIT64 UINT64_C(0x200000000) 48 50 49 51 size_t hardcoded_unmapped_ktext_size = 0; … … 55 57 { 56 58 unsigned int i; 59 57 60 for (i = 0; i < e820counter; i++) { 58 61 uint64_t base = e820table[i].base_address; … … 60 63 61 64 #ifdef __32_BITS__ 62 63 /* Ignore physical memory above 4 GB */ 64 if ((base >> 32) != 0) 65 /* 66 * XXX FIXME: 67 * 68 * Ignore zones which start above PHYSMEM_LIMIT32 69 * or clip zones which go beyond PHYSMEM_LIMIT32. 70 * 71 * The PHYSMEM_LIMIT32 (2 GB - 64 MB) is a rather 72 * arbitrary constant which allows to have at 73 * least 64 MB in the kernel address space to 74 * map hardware resources. 75 * 76 * The kernel uses fixed 1:1 identity mapping 77 * of the physical memory with 2:2 GB split. 78 * This is a severe limitation of the current 79 * kernel memory management. 80 * 81 */ 82 83 if (base > PHYSMEM_LIMIT32) 65 84 continue; 66 85 67 /* Clip regions above 4 GB */ 68 if (((base + size) >> 32) != 0) 69 size = 0xffffffff - base; 70 71 #endif 72 pfn_t pfn; 73 size_t count; 86 if (base + size > PHYSMEM_LIMIT32) 87 size = PHYSMEM_LIMIT32 - base; 88 #endif 89 90 #ifdef __64_BITS__ 91 /* 92 * XXX FIXME: 93 * 94 * Ignore zones which start above PHYSMEM_LIMIT64 95 * or clip zones which go beyond PHYSMEM_LIMIT64. 96 * 97 * The PHYSMEM_LIMIT64 (8 GB) is the size of the 98 * fixed 1:1 identically mapped physical memory 99 * accessible during the bootstrap process. 100 * This is a severe limitation of the current 101 * kernel memory management. 102 * 103 */ 104 105 if (base > PHYSMEM_LIMIT64) 106 continue; 107 108 if (base + size > PHYSMEM_LIMIT64) 109 size = PHYSMEM_LIMIT64 - base; 110 #endif 74 111 75 112 if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) { 76 /* To be safe, make available zone possibly smaller */ 77 pfn = ADDR2PFN(ALIGN_UP(base, FRAME_SIZE)); 78 count = SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)); 113 /* To be safe, make the available zone possibly smaller */ 114 uint64_t new_base = ALIGN_UP(base, FRAME_SIZE); 115 uint64_t new_size = ALIGN_DOWN(size - (new_base - base), 116 FRAME_SIZE); 117 118 pfn_t pfn = ADDR2PFN(new_base); 119 size_t count = SIZE2FRAMES(new_size); 79 120 80 121 pfn_t conf; … … 87 128 88 129 // XXX this has to be removed 89 if (last_frame < ALIGN_UP(base + size, FRAME_SIZE)) 90 last_frame = ALIGN_UP(base + size, FRAME_SIZE); 91 } 92 93 if (e820table[i].type == MEMMAP_MEMORY_RESERVED) { 94 /* To be safe, make reserved zone possibly larger */ 95 pfn = ADDR2PFN(ALIGN_DOWN(base, FRAME_SIZE)); 96 count = SIZE2FRAMES(ALIGN_UP(size, FRAME_SIZE)); 97 98 zone_create(pfn, count, 0, ZONE_RESERVED); 99 } 100 101 if (e820table[i].type == MEMMAP_MEMORY_ACPI) { 102 /* To be safe, make firmware zone possibly larger */ 103 pfn = ADDR2PFN(ALIGN_DOWN(base, (uintptr_t) FRAME_SIZE)); 104 count = SIZE2FRAMES(ALIGN_UP(size, (uintptr_t) FRAME_SIZE)); 105 106 zone_create(pfn, count, 0, ZONE_FIRMWARE); 130 if (last_frame < ALIGN_UP(new_base + new_size, FRAME_SIZE)) 131 last_frame = ALIGN_UP(new_base + new_size, FRAME_SIZE); 132 } else if ((e820table[i].type == MEMMAP_MEMORY_ACPI) || 133 (e820table[i].type == MEMMAP_MEMORY_NVS)) { 134 /* To be safe, make the firmware zone possibly larger */ 135 uint64_t new_base = ALIGN_DOWN(base, FRAME_SIZE); 136 uint64_t new_size = ALIGN_UP(size + (base - new_base), 137 FRAME_SIZE); 138 139 zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0, 140 ZONE_FIRMWARE); 141 } else { 142 /* To be safe, make the reserved zone possibly larger */ 143 uint64_t new_base = ALIGN_DOWN(base, FRAME_SIZE); 144 uint64_t new_size = ALIGN_UP(size + (base - new_base), 145 FRAME_SIZE); 146 147 zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0, 148 ZONE_RESERVED); 107 149 } 108 150 } 109 151 } 110 152 111 static c har *e820names[] = {153 static const char *e820names[] = { 112 154 "invalid", 113 155 "available", … … 118 160 }; 119 161 120 121 162 void physmem_print(void) 122 163 { 123 164 unsigned int i; 124 char *name;165 printf("[base ] [size ] [name ]\n"); 125 166 126 printf("Base Size Name\n");127 printf("------------------ ------------------ ---------\n");128 129 167 for (i = 0; i < e820counter; i++) { 168 const char *name; 169 130 170 if (e820table[i].type <= MEMMAP_MEMORY_UNUSABLE) 131 171 name = e820names[e820table[i].type]; … … 133 173 name = "invalid"; 134 174 135 printf("%# 18llx %#18llx%s\n", e820table[i].base_address,136 e820table[i].size, name);175 printf("%#018" PRIx64 " %#018" PRIx64" %s\n", e820table[i].base_address, 176 e820table[i].size, name); 137 177 } 138 178 } … … 148 188 #ifdef CONFIG_SMP 149 189 minconf = max(minconf, 150 ADDR2PFN(AP_BOOT_OFFSET + hardcoded_unmapped_ktext_size + 151 hardcoded_unmapped_kdata_size)); 152 #endif 190 ADDR2PFN(AP_BOOT_OFFSET + hardcoded_unmapped_ktext_size + 191 hardcoded_unmapped_kdata_size)); 192 #endif 193 153 194 init_e820_memory(minconf); 154 195 … … 158 199 #ifdef CONFIG_SMP 159 200 /* Reserve AP real mode bootstrap memory */ 160 frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH, 161 (hardcoded_unmapped_ktext_size +162 hardcoded_unmapped_kdata_size) >> FRAME_WIDTH);201 frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH, 202 (hardcoded_unmapped_ktext_size + 203 hardcoded_unmapped_kdata_size) >> FRAME_WIDTH); 163 204 #endif 164 205 } -
kernel/arch/ia32/src/mm/page.c
rb50b5af2 r04803bf 39 39 #include <mm/page.h> 40 40 #include <mm/as.h> 41 #include < arch/types.h>41 #include <typedefs.h> 42 42 #include <align.h> 43 43 #include <config.h> … … 61 61 * PA2KA(identity) mapping for all frames until last_frame. 62 62 */ 63 page_table_lock(AS_KERNEL, true); 63 64 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) { 64 65 flags = PAGE_CACHEABLE | PAGE_WRITE; … … 67 68 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); 68 69 } 70 page_table_unlock(AS_KERNEL, true); 69 71 70 exc_register(14, "page_fault", (iroutine) page_fault);72 exc_register(14, "page_fault", true, (iroutine_t) page_fault); 71 73 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); 72 74 } else … … 80 82 { 81 83 if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) 82 panic("Unable to map physical memory %p (%d bytes).", physaddr, size) 84 panic("Unable to map physical memory %p (%zu bytes).", 85 (void *) physaddr, size); 83 86 84 87 uintptr_t virtaddr = PA2KA(last_frame); 85 88 pfn_t i; 89 page_table_lock(AS_KERNEL, true); 86 90 for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) { 87 91 uintptr_t addr = PFN2ADDR(i); 88 92 page_mapping_insert(AS_KERNEL, virtaddr + addr, physaddr + addr, PAGE_NOT_CACHEABLE | PAGE_WRITE); 89 93 } 94 page_table_unlock(AS_KERNEL, true); 90 95 91 96 last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); … … 94 99 } 95 100 96 void page_fault( int n __attribute__((unused)), istate_t *istate)101 void page_fault(unsigned int n __attribute__((unused)), istate_t *istate) 97 102 { 98 103 uintptr_t page; … … 111 116 if (as_page_fault(page, access, istate) == AS_PF_FAULT) { 112 117 fault_if_from_uspace(istate, "Page fault: %#x.", page); 113 114 decode_istate(istate); 115 printf("page fault address: %#lx\n", page); 116 panic("Page fault."); 118 panic_memtrap(istate, access, page, NULL); 117 119 } 118 120 } -
kernel/arch/ia32/src/mm/tlb.c
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32mm 29 /** @addtogroup ia32mm 30 30 * @{ 31 31 */ … … 37 37 #include <arch/mm/asid.h> 38 38 #include <arch/asm.h> 39 #include < arch/types.h>39 #include <typedefs.h> 40 40 41 41 /** Invalidate all entries in TLB. */ -
kernel/arch/ia32/src/pm.c
rb50b5af2 r04803bf 35 35 #include <arch/pm.h> 36 36 #include <config.h> 37 #include < arch/types.h>37 #include <typedefs.h> 38 38 #include <arch/interrupt.h> 39 39 #include <arch/asm.h> … … 75 75 /* VESA Init descriptor */ 76 76 #ifdef CONFIG_FB 77 { 0xffff, 0, VESA_INIT_SEGMENT >>12, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }78 #endif 77 { 0xffff, 0, VESA_INIT_SEGMENT >> 12, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 } 78 #endif 79 79 }; 80 80 … … 86 86 87 87 /* gdtr is changed by kmp before next CPU is initialized */ 88 ptr_16_32_t bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((uintptr_t) gdt) }; 89 ptr_16_32_t gdtr = { .limit = sizeof(gdt), .base = (uintptr_t) gdt }; 88 ptr_16_32_t gdtr = { 89 .limit = sizeof(gdt), 90 .base = (uintptr_t) gdt 91 }; 90 92 91 93 void gdt_setbase(descriptor_t *d, uintptr_t base) … … 128 130 129 131 d->unused = 0; 130 d->selector = gdtselector(KTEXT_DES); 131 132 d->access = AR_PRESENT | AR_INTERRUPT; /* masking interrupt */ 132 d->selector = GDT_SELECTOR(KTEXT_DES); 133 133 134 134 if (i == VECTOR_SYSCALL) { 135 135 /* 136 * The syscall interrupt gate must be calleable from137 * userland. 136 * The syscall trap gate must be callable from 137 * userland. Interrupts will remain enabled. 138 138 */ 139 d->access |= DPL_USER; 139 d->access = AR_PRESENT | AR_TRAP | DPL_USER; 140 } else { 141 /* 142 * Other interrupts use interrupt gates which 143 * disable interrupts. 144 */ 145 d->access = AR_PRESENT | AR_INTERRUPT; 140 146 } 141 142 idt_setoffset(d, ((uintptr_t) interrupt_handlers) +143 i * interrupt_handler_size);144 147 } 145 } 146 148 149 d = &idt[0]; 150 idt_setoffset(d++, (uintptr_t) &int_0); 151 idt_setoffset(d++, (uintptr_t) &int_1); 152 idt_setoffset(d++, (uintptr_t) &int_2); 153 idt_setoffset(d++, (uintptr_t) &int_3); 154 idt_setoffset(d++, (uintptr_t) &int_4); 155 idt_setoffset(d++, (uintptr_t) &int_5); 156 idt_setoffset(d++, (uintptr_t) &int_6); 157 idt_setoffset(d++, (uintptr_t) &int_7); 158 idt_setoffset(d++, (uintptr_t) &int_8); 159 idt_setoffset(d++, (uintptr_t) &int_9); 160 idt_setoffset(d++, (uintptr_t) &int_10); 161 idt_setoffset(d++, (uintptr_t) &int_11); 162 idt_setoffset(d++, (uintptr_t) &int_12); 163 idt_setoffset(d++, (uintptr_t) &int_13); 164 idt_setoffset(d++, (uintptr_t) &int_14); 165 idt_setoffset(d++, (uintptr_t) &int_15); 166 idt_setoffset(d++, (uintptr_t) &int_16); 167 idt_setoffset(d++, (uintptr_t) &int_17); 168 idt_setoffset(d++, (uintptr_t) &int_18); 169 idt_setoffset(d++, (uintptr_t) &int_19); 170 idt_setoffset(d++, (uintptr_t) &int_20); 171 idt_setoffset(d++, (uintptr_t) &int_21); 172 idt_setoffset(d++, (uintptr_t) &int_22); 173 idt_setoffset(d++, (uintptr_t) &int_23); 174 idt_setoffset(d++, (uintptr_t) &int_24); 175 idt_setoffset(d++, (uintptr_t) &int_25); 176 idt_setoffset(d++, (uintptr_t) &int_26); 177 idt_setoffset(d++, (uintptr_t) &int_27); 178 idt_setoffset(d++, (uintptr_t) &int_28); 179 idt_setoffset(d++, (uintptr_t) &int_29); 180 idt_setoffset(d++, (uintptr_t) &int_30); 181 idt_setoffset(d++, (uintptr_t) &int_31); 182 idt_setoffset(d++, (uintptr_t) &int_32); 183 idt_setoffset(d++, (uintptr_t) &int_33); 184 idt_setoffset(d++, (uintptr_t) &int_34); 185 idt_setoffset(d++, (uintptr_t) &int_35); 186 idt_setoffset(d++, (uintptr_t) &int_36); 187 idt_setoffset(d++, (uintptr_t) &int_37); 188 idt_setoffset(d++, (uintptr_t) &int_38); 189 idt_setoffset(d++, (uintptr_t) &int_39); 190 idt_setoffset(d++, (uintptr_t) &int_40); 191 idt_setoffset(d++, (uintptr_t) &int_41); 192 idt_setoffset(d++, (uintptr_t) &int_42); 193 idt_setoffset(d++, (uintptr_t) &int_43); 194 idt_setoffset(d++, (uintptr_t) &int_44); 195 idt_setoffset(d++, (uintptr_t) &int_45); 196 idt_setoffset(d++, (uintptr_t) &int_46); 197 idt_setoffset(d++, (uintptr_t) &int_47); 198 idt_setoffset(d++, (uintptr_t) &int_48); 199 idt_setoffset(d++, (uintptr_t) &int_49); 200 idt_setoffset(d++, (uintptr_t) &int_50); 201 idt_setoffset(d++, (uintptr_t) &int_51); 202 idt_setoffset(d++, (uintptr_t) &int_52); 203 idt_setoffset(d++, (uintptr_t) &int_53); 204 idt_setoffset(d++, (uintptr_t) &int_54); 205 idt_setoffset(d++, (uintptr_t) &int_55); 206 idt_setoffset(d++, (uintptr_t) &int_56); 207 idt_setoffset(d++, (uintptr_t) &int_57); 208 idt_setoffset(d++, (uintptr_t) &int_58); 209 idt_setoffset(d++, (uintptr_t) &int_59); 210 idt_setoffset(d++, (uintptr_t) &int_60); 211 idt_setoffset(d++, (uintptr_t) &int_61); 212 idt_setoffset(d++, (uintptr_t) &int_62); 213 idt_setoffset(d++, (uintptr_t) &int_63); 214 215 idt_setoffset(&idt[VECTOR_SYSCALL], (uintptr_t) &int_syscall); 216 } 147 217 148 218 /* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */ … … 215 285 * to its own TSS. We just need to load the TR register. 216 286 */ 217 tr_load( gdtselector(TSS_DES));287 tr_load(GDT_SELECTOR(TSS_DES)); 218 288 219 289 clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels and clear NT flag. */ -
kernel/arch/ia32/src/proc/scheduler.c
rb50b5af2 r04803bf 38 38 #include <proc/thread.h> 39 39 #include <arch.h> 40 #include <arch/ context.h> /* SP_DELTA */40 #include <arch/interrupt.h> 41 41 #include <arch/pm.h> 42 42 #include <arch/asm.h> … … 58 58 void before_thread_runs_arch(void) 59 59 { 60 uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - 61 SP_DELTA]; 60 uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE]; 62 61 63 /* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */ 64 write_msr(IA32_MSR_SYSENTER_ESP, kstk); 62 if (CPU->arch.fi.bits.sep) { 63 /* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */ 64 write_msr(IA32_MSR_SYSENTER_ESP, kstk - sizeof(istate_t)); 65 } 65 66 66 67 /* Set kernel stack for CPL3 -> CPL0 switch via interrupt */ 67 68 CPU->arch.tss->esp0 = kstk; 68 CPU->arch.tss->ss0 = gdtselector(KDATA_DES);69 CPU->arch.tss->ss0 = GDT_SELECTOR(KDATA_DES); 69 70 70 71 /* Set up TLS in GS register */ -
kernel/arch/ia32/src/proc/task.c
rb50b5af2 r04803bf 34 34 35 35 #include <proc/task.h> 36 #include < arch/types.h>36 #include <typedefs.h> 37 37 #include <adt/bitmap.h> 38 38 #include <mm/slab.h> -
kernel/arch/ia32/src/smp/ap.S
rb50b5af2 r04803bf 78 78 addl $0x80000000, %esp # PA2KA(ctx.sp) 79 79 80 pushl $0 # create the first stack frame 81 movl %esp, %ebp 82 80 83 jmpl $KTEXT, $main_ap 81 84 -
kernel/arch/ia32/src/smp/apic.c
rb50b5af2 r04803bf 33 33 */ 34 34 35 #include < arch/types.h>35 #include <typedefs.h> 36 36 #include <arch/smp/apic.h> 37 37 #include <arch/smp/ap.h> … … 53 53 * Advanced Programmable Interrupt Controller for SMP systems. 54 54 * Tested on: 55 * Bochs 2.0.2 - Bochs 2.2.6 with 2-8 CPUs 56 * Simics 2.0.28 - Simics 2.2.19 2-15 CPUs 57 * VMware Workstation 5.5 with 2 CPUs 58 * QEMU 0.8.0 with 2-15 CPUs 59 * ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs 60 * ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs 61 * MSI K7D Master-L with 2x 2100MHz Athlon MP CPUs 55 * Bochs 2.0.2 - Bochs 2.2.6 with 2-8 CPUs 56 * Simics 2.0.28 - Simics 2.2.19 2-15 CPUs 57 * VMware Workstation 5.5 with 2 CPUs 58 * QEMU 0.8.0 with 2-15 CPUs 59 * ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs 60 * ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs 61 * MSI K7D Master-L with 2x 2100MHz Athlon MP CPUs 62 * 62 63 */ 63 64 … … 69 70 * optimize the code too much and accesses to l_apic and io_apic, that must 70 71 * always be 32-bit, would use byte oriented instructions. 71 */ 72 volatile uint32_t *l_apic = (uint32_t *) 0xfee00000; 73 volatile uint32_t *io_apic = (uint32_t *) 0xfec00000; 72 * 73 */ 74 volatile uint32_t *l_apic = (uint32_t *) UINT32_C(0xfee00000); 75 volatile uint32_t *io_apic = (uint32_t *) UINT32_C(0xfec00000); 74 76 75 77 uint32_t apic_id_mask = 0; 78 uint8_t bsp_l_apic = 0; 79 76 80 static irq_t l_apic_timer_irq; 77 81 … … 79 83 80 84 #ifdef LAPIC_VERBOSE 81 static c har *delmod_str[] = {85 static const char *delmod_str[] = { 82 86 "Fixed", 83 87 "Lowest Priority", … … 90 94 }; 91 95 92 static c har *destmod_str[] = {96 static const char *destmod_str[] = { 93 97 "Physical", 94 98 "Logical" 95 99 }; 96 100 97 static c har *trigmod_str[] = {101 static const char *trigmod_str[] = { 98 102 "Edge", 99 103 "Level" 100 104 }; 101 105 102 static c har *mask_str[] = {106 static const char *mask_str[] = { 103 107 "Unmasked", 104 108 "Masked" 105 109 }; 106 110 107 static c har *delivs_str[] = {111 static const char *delivs_str[] = { 108 112 "Idle", 109 113 "Send Pending" 110 114 }; 111 115 112 static c har *tm_mode_str[] = {116 static const char *tm_mode_str[] = { 113 117 "One-shot", 114 118 "Periodic" 115 119 }; 116 120 117 static c har *intpol_str[] = {121 static const char *intpol_str[] = { 118 122 "Polarity High", 119 123 "Polarity Low" … … 123 127 /** APIC spurious interrupt handler. 124 128 * 125 * @param n Interrupt vector.129 * @param n Interrupt vector. 126 130 * @param istate Interrupted state. 127 */ 128 static void apic_spurious(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) 131 * 132 */ 133 static void apic_spurious(unsigned int n __attribute__((unused)), 134 istate_t *istate __attribute__((unused))) 129 135 { 130 136 #ifdef CONFIG_DEBUG … … 145 151 * irq->lock so we just unlock it and then lock it again. 146 152 */ 147 spinlock_unlock(&irq->lock);153 irq_spinlock_unlock(&irq->lock, false); 148 154 clock(); 149 spinlock_lock(&irq->lock); 155 irq_spinlock_lock(&irq->lock, false); 156 } 157 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; 150 169 } 151 170 … … 153 172 void apic_init(void) 154 173 { 155 io_apic_id_t idreg; 156 157 exc_register(VECTOR_APIC_SPUR, "apic_spurious", (iroutine) apic_spurious); 158 174 exc_register(VECTOR_APIC_SPUR, "apic_spurious", false, 175 (iroutine_t) apic_spurious); 176 159 177 enable_irqs_function = io_apic_enable_irqs; 160 178 disable_irqs_function = io_apic_disable_irqs; 161 179 eoi_function = l_apic_eoi; 180 irqs_info = "apic"; 162 181 163 182 /* … … 166 185 * Other interrupts will be forwarded to the lowest priority CPU. 167 186 */ 168 io_apic_disable_irqs(0xffff );187 io_apic_disable_irqs(0xffffU); 169 188 170 189 irq_initialize(&l_apic_timer_irq); … … 179 198 for (i = 0; i < IRQ_COUNT; i++) { 180 199 int pin; 181 200 182 201 if ((pin = smp_irq_to_pin(i)) != -1) 183 202 io_apic_change_ioredtbl((uint8_t) pin, DEST_ALL, (uint8_t) (IVT_IRQBASE + i), LOPRI); … … 187 206 * Ensure that io_apic has unique ID. 188 207 */ 208 io_apic_id_t idreg; 209 189 210 idreg.value = io_apic_read(IOAPICID); 190 if ((1 << idreg.apic_id) & apic_id_mask) { /* see if IO APIC ID is used already */211 if ((1 << idreg.apic_id) & apic_id_mask) { /* See if IO APIC ID is used already */ 191 212 for (i = 0; i < APIC_ID_COUNT; i++) { 192 213 if (!((1 << i) & apic_id_mask)) { … … 197 218 } 198 219 } 199 220 200 221 /* 201 222 * Configure the BSP's lapic. 202 223 */ 203 224 l_apic_init(); 204 205 l_apic_debug(); 225 l_apic_debug(); 226 227 bsp_l_apic = l_apic_id(); 206 228 } 207 229 … … 211 233 * 212 234 * @return 0 on error, 1 on success. 235 * 213 236 */ 214 237 int apic_poll_errors(void) … … 232 255 if (esr.illegal_register_address) 233 256 printf("Illegal Register Address\n"); 234 257 235 258 return !esr.err_bitmap; 236 259 } … … 241 264 * 242 265 * @return 0 on failure, 1 on success. 266 * 243 267 */ 244 268 int l_apic_broadcast_custom_ipi(uint8_t vector) 245 269 { 246 270 icr_t icr; 247 271 248 272 icr.lo = l_apic[ICRlo]; 249 273 icr.delmod = DELMOD_FIXED; … … 253 277 icr.trigger_mode = TRIGMOD_LEVEL; 254 278 icr.vector = vector; 255 279 256 280 l_apic[ICRlo] = icr.lo; 257 281 258 282 icr.lo = l_apic[ICRlo]; 259 283 if (icr.delivs == DELIVS_PENDING) { … … 262 286 #endif 263 287 } 264 288 265 289 return apic_poll_errors(); 266 290 } … … 271 295 * 272 296 * @return 0 on failure, 1 on success. 297 * 273 298 */ 274 299 int l_apic_send_init_ipi(uint8_t apicid) 275 300 { 301 /* 302 * Read the ICR register in and zero all non-reserved fields. 303 */ 276 304 icr_t icr; 277 int i; 278 279 /* 280 * Read the ICR register in and zero all non-reserved fields. 281 */ 305 282 306 icr.lo = l_apic[ICRlo]; 283 307 icr.hi = l_apic[ICRhi]; … … 293 317 l_apic[ICRhi] = icr.hi; 294 318 l_apic[ICRlo] = icr.lo; 295 319 296 320 /* 297 321 * According to MP Specification, 20us should be enough to … … 299 323 */ 300 324 delay(20); 301 325 302 326 if (!apic_poll_errors()) 303 327 return 0; 304 328 305 329 icr.lo = l_apic[ICRlo]; 306 330 if (icr.delivs == DELIVS_PENDING) { … … 309 333 #endif 310 334 } 311 335 312 336 icr.delmod = DELMOD_INIT; 313 337 icr.destmod = DESTMOD_PHYS; … … 317 341 icr.vector = 0; 318 342 l_apic[ICRlo] = icr.lo; 319 343 320 344 /* 321 345 * Wait 10ms as MP Specification specifies. 322 346 */ 323 347 delay(10000); 324 348 325 349 if (!is_82489DX_apic(l_apic[LAVR])) { 326 350 /* 327 351 * If this is not 82489DX-based l_apic we must send two STARTUP IPI's. 328 352 */ 329 for (i = 0; i<2; i++) { 353 unsigned int i; 354 for (i = 0; i < 2; i++) { 330 355 icr.lo = l_apic[ICRlo]; 331 356 icr.vector = (uint8_t) (((uintptr_t) ap_boot) >> 12); /* calculate the reset vector */ … … 346 371 void l_apic_init(void) 347 372 { 373 /* Initialize LVT Error register. */ 348 374 lvt_error_t error; 349 lvt_lint_t lint; 350 tpr_t tpr; 351 svr_t svr; 352 icr_t icr; 353 tdcr_t tdcr; 354 lvt_tm_t tm; 355 ldr_t ldr; 356 dfr_t dfr; 357 uint32_t t1, t2; 358 359 /* Initialize LVT Error register. */ 375 360 376 error.value = l_apic[LVT_Err]; 361 377 error.masked = true; 362 378 l_apic[LVT_Err] = error.value; 363 379 364 380 /* Initialize LVT LINT0 register. */ 381 lvt_lint_t lint; 382 365 383 lint.value = l_apic[LVT_LINT0]; 366 384 lint.masked = true; 367 385 l_apic[LVT_LINT0] = lint.value; 368 386 369 387 /* Initialize LVT LINT1 register. */ 370 388 lint.value = l_apic[LVT_LINT1]; 371 389 lint.masked = true; 372 390 l_apic[LVT_LINT1] = lint.value; 373 391 374 392 /* Task Priority Register initialization. */ 393 tpr_t tpr; 394 375 395 tpr.value = l_apic[TPR]; 376 396 tpr.pri_sc = 0; … … 379 399 380 400 /* Spurious-Interrupt Vector Register initialization. */ 401 svr_t svr; 402 381 403 svr.value = l_apic[SVR]; 382 404 svr.vector = VECTOR_APIC_SPUR; … … 384 406 svr.focus_checking = true; 385 407 l_apic[SVR] = svr.value; 386 408 387 409 if (CPU->arch.family >= 6) 388 410 enable_l_apic_in_msr(); 389 411 390 412 /* Interrupt Command Register initialization. */ 413 icr_t icr; 414 391 415 icr.lo = l_apic[ICRlo]; 392 416 icr.delmod = DELMOD_INIT; … … 398 422 399 423 /* Timer Divide Configuration Register initialization. */ 424 tdcr_t tdcr; 425 400 426 tdcr.value = l_apic[TDCR]; 401 427 tdcr.div_value = DIVIDE_1; 402 428 l_apic[TDCR] = tdcr.value; 403 429 404 430 /* Program local timer. */ 431 lvt_tm_t tm; 432 405 433 tm.value = l_apic[LVT_Tm]; 406 434 tm.vector = VECTOR_CLK; … … 408 436 tm.masked = false; 409 437 l_apic[LVT_Tm] = tm.value; 410 438 411 439 /* 412 440 * Measure and configure the timer to generate timer 413 441 * interrupt with period 1s/HZ seconds. 414 442 */ 443 uint32_t t1 = l_apic[CCRT]; 444 l_apic[ICRT] = 0xffffffff; 445 446 while (l_apic[CCRT] == t1); 447 415 448 t1 = l_apic[CCRT]; 416 l_apic[ICRT] = 0xffffffff; 417 418 while (l_apic[CCRT] == t1) 419 ; 420 421 t1 = l_apic[CCRT]; 422 delay(1000000/HZ); 423 t2 = l_apic[CCRT]; 424 425 l_apic[ICRT] = t1-t2; 449 delay(1000000 / HZ); 450 uint32_t t2 = l_apic[CCRT]; 451 452 l_apic[ICRT] = t1 - t2; 426 453 427 454 /* Program Logical Destination Register. */ 428 ASSERT(CPU->id < 8) 455 ASSERT(CPU->id < 8); 456 ldr_t ldr; 457 429 458 ldr.value = l_apic[LDR]; 430 459 ldr.id = (uint8_t) (1 << CPU->id); … … 432 461 433 462 /* Program Destination Format Register for Flat mode. */ 463 dfr_t dfr; 464 434 465 dfr.value = l_apic[DFR]; 435 466 dfr.model = MODEL_FLAT; … … 447 478 { 448 479 #ifdef LAPIC_VERBOSE 480 printf("LVT on cpu%u, LAPIC ID: %" PRIu8 "\n", 481 CPU->id, l_apic_id()); 482 449 483 lvt_tm_t tm; 484 tm.value = l_apic[LVT_Tm]; 485 printf("LVT Tm: vector=%" PRIu8 ", %s, %s, %s\n", 486 tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], 487 tm_mode_str[tm.mode]); 488 450 489 lvt_lint_t lint; 451 lvt_error_t error;452 453 printf("LVT on cpu%d, LAPIC ID: %d\n", CPU->id, l_apic_id());454 455 tm.value = l_apic[LVT_Tm];456 printf("LVT Tm: vector=%hhd, %s, %s, %s\n", tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], tm_mode_str[tm.mode]);457 490 lint.value = l_apic[LVT_LINT0]; 458 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]); 459 lint.value = l_apic[LVT_LINT1]; 460 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]); 491 printf("LVT LINT0: vector=%" PRIu8 ", %s, %s, %s, irr=%u, %s, %s\n", 492 tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], 493 intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], 494 mask_str[lint.masked]); 495 496 lint.value = l_apic[LVT_LINT1]; 497 printf("LVT LINT1: vector=%" PRIu8 ", %s, %s, %s, irr=%u, %s, %s\n", 498 tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], 499 intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], 500 mask_str[lint.masked]); 501 502 lvt_error_t error; 461 503 error.value = l_apic[LVT_Err]; 462 printf("LVT Err: vector=%hhd, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]); 504 printf("LVT Err: vector=%" PRIu8 ", %s, %s\n", error.vector, 505 delivs_str[error.delivs], mask_str[error.masked]); 463 506 #endif 464 507 } 465 508 466 /** Get Local APIC ID.467 *468 * @return Local APIC ID.469 */470 uint8_t l_apic_id(void)471 {472 l_apic_id_t idreg;473 474 idreg.value = l_apic[L_APIC_ID];475 return idreg.apic_id;476 }477 478 509 /** Read from IO APIC register. 479 510 * … … 481 512 * 482 513 * @return Content of the addressed IO APIC register. 514 * 483 515 */ 484 516 uint32_t io_apic_read(uint8_t address) … … 495 527 * 496 528 * @param address IO APIC register address. 497 * @param x Content to be written to the addressed IO APIC register. 498 */ 499 void io_apic_write(uint8_t address, uint32_t x) 529 * @param val Content to be written to the addressed IO APIC register. 530 * 531 */ 532 void io_apic_write(uint8_t address, uint32_t val) 500 533 { 501 534 io_regsel_t regsel; … … 504 537 regsel.reg_addr = address; 505 538 io_apic[IOREGSEL] = regsel.value; 506 io_apic[IOWIN] = x;539 io_apic[IOWIN] = val; 507 540 } 508 541 509 542 /** Change some attributes of one item in I/O Redirection Table. 510 543 * 511 * @param pin IO APIC pin number.512 * @param dest Interrupt destination address.513 * @param v Interrupt vector to trigger.544 * @param pin IO APIC pin number. 545 * @param dest Interrupt destination address. 546 * @param vec Interrupt vector to trigger. 514 547 * @param flags Flags. 515 */ 516 void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t v, int flags) 517 { 518 io_redirection_reg_t reg; 519 int dlvr = DELMOD_FIXED; 548 * 549 */ 550 void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t vec, 551 unsigned int flags) 552 { 553 unsigned int dlvr; 520 554 521 555 if (flags & LOPRI) 522 556 dlvr = DELMOD_LOWPRI; 523 557 else 558 dlvr = DELMOD_FIXED; 559 560 io_redirection_reg_t reg; 524 561 reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2)); 525 562 reg.hi = io_apic_read((uint8_t) (IOREDTBL + pin * 2 + 1)); … … 530 567 reg.intpol = POLARITY_HIGH; 531 568 reg.delmod = dlvr; 532 reg.intvec = v ;533 569 reg.intvec = vec; 570 534 571 io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo); 535 572 io_apic_write((uint8_t) (IOREDTBL + pin * 2 + 1), reg.hi); … … 539 576 * 540 577 * @param irqmask Bitmask of IRQs to be masked (0 = do not mask, 1 = mask). 578 * 541 579 */ 542 580 void io_apic_disable_irqs(uint16_t irqmask) 543 581 { 544 io_redirection_reg_t reg;545 582 unsigned int i; 546 int pin;547 548 583 for (i = 0; i < 16; i++) { 549 584 if (irqmask & (1 << i)) { … … 552 587 * mapping for the respective IRQ number. 553 588 */ 554 pin = smp_irq_to_pin(i);589 int pin = smp_irq_to_pin(i); 555 590 if (pin != -1) { 591 io_redirection_reg_t reg; 592 556 593 reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2)); 557 594 reg.masked = true; … … 566 603 * 567 604 * @param irqmask Bitmask of IRQs to be unmasked (0 = do not unmask, 1 = unmask). 605 * 568 606 */ 569 607 void io_apic_enable_irqs(uint16_t irqmask) 570 608 { 571 609 unsigned int i; 572 int pin;573 io_redirection_reg_t reg;574 575 610 for (i = 0; i < 16; i++) { 576 611 if (irqmask & (1 << i)) { … … 579 614 * mapping for the respective IRQ number. 580 615 */ 581 pin = smp_irq_to_pin(i);616 int pin = smp_irq_to_pin(i); 582 617 if (pin != -1) { 618 io_redirection_reg_t reg; 619 583 620 reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2)); 584 621 reg.masked = false; -
kernel/arch/ia32/src/smp/ipi.c
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ -
kernel/arch/ia32/src/smp/mps.c
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 42 42 #include <arch/smp/smp.h> 43 43 #include <func.h> 44 #include < arch/types.h>44 #include <typedefs.h> 45 45 #include <cpu.h> 46 46 #include <arch/asm.h> … … 52 52 */ 53 53 54 #define FS_SIGNATURE 0x5f504d5f 55 #define CT_SIGNATURE 0x504d4350 56 57 static int mps_fs_check(uint8_t *base); 58 static int mps_ct_check(void); 59 60 static int configure_via_ct(void); 61 static int configure_via_default(uint8_t n); 62 63 static int ct_processor_entry(struct __processor_entry *pr); 64 static void ct_bus_entry(struct __bus_entry *bus); 65 static void ct_io_apic_entry(struct __io_apic_entry *ioa); 66 static void ct_io_intr_entry(struct __io_intr_entry *iointr); 67 static void ct_l_intr_entry(struct __l_intr_entry *lintr); 68 69 static void ct_extended_entries(void); 54 #define FS_SIGNATURE UINT32_C(0x5f504d5f) 55 #define CT_SIGNATURE UINT32_C(0x504d4350) 70 56 71 57 static struct mps_fs *fs; 72 58 static struct mps_ct *ct; 73 59 74 struct __processor_entry *processor_entries = NULL; 75 struct __bus_entry *bus_entries = NULL; 76 struct __io_apic_entry *io_apic_entries = NULL; 77 struct __io_intr_entry *io_intr_entries = NULL; 78 struct __l_intr_entry *l_intr_entries = NULL; 79 80 unsigned int processor_entry_cnt = 0; 81 unsigned int bus_entry_cnt = 0; 82 unsigned int io_apic_entry_cnt = 0; 83 unsigned int io_intr_entry_cnt = 0; 84 unsigned int l_intr_entry_cnt = 0; 85 86 /* 87 * Implementation of IA-32 SMP configuration interface. 88 */ 89 static size_t get_cpu_count(void); 90 static bool is_cpu_enabled(size_t i); 91 static bool is_bsp(size_t i); 92 static uint8_t get_cpu_apic_id(size_t i); 93 static int mps_irq_to_pin(unsigned int irq); 94 60 static struct __processor_entry *processor_entries = NULL; 61 static struct __bus_entry *bus_entries = NULL; 62 static struct __io_apic_entry *io_apic_entries = NULL; 63 static struct __io_intr_entry *io_intr_entries = NULL; 64 static struct __l_intr_entry *l_intr_entries = NULL; 65 66 static size_t io_apic_cnt = 0; 67 68 static size_t processor_entry_cnt = 0; 69 static size_t bus_entry_cnt = 0; 70 static size_t io_apic_entry_cnt = 0; 71 static size_t io_intr_entry_cnt = 0; 72 static size_t l_intr_entry_cnt = 0; 73 74 static uint8_t mps_cpu_apic_id(size_t i) 75 { 76 ASSERT(i < processor_entry_cnt); 77 78 return processor_entries[i].l_apic_id; 79 } 80 81 static bool mps_cpu_enabled(size_t i) 82 { 83 ASSERT(i < processor_entry_cnt); 84 85 /* 86 * FIXME: The current local APIC driver limits usable 87 * CPU IDs to 8. 88 * 89 */ 90 if (i > 7) 91 return false; 92 93 return (bool) ((processor_entries[i].cpu_flags & 0x01) == 0x01); 94 } 95 96 static bool mps_cpu_bootstrap(size_t i) 97 { 98 ASSERT(i < processor_entry_cnt); 99 100 return (bool) ((processor_entries[i].cpu_flags & 0x02) == 0x02); 101 } 102 103 static int mps_irq_to_pin(unsigned int irq) 104 { 105 size_t i; 106 107 for (i = 0; i < io_intr_entry_cnt; i++) { 108 if (io_intr_entries[i].src_bus_irq == irq && 109 io_intr_entries[i].intr_type == 0) 110 return io_intr_entries[i].dst_io_apic_pin; 111 } 112 113 return -1; 114 } 115 116 /** Implementation of IA-32 SMP configuration interface. 117 * 118 */ 95 119 struct smp_config_operations mps_config_operations = { 96 .cpu_count = get_cpu_count, 97 .cpu_enabled = is_cpu_enabled, 98 .cpu_bootstrap = is_bsp, 99 .cpu_apic_id = get_cpu_apic_id, 120 .cpu_enabled = mps_cpu_enabled, 121 .cpu_bootstrap = mps_cpu_bootstrap, 122 .cpu_apic_id = mps_cpu_apic_id, 100 123 .irq_to_pin = mps_irq_to_pin 101 124 }; 102 125 103 size_t get_cpu_count(void) 104 { 105 return processor_entry_cnt; 106 } 107 108 bool is_cpu_enabled(size_t i) 109 { 110 ASSERT(i < processor_entry_cnt); 111 return (bool) ((processor_entries[i].cpu_flags & 0x01) == 0x01); 112 } 113 114 bool is_bsp(size_t i) 115 { 116 ASSERT(i < processor_entry_cnt); 117 return (bool) ((processor_entries[i].cpu_flags & 0x02) == 0x02); 118 } 119 120 uint8_t get_cpu_apic_id(size_t i) 121 { 122 ASSERT(i < processor_entry_cnt); 123 return processor_entries[i].l_apic_id; 124 } 125 126 127 /* 128 * Used to check the integrity of the MP Floating Structure. 129 */ 130 int mps_fs_check(uint8_t *base) 126 /** Check the integrity of the MP Floating Structure. 127 * 128 */ 129 static bool mps_fs_check(uint8_t *base) 131 130 { 132 131 unsigned int i; … … 136 135 sum = (uint8_t) (sum + base[i]); 137 136 138 return !sum;139 } 140 141 /* 142 * Used to check the integrity of the MP Configuration Table.143 */ 144 intmps_ct_check(void)137 return (sum == 0); 138 } 139 140 /** Check the integrity of the MP Configuration Table. 141 * 142 */ 143 static bool mps_ct_check(void) 145 144 { 146 145 uint8_t *base = (uint8_t *) ct; 147 146 uint8_t *ext = base + ct->base_table_length; 148 147 uint8_t sum; 149 int i;150 151 /* countthe checksum for the base table */152 for (i = 0, sum = 0; i < ct->base_table_length; i++)148 uint16_t i; 149 150 /* Compute the checksum for the base table */ 151 for (i = 0, sum = 0; i < ct->base_table_length; i++) 153 152 sum = (uint8_t) (sum + base[i]); 154 153 155 154 if (sum) 156 return 0;157 158 /* countthe checksum for the extended table */155 return false; 156 157 /* Compute the checksum for the extended table */ 159 158 for (i = 0, sum = 0; i < ct->ext_table_length; i++) 160 159 sum = (uint8_t) (sum + ext[i]); 161 162 return sum == ct->ext_table_checksum; 163 } 164 165 void mps_init(void) 166 { 167 uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xf0000) }; 168 unsigned int i, j, length[2] = { 1024, 64 * 1024 }; 169 170 160 161 return (sum == ct->ext_table_checksum); 162 } 163 164 static void ct_processor_entry(struct __processor_entry *pr) 165 { 171 166 /* 172 * Find MP Floating Pointer Structure 173 * 1a. search first 1K of EBDA 174 * 1b. if EBDA is undefined, search last 1K of base memory 175 * 2. search 64K starting at 0xf0000 167 * Ignore processors which are not marked enabled. 176 168 */ 177 178 addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024); 179 for (i = 0; i < 2; i++) { 180 for (j = 0; j < length[i]; j += 16) { 181 if (*((uint32_t *) &addr[i][j]) == 182 FS_SIGNATURE && mps_fs_check(&addr[i][j])) { 183 fs = (struct mps_fs *) &addr[i][j]; 184 goto fs_found; 185 } 169 if ((pr->cpu_flags & (1 << 0)) == 0) 170 return; 171 172 apic_id_mask |= (1 << pr->l_apic_id); 173 } 174 175 static void ct_bus_entry(struct __bus_entry *bus __attribute__((unused))) 176 { 177 #ifdef MPSCT_VERBOSE 178 char buf[7]; 179 180 memcpy((void *) buf, (void *) bus->bus_type, 6); 181 buf[6] = 0; 182 183 printf("MPS: bus=%" PRIu8 " (%s)\n", bus->bus_id, buf); 184 #endif 185 } 186 187 static void ct_io_apic_entry(struct __io_apic_entry *ioa) 188 { 189 /* This I/O APIC is marked unusable */ 190 if ((ioa->io_apic_flags & 1) == 0) 191 return; 192 193 if (io_apic_cnt++ > 0) { 194 /* 195 * Multiple I/O APICs are currently not supported. 196 */ 197 return; 198 } 199 200 io_apic = (uint32_t *) (uintptr_t) ioa->io_apic; 201 } 202 203 static void ct_io_intr_entry(struct __io_intr_entry *iointr 204 __attribute__((unused))) 205 { 206 #ifdef MPSCT_VERBOSE 207 printf("MPS: "); 208 209 switch (iointr->intr_type) { 210 case 0: 211 printf("INT"); 212 break; 213 case 1: 214 printf("NMI"); 215 break; 216 case 2: 217 printf("SMI"); 218 break; 219 case 3: 220 printf("ExtINT"); 221 break; 222 } 223 224 printf(", "); 225 226 switch (iointr->poel & 3) { 227 case 0: 228 printf("bus-like"); 229 break; 230 case 1: 231 printf("active high"); 232 break; 233 case 2: 234 printf("reserved"); 235 break; 236 case 3: 237 printf("active low"); 238 break; 239 } 240 241 printf(", "); 242 243 switch ((iointr->poel >> 2) & 3) { 244 case 0: 245 printf("bus-like"); 246 break; 247 case 1: 248 printf("edge-triggered"); 249 break; 250 case 2: 251 printf("reserved"); 252 break; 253 case 3: 254 printf("level-triggered"); 255 break; 256 } 257 258 printf(", bus=%" PRIu8 " irq=%" PRIu8 " io_apic=%" PRIu8" pin=%" 259 PRIu8 "\n", iointr->src_bus_id, iointr->src_bus_irq, 260 iointr->dst_io_apic_id, iointr->dst_io_apic_pin); 261 #endif 262 } 263 264 static void ct_l_intr_entry(struct __l_intr_entry *lintr 265 __attribute__((unused))) 266 { 267 #ifdef MPSCT_VERBOSE 268 printf("MPS: "); 269 270 switch (lintr->intr_type) { 271 case 0: 272 printf("INT"); 273 break; 274 case 1: 275 printf("NMI"); 276 break; 277 case 2: 278 printf("SMI"); 279 break; 280 case 3: 281 printf("ExtINT"); 282 break; 283 } 284 285 printf(", "); 286 287 switch (lintr->poel & 3) { 288 case 0: 289 printf("bus-like"); 290 break; 291 case 1: 292 printf("active high"); 293 break; 294 case 2: 295 printf("reserved"); 296 break; 297 case 3: 298 printf("active low"); 299 break; 300 } 301 302 printf(", "); 303 304 switch ((lintr->poel >> 2) & 3) { 305 case 0: 306 printf("bus-like"); 307 break; 308 case 1: 309 printf("edge-triggered"); 310 break; 311 case 2: 312 printf("reserved"); 313 break; 314 case 3: 315 printf("level-triggered"); 316 break; 317 } 318 319 printf(", bus=%" PRIu8 " irq=%" PRIu8 " l_apic=%" PRIu8" pin=%" 320 PRIu8 "\n", lintr->src_bus_id, lintr->src_bus_irq, 321 lintr->dst_l_apic_id, lintr->dst_l_apic_pin); 322 #endif 323 } 324 325 static void ct_extended_entries(void) 326 { 327 uint8_t *ext = (uint8_t *) ct + ct->base_table_length; 328 uint8_t *cur; 329 330 for (cur = ext; cur < ext + ct->ext_table_length; 331 cur += cur[CT_EXT_ENTRY_LEN]) { 332 switch (cur[CT_EXT_ENTRY_TYPE]) { 333 default: 334 printf("MPS: Skipping MP Configuration Table extended " 335 "entry type %" PRIu8 "\n", cur[CT_EXT_ENTRY_TYPE]); 186 336 } 187 337 } 188 189 return; 190 191 fs_found: 192 printf("%p: MPS Floating Pointer Structure\n", fs); 193 194 if (fs->config_type == 0 && fs->configuration_table) { 195 if (fs->mpfib2 >> 7) { 196 printf("%s: PIC mode not supported\n", __func__); 197 return; 198 } 199 200 ct = (struct mps_ct *)PA2KA((uintptr_t)fs->configuration_table); 201 config.cpu_count = configure_via_ct(); 202 } 203 else 204 config.cpu_count = configure_via_default(fs->config_type); 205 206 return; 207 } 208 209 int configure_via_ct(void) 210 { 211 uint8_t *cur; 212 unsigned int i, cnt; 213 338 } 339 340 static void configure_via_ct(void) 341 { 214 342 if (ct->signature != CT_SIGNATURE) { 215 printf("%s: bad ct->signature\n", __func__); 216 return 1; 217 } 343 printf("MPS: Wrong ct->signature\n"); 344 return; 345 } 346 218 347 if (!mps_ct_check()) { 219 printf("%s: bad ct checksum\n", __func__); 220 return 1; 221 } 348 printf("MPS: Wrong ct checksum\n"); 349 return; 350 } 351 222 352 if (ct->oem_table) { 223 printf("%s: ct->oem_table not supported\n", __func__); 224 return 1; 225 } 226 227 l_apic = (uint32_t *)(uintptr_t)ct->l_apic; 228 229 cnt = 0; 230 cur = &ct->base_table[0]; 353 printf("MPS: ct->oem_table not supported\n"); 354 return; 355 } 356 357 l_apic = (uint32_t *) (uintptr_t) ct->l_apic; 358 359 uint8_t *cur = &ct->base_table[0]; 360 uint16_t i; 361 231 362 for (i = 0; i < ct->entry_count; i++) { 232 363 switch (*cur) { 233 /* Processor entry */ 234 case 0: 364 case 0: /* Processor entry */ 235 365 processor_entries = processor_entries ? 236 366 processor_entries : 237 367 (struct __processor_entry *) cur; 238 368 processor_entry_cnt++; 239 cnt += ct_processor_entry((struct __processor_entry *) 240 cur); 369 ct_processor_entry((struct __processor_entry *) cur); 241 370 cur += 20; 242 371 break; 243 244 /* Bus entry */ 245 case 1: 372 case 1: /* Bus entry */ 246 373 bus_entries = bus_entries ? 247 374 bus_entries : (struct __bus_entry *) cur; … … 250 377 cur += 8; 251 378 break; 252 253 /* I/O Apic */ 254 case 2: 379 case 2: /* I/O APIC */ 255 380 io_apic_entries = io_apic_entries ? 256 381 io_apic_entries : (struct __io_apic_entry *) cur; 257 io_apic_entry_cnt++;382 io_apic_entry_cnt++; 258 383 ct_io_apic_entry((struct __io_apic_entry *) cur); 259 384 cur += 8; 260 385 break; 261 262 /* I/O Interrupt Assignment */ 263 case 3: 386 case 3: /* I/O Interrupt Assignment */ 264 387 io_intr_entries = io_intr_entries ? 265 388 io_intr_entries : (struct __io_intr_entry *) cur; … … 268 391 cur += 8; 269 392 break; 270 271 /* Local Interrupt Assignment */ 272 case 4: 393 case 4: /* Local Interrupt Assignment */ 273 394 l_intr_entries = l_intr_entries ? 274 395 l_intr_entries : (struct __l_intr_entry *) cur; … … 277 398 cur += 8; 278 399 break; 279 280 400 default: 281 401 /* 282 402 * Something is wrong. Fallback to UP mode. 283 403 */ 284 285 printf("%s: ct badness\n", __func__); 286 return 1; 404 printf("MPS: ct badness %" PRIu8 "\n", *cur); 405 return; 287 406 } 288 407 } … … 292 411 */ 293 412 ct_extended_entries(); 294 return cnt; 295 } 296 297 int configure_via_default(uint8_t n __attribute__((unused))) 413 } 414 415 static void configure_via_default(uint8_t n __attribute__((unused))) 298 416 { 299 417 /* 300 418 * Not yet implemented. 301 419 */ 302 printf("%s: not supported\n", __func__); 303 return 1; 304 } 305 306 307 int ct_processor_entry(struct __processor_entry *pr __attribute__((unused))) 308 { 420 printf("MPS: Default configuration not supported\n"); 421 } 422 423 void mps_init(void) 424 { 425 uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xf0000) }; 426 unsigned int i; 427 unsigned int j; 428 unsigned int length[2] = { 1024, 64 * 1024 }; 429 309 430 /* 310 * Ignore processors which are not marked enabled. 431 * Find MP Floating Pointer Structure 432 * 1a. search first 1K of EBDA 433 * 1b. if EBDA is undefined, search last 1K of base memory 434 * 2. search 64K starting at 0xf0000 311 435 */ 312 if ((pr->cpu_flags & (1 << 0)) == 0) 313 return 0; 314 315 apic_id_mask |= (1 << pr->l_apic_id); 316 return 1; 317 } 318 319 void ct_bus_entry(struct __bus_entry *bus __attribute__((unused))) 320 { 321 #ifdef MPSCT_VERBOSE 322 char buf[7]; 323 memcpy((void *) buf, (void *) bus->bus_type, 6); 324 buf[6] = 0; 325 printf("bus%d: %s\n", bus->bus_id, buf); 326 #endif 327 } 328 329 void ct_io_apic_entry(struct __io_apic_entry *ioa) 330 { 331 static unsigned int io_apic_count = 0; 332 333 /* this ioapic is marked unusable */ 334 if ((ioa->io_apic_flags & 1) == 0) 335 return; 336 337 if (io_apic_count++ > 0) { 338 /* 339 * Multiple IO APIC's are currently not supported. 340 */ 341 return; 342 } 343 344 io_apic = (uint32_t *)(uintptr_t)ioa->io_apic; 345 } 346 347 //#define MPSCT_VERBOSE 348 void ct_io_intr_entry(struct __io_intr_entry *iointr __attribute__((unused))) 349 { 350 #ifdef MPSCT_VERBOSE 351 switch (iointr->intr_type) { 352 case 0: 353 printf("INT"); 354 break; 355 case 1: 356 printf("NMI"); 357 break; 358 case 2: 359 printf("SMI"); 360 break; 361 case 3: 362 printf("ExtINT"); 363 break; 364 } 365 putchar(','); 366 switch (iointr->poel & 3) { 367 case 0: 368 printf("bus-like"); 369 break; 370 case 1: 371 printf("active high"); 372 break; 373 case 2: 374 printf("reserved"); 375 break; 376 case 3: 377 printf("active low"); 378 break; 379 } 380 putchar(','); 381 switch ((iointr->poel >> 2) & 3) { 382 case 0: 383 printf("bus-like"); 384 break; 385 case 1: 386 printf("edge-triggered"); 387 break; 388 case 2: 389 printf("reserved"); 390 break; 391 case 3: 392 printf("level-triggered"); 393 break; 394 } 395 putchar(','); 396 printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq); 397 putchar(','); 398 printf("io_apic%d,pin%d", iointr->dst_io_apic_id, 399 iointr->dst_io_apic_pin); 400 putchar('\n'); 401 #endif 402 } 403 404 void ct_l_intr_entry(struct __l_intr_entry *lintr __attribute__((unused))) 405 { 406 #ifdef MPSCT_VERBOSE 407 switch (lintr->intr_type) { 408 case 0: 409 printf("INT"); 410 break; 411 case 1: 412 printf("NMI"); 413 break; 414 case 2: 415 printf("SMI"); 416 break; 417 case 3: 418 printf("ExtINT"); 419 break; 420 } 421 putchar(','); 422 switch (lintr->poel & 3) { 423 case 0: 424 printf("bus-like"); 425 break; 426 case 1: 427 printf("active high"); 428 break; 429 case 2: 430 printf("reserved"); 431 break; 432 case 3: 433 printf("active low"); 434 break; 435 } 436 putchar(','); 437 switch ((lintr->poel >> 2) & 3) { 438 case 0: 439 printf("bus-like"); 440 break; 441 case 1: 442 printf("edge-triggered"); 443 break; 444 case 2: 445 printf("reserved"); 446 break; 447 case 3: 448 printf("level-triggered"); 449 break; 450 } 451 putchar(','); 452 printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq); 453 putchar(','); 454 printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin); 455 putchar('\n'); 456 #endif 457 } 458 459 void ct_extended_entries(void) 460 { 461 uint8_t *ext = (uint8_t *) ct + ct->base_table_length; 462 uint8_t *cur; 463 464 for (cur = ext; cur < ext + ct->ext_table_length; 465 cur += cur[CT_EXT_ENTRY_LEN]) { 466 switch (cur[CT_EXT_ENTRY_TYPE]) { 467 default: 468 printf("%p: skipping MP Configuration Table extended " 469 "entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]); 470 break; 436 437 addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024); 438 for (i = 0; i < 2; i++) { 439 for (j = 0; j < length[i]; j += 16) { 440 if ((*((uint32_t *) &addr[i][j]) == 441 FS_SIGNATURE) && (mps_fs_check(&addr[i][j]))) { 442 fs = (struct mps_fs *) &addr[i][j]; 443 goto fs_found; 444 } 471 445 } 472 446 } 473 } 474 475 int mps_irq_to_pin(unsigned int irq) 476 { 477 unsigned int i; 478 479 for (i = 0; i < io_intr_entry_cnt; i++) { 480 if (io_intr_entries[i].src_bus_irq == irq && 481 io_intr_entries[i].intr_type == 0) 482 return io_intr_entries[i].dst_io_apic_pin; 483 } 484 485 return -1; 447 448 return; 449 450 fs_found: 451 printf("%p: MPS Floating Pointer Structure\n", fs); 452 453 if ((fs->config_type == 0) && (fs->configuration_table)) { 454 if (fs->mpfib2 >> 7) { 455 printf("MPS: PIC mode not supported\n"); 456 return; 457 } 458 459 ct = (struct mps_ct *) PA2KA((uintptr_t) fs->configuration_table); 460 configure_via_ct(); 461 } else 462 configure_via_default(fs->config_type); 463 464 if (processor_entry_cnt > 0) 465 config.cpu_count = processor_entry_cnt; 486 466 } 487 467 -
kernel/arch/ia32/src/smp/smp.c
rb50b5af2 r04803bf 62 62 void smp_init(void) 63 63 { 64 uintptr_t l_apic_address, io_apic_address;65 66 64 if (acpi_madt) { 67 65 acpi_madt_parse(); 68 66 ops = &madt_config_operations; 69 67 } 68 70 69 if (config.cpu_count == 1) { 71 70 mps_init(); 72 71 ops = &mps_config_operations; 73 72 } 74 75 l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, 76 FRAME_ATOMIC | FRAME_KA); 77 if (!l_apic_address) 78 panic("Cannot allocate address for l_apic."); 79 80 io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, 81 FRAME_ATOMIC | FRAME_KA); 82 if (!io_apic_address) 83 panic("Cannot allocate address for io_apic."); 84 85 if (config.cpu_count > 1) { 86 page_mapping_insert(AS_KERNEL, l_apic_address, 87 (uintptr_t) l_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE); 88 page_mapping_insert(AS_KERNEL, io_apic_address, 89 (uintptr_t) io_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE); 90 91 l_apic = (uint32_t *) l_apic_address; 92 io_apic = (uint32_t *) io_apic_address; 73 74 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); 93 77 } 94 78 } … … 106 90 107 91 ASSERT(ops != NULL); 108 92 109 93 /* 110 94 * We need to access data in frame 0. 111 95 * We boldly make use of kernel address space mapping. 112 96 */ 113 97 114 98 /* 115 99 * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot() 116 100 */ 117 101 *((uint16_t *) (PA2KA(0x467 + 0))) = 118 (uint16_t) (((uintptr_t) ap_boot) >> 4); /* segment */119 *((uint16_t *) (PA2KA(0x467 + 2))) = 0; /* offset */102 (uint16_t) (((uintptr_t) ap_boot) >> 4); /* segment */ 103 *((uint16_t *) (PA2KA(0x467 + 2))) = 0; /* offset */ 120 104 121 105 /* … … 123 107 * BIOS will not do the POST after the INIT signal. 124 108 */ 125 pio_write_8((ioport8_t *) 0x70, 0xf);126 pio_write_8((ioport8_t *) 0x71, 0xa);127 109 pio_write_8((ioport8_t *) 0x70, 0xf); 110 pio_write_8((ioport8_t *) 0x71, 0xa); 111 128 112 pic_disable_irqs(0xffff); 129 113 apic_init(); 130 114 131 uint8_t apic = l_apic_id(); 132 133 for (i = 0; i < ops->cpu_count(); i++) { 134 descriptor_t *gdt_new; 135 115 for (i = 0; i < config.cpu_count; i++) { 136 116 /* 137 117 * Skip processors marked unusable. … … 139 119 if (!ops->cpu_enabled(i)) 140 120 continue; 141 121 142 122 /* 143 123 * The bootstrap processor is already up. … … 145 125 if (ops->cpu_bootstrap(i)) 146 126 continue; 147 148 if (ops->cpu_apic_id(i) == apic) {149 printf(" %s: bad processor entry #%u, will not send IPI "150 "to myself\n", __FUNCTION__,i);127 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); 151 131 continue; 152 132 } … … 160 140 * the memory subsystem 161 141 */ 162 gdt_new = (descriptor_t *) malloc(GDT_ITEMS * 163 sizeof(descriptor_t), FRAME_ATOMIC); 142 descriptor_t *gdt_new = 143 (descriptor_t *) malloc(GDT_ITEMS * sizeof(descriptor_t), 144 FRAME_ATOMIC); 164 145 if (!gdt_new) 165 146 panic("Cannot allocate memory for GDT."); 166 147 167 148 memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(descriptor_t)); 168 149 memsetb(&gdt_new[TSS_DES], sizeof(descriptor_t), 0); … … 170 151 protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new); 171 152 gdtr.base = (uintptr_t) gdt_new; 172 153 173 154 if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) { 174 155 /* … … 179 160 if (waitq_sleep_timeout(&ap_completion_wq, 1000000, 180 161 SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) { 181 unsigned int cpu = (config.cpu_active > i) ?182 config.cpu_active : i;183 162 printf("%s: waiting for cpu%u (APIC ID = %d) " 184 "timed out\n", __FUNCTION__, cpu,163 "timed out\n", __FUNCTION__, i, 185 164 ops->cpu_apic_id(i)); 186 165 } -
kernel/arch/ia32/src/syscall.c
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 36 36 #include <arch/cpu.h> 37 37 #include <arch/asm.h> 38 #include < arch/types.h>38 #include <typedefs.h> 39 39 #include <arch/pm.h> 40 40 … … 45 45 46 46 /* set kernel mode CS selector */ 47 write_msr(IA32_MSR_SYSENTER_CS, gdtselector(KTEXT_DES));47 write_msr(IA32_MSR_SYSENTER_CS, GDT_SELECTOR(KTEXT_DES)); 48 48 /* set kernel mode entry point */ 49 49 write_msr(IA32_MSR_SYSENTER_EIP, (uint32_t) sysenter_handler); -
kernel/arch/ia32/src/userspace.c
rb50b5af2 r04803bf 35 35 #include <userspace.h> 36 36 #include <arch/pm.h> 37 #include < arch/types.h>37 #include <typedefs.h> 38 38 #include <arch.h> 39 39 #include <proc/uarg.h> … … 70 70 "movl %[uarg], %%eax\n" 71 71 72 /* %e bxis defined to hold pcb_ptr - set it to 0 */73 "xorl %%e bx, %%ebx\n"72 /* %edi is defined to hold pcb_ptr - set it to 0 */ 73 "xorl %%edi, %%edi\n" 74 74 75 75 "iret\n" 76 76 : 77 : [udata_des] "i" ( gdtselector(UDATA_DES) | PL_USER),77 : [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER), 78 78 [stack_size] "r" ((uint8_t *) kernel_uarg->uspace_stack + THREAD_STACK_SIZE), 79 79 [ipl] "r" (ipl), 80 [utext_des] "i" ( gdtselector(UTEXT_DES) | PL_USER),80 [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER), 81 81 [entry] "r" (kernel_uarg->uspace_entry), 82 82 [uarg] "r" (kernel_uarg->uspace_uarg), 83 [tls_des] "r" ( gdtselector(TLS_DES))83 [tls_des] "r" (GDT_SELECTOR(TLS_DES)) 84 84 : "eax"); 85 85
Note:
See TracChangeset
for help on using the changeset viewer.
