Changes in / [f56e897f:e4a4b44] in mainline
- Files:
-
- 1 deleted
- 64 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/abs32le/include/atomic.h
rf56e897f re4a4b44 42 42 43 43 ATOMIC static inline void atomic_inc(atomic_t *val) 44 WRITES(&val->count)45 REQUIRES_EXTENT_MUTABLE(val)46 44 REQUIRES(val->count < ATOMIC_COUNT_MAX) 47 45 { … … 53 51 54 52 ATOMIC static inline void atomic_dec(atomic_t *val) 55 WRITES(&val->count)56 REQUIRES_EXTENT_MUTABLE(val)57 53 REQUIRES(val->count > ATOMIC_COUNT_MIN) 58 54 { … … 64 60 65 61 ATOMIC static inline atomic_count_t atomic_postinc(atomic_t *val) 66 WRITES(&val->count)67 REQUIRES_EXTENT_MUTABLE(val)68 62 REQUIRES(val->count < ATOMIC_COUNT_MAX) 69 63 { … … 79 73 80 74 ATOMIC static inline atomic_count_t atomic_postdec(atomic_t *val) 81 WRITES(&val->count)82 REQUIRES_EXTENT_MUTABLE(val)83 75 REQUIRES(val->count > ATOMIC_COUNT_MIN) 84 76 { … … 97 89 98 90 ATOMIC static inline atomic_count_t test_and_set(atomic_t *val) 99 WRITES(&val->count)100 REQUIRES_EXTENT_MUTABLE(val)101 91 { 102 92 /* On real hardware the retrieving of the original … … 109 99 } 110 100 101 ATOMIC static inline atomic_count_t arch_atomic_get(atomic_t *val) 102 { 103 /* This function is not needed on real hardware, it just 104 duplicates the functionality of atomic_get(). It is 105 defined here because atomic_get() is an inline function 106 declared in a header file which we are included in. */ 107 108 return val->count; 109 } 110 111 111 static inline void atomic_lock_arch(atomic_t *val) 112 WRITES(&val->count)113 REQUIRES_EXTENT_MUTABLE(val)114 112 { 115 113 do { 116 while ( val->count);114 while (arch_atomic_get(val)); 117 115 } while (test_and_set(val)); 118 116 } -
kernel/arch/abs32le/include/interrupt.h
rf56e897f re4a4b44 54 54 55 55 static inline int istate_from_uspace(istate_t *istate) 56 REQUIRES_EXTENT_MUTABLE(istate)57 56 { 58 57 /* On real hardware this checks whether the interrupted … … 63 62 64 63 static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr) 65 WRITES(&istate->ip)66 64 { 67 65 /* On real hardware this sets the instruction pointer. */ … … 71 69 72 70 static inline unative_t istate_get_pc(istate_t *istate) 73 REQUIRES_EXTENT_MUTABLE(istate)74 71 { 75 72 /* On real hardware this returns the instruction pointer. */ … … 79 76 80 77 static inline unative_t istate_get_fp(istate_t *istate) 81 REQUIRES_EXTENT_MUTABLE(istate)82 78 { 83 79 /* On real hardware this returns the frame pointer. */ -
kernel/arch/abs32le/include/mm/page.h
rf56e897f re4a4b44 140 140 141 141 static inline unsigned int get_pt_flags(pte_t *pt, size_t i) 142 REQUIRES_ARRAY_MUTABLE(pt, PTL0_ENTRIES_ARCH)143 142 { 144 143 pte_t *p = &pt[i]; … … 156 155 157 156 static inline void set_pt_flags(pte_t *pt, size_t i, int flags) 158 WRITES(ARRAY_RANGE(pt, PTL0_ENTRIES_ARCH))159 REQUIRES_ARRAY_MUTABLE(pt, PTL0_ENTRIES_ARCH)160 157 { 161 158 pte_t *p = &pt[i]; -
kernel/arch/amd64/Makefile.inc
rf56e897f re4a4b44 33 33 34 34 FPU_NO_CFLAGS = -mno-sse -mno-sse2 35 CMN1 = -m64 -mcmodel= large-mno-red-zone -fno-unwind-tables -fno-omit-frame-pointer35 CMN1 = -m64 -mcmodel=kernel -mno-red-zone -fno-unwind-tables -fno-omit-frame-pointer 36 36 GCC_CFLAGS += $(CMN1) 37 37 ICC_CFLAGS += $(CMN1) -
kernel/arch/amd64/_link.ld.in
rf56e897f re4a4b44 1 1 /** AMD64 linker script 2 * 2 * 3 3 * umapped section: 4 * 5 * 4 * kernel text 5 * kernel data 6 6 * mapped section: 7 * 8 * kernel data7 * kernel text 8 * kernel data 9 9 */ 10 10 … … 17 17 *(K_TEXT_START); 18 18 unmapped_ktext_end = .; 19 19 20 20 unmapped_kdata_start = .; 21 21 *(K_DATA_START); … … 23 23 unmapped_kdata_end = .; 24 24 } 25 25 26 26 .mapped (PA2KA(BOOT_OFFSET)+SIZEOF(.unmapped)) : AT (SIZEOF(.unmapped)) { 27 27 ktext_start = .; 28 28 *(.text); 29 29 ktext_end = .; 30 30 31 31 kdata_start = .; 32 *(.data); 33 *(.rodata*); 32 *(.data); /* initialized data */ 33 *(.rodata*); /* string literals */ 34 34 hardcoded_load_address = .; 35 35 QUAD(PA2KA(BOOT_OFFSET)); … … 42 42 hardcoded_unmapped_kdata_size = .; 43 43 QUAD(unmapped_kdata_end - unmapped_kdata_start); 44 *(COMMON); 45 44 *(COMMON); /* global variables */ 45 46 46 . = ALIGN(8); 47 47 symbol_table = .; 48 *(symtab.*); /* Symbol table, must be LAST symbol!*/49 50 *(.bss); 51 48 *(symtab.*); /* Symbol table, must be LAST symbol!*/ 49 50 *(.bss); /* uninitialized static variables */ 51 52 52 kdata_end = .; 53 53 } 54 54 55 55 /DISCARD/ : { 56 56 *(*); 57 57 } 58 58 59 #ifdef CONFIG_SMP 59 #ifdef CONFIG_SMP 60 60 _hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start); 61 61 ap_boot = unmapped_ap_boot - BOOT_OFFSET + AP_BOOT_OFFSET; 62 62 ap_gdtr = unmapped_ap_gdtr - BOOT_OFFSET + AP_BOOT_OFFSET; 63 63 protected_ap_gdtr = PA2KA(ap_gdtr); 64 64 65 #endif /* CONFIG_SMP */ 65 66 66 67 } -
kernel/arch/amd64/include/arch.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup amd64 29 /** @addtogroup amd64 30 30 * @{ 31 31 */ -
kernel/arch/amd64/include/boot/boot.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup amd64 29 /** @addtogroup amd64 30 30 * @{ 31 31 */ … … 36 36 #define KERN_amd64_BOOT_H_ 37 37 38 #define BOOT_OFFSET 39 #define AP_BOOT_OFFSET 0x00800040 #define BOOT_STACK_SIZE 0x00040038 #define BOOT_OFFSET 0x108000 39 #define AP_BOOT_OFFSET 0x8000 40 #define BOOT_STACK_SIZE 0x400 41 41 42 #define MULTIBOOT_HEADER_MAGIC 43 #define MULTIBOOT_HEADER_FLAGS 42 #define MULTIBOOT_HEADER_MAGIC 0x1BADB002 43 #define MULTIBOOT_HEADER_FLAGS 0x00010003 44 44 45 45 #ifndef __ASM__ -
kernel/arch/amd64/include/context.h
rf56e897f re4a4b44 59 59 */ 60 60 typedef struct { 61 62 63 64 65 66 67 68 69 70 71 72 61 uintptr_t sp; 62 uintptr_t pc; 63 64 uint64_t rbx; 65 uint64_t rbp; 66 67 uint64_t r12; 68 uint64_t r13; 69 uint64_t r14; 70 uint64_t r15; 71 72 ipl_t ipl; 73 73 } __attribute__ ((packed)) context_t; 74 74 -
kernel/arch/amd64/include/elf.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup amd64 29 /** @addtogroup amd64 30 30 * @{ 31 31 */ … … 36 36 #define KERN_amd64_ELF_H_ 37 37 38 #define ELF_MACHINEEM_X86_6439 #define ELF_DATA_ENCODING 40 #define ELF_CLASS 38 #define ELF_MACHINE EM_X86_64 39 #define ELF_DATA_ENCODING ELFDATA2LSB 40 #define ELF_CLASS ELFCLASS64 41 41 42 42 #endif -
kernel/arch/amd64/include/faddr.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup amd64 29 /** @addtogroup amd64 30 30 * @{ 31 31 */ … … 38 38 #include <typedefs.h> 39 39 40 #define FADDR(fptr) 40 #define FADDR(fptr) ((uintptr_t) (fptr)) 41 41 42 42 #endif -
kernel/arch/amd64/include/interrupt.h
rf56e897f re4a4b44 116 116 extern void trap_virtual_disable_irqs(uint16_t irqmask); 117 117 118 /* AMD64 - specific page handler */ 119 extern void ident_page_fault(unsigned int, istate_t *); 120 118 121 #endif 119 122 -
kernel/arch/amd64/include/mm/as.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup amd64mm 29 /** @addtogroup amd64mm 30 30 * @{ 31 31 */ … … 36 36 #define KERN_amd64_AS_H_ 37 37 38 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 38 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0 39 39 40 #define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0xffff800000000000 41 #define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffffffffffff 40 #define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0xffff800000000000 41 #define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffff80000000 42 #define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000 43 #define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0x00007fffffffffff 42 44 43 #define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000 44 #define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0x00007fffffffffff 45 #define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1)) 45 46 46 #define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH - (PAGE_SIZE - 1)) 47 48 #define as_constructor_arch(as, flags) (as != as) 49 #define as_destructor_arch(as) (as != as) 50 #define as_create_arch(as, flags) (as != as) 51 47 #define as_constructor_arch(as, flags) (as != as) 48 #define as_destructor_arch(as) (as != as) 49 #define as_create_arch(as, flags) (as != as) 52 50 #define as_install_arch(as) 53 51 #define as_deinstall_arch(as) -
kernel/arch/amd64/include/mm/page.h
rf56e897f re4a4b44 35 35 /** Paging on AMD64 36 36 * 37 * The space is divided in positive numbers (uspace) and 38 * negative numbers (kernel). The 'negative' space starting 39 * with 0xffff800000000000 and ending with 0xffffffffffffffff 40 * is identically mapped physical memory. 41 * 37 * The space is divided in positive numbers - userspace and 38 * negative numbers - kernel space. The 'negative' space starting 39 * with 0xffff800000000000 and ending with 0xffffffff80000000 40 * (-2GB) is identically mapped physical memory. The area 41 * (0xffffffff80000000 ... 0xffffffffffffffff is again identically 42 * mapped first 2GB. 43 * 44 * ATTENTION - PA2KA(KA2PA(x)) != x if 'x' is in kernel 42 45 */ 43 46 … … 47 50 #include <arch/mm/frame.h> 48 51 49 #define PAGE_WIDTH 50 #define PAGE_SIZE 52 #define PAGE_WIDTH FRAME_WIDTH 53 #define PAGE_SIZE FRAME_SIZE 51 54 52 55 #ifdef KERNEL 53 56 54 57 #ifndef __ASM__ 55 56 #define KA2PA(x) (((uintptr_t) (x)) - 0xffff800000000000) 57 #define PA2KA(x) (((uintptr_t) (x)) + 0xffff800000000000) 58 59 #else /* __ASM__ */ 60 61 #define KA2PA(x) ((x) - 0xffff800000000000) 62 #define PA2KA(x) ((x) + 0xffff800000000000) 63 64 #endif /* __ASM__ */ 58 # include <mm/mm.h> 59 # include <typedefs.h> 60 # include <arch/interrupt.h> 61 62 static inline uintptr_t ka2pa(uintptr_t x) 63 { 64 if (x > 0xffffffff80000000) 65 return x - 0xffffffff80000000; 66 else 67 return x - 0xffff800000000000; 68 } 69 70 # define KA2PA(x) ka2pa((uintptr_t) x) 71 # define PA2KA_CODE(x) (((uintptr_t) (x)) + 0xffffffff80000000) 72 # define PA2KA(x) (((uintptr_t) (x)) + 0xffff800000000000) 73 #else 74 # define KA2PA(x) ((x) - 0xffffffff80000000) 75 # define PA2KA(x) ((x) + 0xffffffff80000000) 76 #endif 65 77 66 78 /* Number of entries in each level. */ 67 #define PTL0_ENTRIES_ARCH 68 #define PTL1_ENTRIES_ARCH 69 #define PTL2_ENTRIES_ARCH 70 #define PTL3_ENTRIES_ARCH 79 #define PTL0_ENTRIES_ARCH 512 80 #define PTL1_ENTRIES_ARCH 512 81 #define PTL2_ENTRIES_ARCH 512 82 #define PTL3_ENTRIES_ARCH 512 71 83 72 84 /* Page table sizes for each level. */ 73 #define PTL0_SIZE_ARCH 74 #define PTL1_SIZE_ARCH 75 #define PTL2_SIZE_ARCH 76 #define PTL3_SIZE_ARCH 85 #define PTL0_SIZE_ARCH ONE_FRAME 86 #define PTL1_SIZE_ARCH ONE_FRAME 87 #define PTL2_SIZE_ARCH ONE_FRAME 88 #define PTL3_SIZE_ARCH ONE_FRAME 77 89 78 90 /* Macros calculating indices into page tables in each level. */ 79 #define PTL0_INDEX_ARCH(vaddr) 80 #define PTL1_INDEX_ARCH(vaddr) 81 #define PTL2_INDEX_ARCH(vaddr) 82 #define PTL3_INDEX_ARCH(vaddr) 91 #define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 39) & 0x1ff) 92 #define PTL1_INDEX_ARCH(vaddr) (((vaddr) >> 30) & 0x1ff) 93 #define PTL2_INDEX_ARCH(vaddr) (((vaddr) >> 21) & 0x1ff) 94 #define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x1ff) 83 95 84 96 /* Get PTE address accessors for each level. */ … … 144 156 #ifndef __ASM__ 145 157 146 #include <mm/mm.h>147 #include <arch/interrupt.h>148 #include <typedefs.h>149 150 158 /* Page fault error codes. */ 151 159 … … 153 161 * page. 154 162 */ 155 #define PFERR_CODE_P (1 << 0)163 #define PFERR_CODE_P (1 << 0) 156 164 157 165 /** When bit on this position is 1, the page fault was caused by a write. */ 158 #define PFERR_CODE_RW (1 << 1)166 #define PFERR_CODE_RW (1 << 1) 159 167 160 168 /** When bit on this position is 1, the page fault was caused in user mode. */ 161 #define PFERR_CODE_US (1 << 2)169 #define PFERR_CODE_US (1 << 2) 162 170 163 171 /** When bit on this position is 1, a reserved bit was set in page directory. */ 164 #define PFERR_CODE_RSVD (1 << 3)172 #define PFERR_CODE_RSVD (1 << 3) 165 173 166 174 /** When bit on this position os 1, the page fault was caused during instruction 167 175 * fecth. 168 176 */ 169 #define PFERR_CODE_ID 177 #define PFERR_CODE_ID (1 << 4) 170 178 171 179 /** Page Table Entry. */ 172 180 typedef struct { 173 unsigned intpresent : 1;174 unsigned intwriteable : 1;175 unsigned intuaccessible : 1;176 unsigned intpage_write_through : 1;177 unsigned intpage_cache_disable : 1;178 unsigned intaccessed : 1;179 unsigned intdirty : 1;180 unsigned intunused: 1;181 unsigned intglobal : 1;182 unsigned int soft_valid : 1;/**< Valid content even if present bit is cleared. */183 unsigned intavl : 2;184 unsigned intaddr_12_31 : 30;185 unsigned intaddr_32_51 : 21;186 unsigned intno_execute : 1;181 unsigned present : 1; 182 unsigned writeable : 1; 183 unsigned uaccessible : 1; 184 unsigned page_write_through : 1; 185 unsigned page_cache_disable : 1; 186 unsigned accessed : 1; 187 unsigned dirty : 1; 188 unsigned unused: 1; 189 unsigned global : 1; 190 unsigned soft_valid : 1; /**< Valid content even if present bit is cleared. */ 191 unsigned avl : 2; 192 unsigned addr_12_31 : 30; 193 unsigned addr_32_51 : 21; 194 unsigned no_execute : 1; 187 195 } __attribute__ ((packed)) pte_t; 188 196 … … 203 211 { 204 212 pte_t *p = &pt[i]; 205 213 206 214 p->addr_12_31 = (a >> 12) & 0xfffff; 207 215 p->addr_32_51 = a >> 32; -
kernel/arch/amd64/include/mm/ptl.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup amd64mm 29 /** @addtogroup amd64mm 30 30 * @{ 31 31 */ … … 36 36 #define KERN_amd64_PTL_H_ 37 37 38 #define PTL_NO_EXEC (1 <<63)39 #define PTL_ACCESSED (1 <<5)40 #define PTL_CACHE_DISABLE (1 <<4)41 #define PTL_CACHE_THROUGH (1 <<3)42 #define PTL_USER (1 <<2)43 #define PTL_WRITABLE (1 <<1)44 #define PTL_PRESENT 45 #define PTL_2MB_PAGE (1 <<7)38 #define PTL_NO_EXEC (1<<63) 39 #define PTL_ACCESSED (1<<5) 40 #define PTL_CACHE_DISABLE (1<<4) 41 #define PTL_CACHE_THROUGH (1<<3) 42 #define PTL_USER (1<<2) 43 #define PTL_WRITABLE (1<<1) 44 #define PTL_PRESENT 1 45 #define PTL_2MB_PAGE (1<<7) 46 46 47 47 -
kernel/arch/amd64/include/mm/tlb.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup amd64mm 29 /** @addtogroup amd64mm 30 30 * @{ 31 31 */ -
kernel/arch/amd64/include/pm.h
rf56e897f re4a4b44 71 71 #define PL_USER 3 72 72 73 #define AR_PRESENT (1 << 7)73 #define AR_PRESENT ( 1 << 7) 74 74 #define AR_DATA (2 << 3) 75 75 #define AR_CODE (3 << 3) -
kernel/arch/amd64/include/proc/thread.h
rf56e897f re4a4b44 37 37 38 38 /* CAUTION: keep these in sync with low level assembly code in syscall_entry */ 39 #define SYSCALL_USTACK_RSP 40 #define SYSCALL_KSTACK_RSP 39 #define SYSCALL_USTACK_RSP 0 40 #define SYSCALL_KSTACK_RSP 1 41 41 42 42 typedef struct { 43 43 unative_t tls; 44 44 /** User and kernel RSP for syscalls. */ 45 uint64_t syscall_rsp[2]; 45 uint64_t syscall_rsp[2]; 46 46 } thread_arch_t; 47 47 -
kernel/arch/amd64/src/amd64.c
rf56e897f re4a4b44 122 122 /* Enable FPU */ 123 123 cpu_setup_fpu(); 124 124 125 125 /* Initialize segmentation */ 126 126 pm_init(); … … 132 132 /* Disable alignment check */ 133 133 clean_AM_flag(); 134 134 135 135 if (config.cpu_active == 1) { 136 136 interrupt_init(); … … 260 260 THREAD->arch.tls = addr; 261 261 write_msr(AMD_MSR_FS, addr); 262 263 262 return 0; 264 263 } -
kernel/arch/amd64/src/asm_utils.S
rf56e897f re4a4b44 27 27 # 28 28 29 #define IREGISTER_SPACE 80 30 31 #define IOFFSET_RAX 0x00 32 #define IOFFSET_RCX 0x08 33 #define IOFFSET_RDX 0x10 34 #define IOFFSET_RSI 0x18 35 #define IOFFSET_RDI 0x20 36 #define IOFFSET_R8 0x28 37 #define IOFFSET_R9 0x30 38 #define IOFFSET_R10 0x38 39 #define IOFFSET_R11 0x40 40 #define IOFFSET_RBP 0x48 41 42 # Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int 43 # has no error word and 1 means interrupt with error word 44 45 #define ERROR_WORD_INTERRUPT_LIST 0x00027D00 29 #define IREGISTER_SPACE 80 30 31 #define IOFFSET_RAX 0x0 32 #define IOFFSET_RCX 0x8 33 #define IOFFSET_RDX 0x10 34 #define IOFFSET_RSI 0x18 35 #define IOFFSET_RDI 0x20 36 #define IOFFSET_R8 0x28 37 #define IOFFSET_R9 0x30 38 #define IOFFSET_R10 0x38 39 #define IOFFSET_R11 0x40 40 #define IOFFSET_RBP 0x48 41 42 # Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word 43 # and 1 means interrupt with error word 44 #define ERROR_WORD_INTERRUPT_LIST 0x00027D00 46 45 47 46 #include <arch/pm.h> 48 47 #include <arch/mm/page.h> 49 48 50 49 .text 51 50 .global interrupt_handlers 52 51 .global syscall_entry 52 53 53 .global cpuid 54 54 .global has_cpuid … … 71 71 jmp _memsetw 72 72 73 #define MEMCPY_DST 74 #define MEMCPY_SRC 75 #define MEMCPY_SIZE 73 #define MEMCPY_DST %rdi 74 #define MEMCPY_SRC %rsi 75 #define MEMCPY_SIZE %rdx 76 76 77 77 /** … … 84 84 * or copy_to_uspace(). 85 85 * 86 * @param MEMCPY_DST 87 * @param MEMCPY_SRC 88 * @param MEMCPY_SIZE 86 * @param MEMCPY_DST Destination address. 87 * @param MEMCPY_SRC Source address. 88 * @param MEMCPY_SIZE Number of bytes to copy. 89 89 * 90 90 * @retrun MEMCPY_DST on success, 0 on failure. 91 *92 91 */ 93 92 memcpy: … … 95 94 memcpy_to_uspace: 96 95 movq MEMCPY_DST, %rax 97 96 98 97 movq MEMCPY_SIZE, %rcx 99 shrq $3, %rcx 100 101 rep movsq 102 98 shrq $3, %rcx /* size / 8 */ 99 100 rep movsq /* copy as much as possible word by word */ 101 103 102 movq MEMCPY_SIZE, %rcx 104 andq $7, %rcx 103 andq $7, %rcx /* size % 8 */ 105 104 jz 0f 106 105 107 rep movsb 108 109 110 ret/* return MEMCPY_SRC, success */106 rep movsb /* copy the rest byte by byte */ 107 108 0: 109 ret /* return MEMCPY_SRC, success */ 111 110 112 111 memcpy_from_uspace_failover_address: 113 112 memcpy_to_uspace_failover_address: 114 xorq %rax, %rax 113 xorq %rax, %rax /* return 0, failure */ 115 114 ret 116 115 … … 120 119 # 121 120 has_cpuid: 122 pushfq 123 popq %rax 124 movq %rax, %rdx# copy flags125 btcl $21, %edx# swap the ID bit121 pushfq # store flags 122 popq %rax # read flags 123 movq %rax,%rdx # copy flags 124 btcl $21,%edx # swap the ID bit 126 125 pushq %rdx 127 popfq 126 popfq # propagate the change into flags 128 127 pushfq 129 popq %rdx # read flags130 andl $(1 << 21), %eax# interested only in ID bit131 andl $(1 << 21),%edx132 xorl %edx, %eax# 0 if not supported, 1 if supported128 popq %rdx # read flags 129 andl $(1<<21),%eax # interested only in ID bit 130 andl $(1<<21),%edx 131 xorl %edx,%eax # 0 if not supported, 1 if supported 133 132 ret 134 133 135 134 cpuid: 136 movq %rbx, %r10 137 138 movl %edi,%eax 139 140 cpuid 141 movl %eax, 142 movl %ebx, 143 movl %ecx, 144 movl %edx, 145 135 movq %rbx, %r10 # we have to preserve rbx across function calls 136 137 movl %edi,%eax # load the command into %eax 138 139 cpuid 140 movl %eax,0(%rsi) 141 movl %ebx,4(%rsi) 142 movl %ecx,8(%rsi) 143 movl %edx,12(%rsi) 144 146 145 movq %r10, %rbx 147 146 ret … … 153 152 wrmsr 154 153 ret 155 154 156 155 read_efer_flag: 157 156 movq $0xc0000080, %rcx 158 157 rdmsr 159 ret 158 ret 160 159 161 160 # Push all volatile general purpose registers on stack … … 186 185 .endm 187 186 188 #define INTERRUPT_ALIGN 189 187 #define INTERRUPT_ALIGN 128 188 190 189 ## Declare interrupt handlers 191 190 # … … 196 195 # 197 196 .macro handler i n 198 197 199 198 /* 200 199 * Choose between version with error code and version without error … … 205 204 * Therefore we align the interrupt handlers. 206 205 */ 207 206 208 207 .iflt \i-32 209 208 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST … … 216 215 * Version without error word, 217 216 */ 218 subq $(IREGISTER_SPACE +8), %rsp217 subq $(IREGISTER_SPACE+8), %rsp 219 218 .endif 220 219 .else … … 222 221 * Version without error word, 223 222 */ 224 subq $(IREGISTER_SPACE +8), %rsp225 .endif 226 223 subq $(IREGISTER_SPACE+8), %rsp 224 .endif 225 227 226 save_all_gpr 228 227 cld … … 242 241 restore_all_gpr 243 242 # $8 = Skip error word 244 addq $(IREGISTER_SPACE +8), %rsp243 addq $(IREGISTER_SPACE+8), %rsp 245 244 iretq 246 245 247 246 .align INTERRUPT_ALIGN 248 .if (\n - \i) -1249 handler "(\i + 1)",\n247 .if (\n-\i)-1 248 handler "(\i+1)",\n 250 249 .endif 251 250 .endm … … 253 252 .align INTERRUPT_ALIGN 254 253 interrupt_handlers: 255 256 257 254 h_start: 255 handler 0 IDT_ITEMS 256 h_end: 258 257 259 258 ## Low-level syscall handler 260 # 259 # 261 260 # Registers on entry: 262 261 # 263 # @param rcx 264 # @param r11 265 # 266 # @param rax 267 # @param rdi 268 # @param rsi 269 # @param rdx 270 # @param r10 4th syscall argument. Used instead of RCX because271 # theSYSCALL instruction clobbers it.272 # @param r8 273 # @param r9 274 # 275 # @return 262 # @param rcx Userspace return address. 263 # @param r11 Userspace RLFAGS. 264 # 265 # @param rax Syscall number. 266 # @param rdi 1st syscall argument. 267 # @param rsi 2nd syscall argument. 268 # @param rdx 3rd syscall argument. 269 # @param r10 4th syscall argument. Used instead of RCX because the 270 # SYSCALL instruction clobbers it. 271 # @param r8 5th syscall argument. 272 # @param r9 6th syscall argument. 273 # 274 # @return Return value is in rax. 276 275 # 277 276 syscall_entry: 278 swapgs # Switch to hidden gs 277 swapgs # Switch to hidden gs 278 # 279 # %gs:0 Scratch space for this thread's user RSP 280 # %gs:8 Address to be used as this thread's kernel RSP 279 281 # 280 # %gs:0 Scratch space for this thread's user RSP 281 # %gs:8 Address to be used as this thread's kernel RSP 282 # 283 movq %rsp, %gs:0 # Save this thread's user RSP 284 movq %gs:8, %rsp # Set this thread's kernel RSP 285 swapgs # Switch back to remain consistent 282 movq %rsp, %gs:0 # Save this thread's user RSP 283 movq %gs:8, %rsp # Set this thread's kernel RSP 284 swapgs # Switch back to remain consistent 286 285 sti 287 286 … … 300 299 popq %r11 301 300 popq %rcx 302 301 303 302 cli 304 303 swapgs 305 movq %gs:0, %rsp 304 movq %gs:0, %rsp # Restore the user RSP 306 305 swapgs 307 306 308 307 sysretq 309 308 … … 311 310 .global interrupt_handler_size 312 311 313 interrupt_handler_size: .quad (h_end - h_start) /IDT_ITEMS312 interrupt_handler_size: .quad (h_end-h_start)/IDT_ITEMS -
kernel/arch/amd64/src/boot/boot.S
rf56e897f re4a4b44 31 31 #include <arch/boot/boot.h> 32 32 #include <arch/boot/memmap.h> 33 #include <arch/mm/page.h> 33 #include <arch/mm/page.h> 34 34 #include <arch/mm/ptl.h> 35 35 #include <arch/pm.h> … … 172 172 xorq %rsi, %rsi 173 173 movl grub_ebx, %esi 174 175 movabsq $arch_pre_main, %rax 176 callq *%rax 174 call arch_pre_main 177 175 178 176 # create the first stack frame 179 177 pushq $0 180 178 movq %rsp, %rbp 181 182 movabsq $main_bsp, %rax 183 call *%rax 179 180 call main_bsp 184 181 185 182 # not reached … … 259 256 # 260 257 # Macro for generating initial page table contents. 261 # @param cnt Number of entries to generat e. Must be multiple of 8.258 # @param cnt Number of entries to generat. Must be multiple of 8. 262 259 # @param g Number of GB that will be added to the mapping. 263 260 # 264 .macro ptl2gen cnt g 265 266 ptl2gen "\cnt - 8" \g267 268 269 270 271 272 273 274 275 261 .macro ptl2gen cnt g 262 .if \cnt 263 ptl2gen "\cnt - 8" \g 264 .quad ((\cnt - 8) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 265 .quad ((\cnt - 7) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 266 .quad ((\cnt - 6) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 267 .quad ((\cnt - 5) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 268 .quad ((\cnt - 4) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 269 .quad ((\cnt - 3) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 270 .quad ((\cnt - 2) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 271 .quad ((\cnt - 1) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 272 .endif 276 273 .endm 277 274 278 # Page table for pages in the 1st gigabyte. 279 .align 4096 280 ptl_2_0g: 275 # Page table for pages in the first gigabyte. 276 .align 4096 277 .global ptl_2_0g 278 ptl_2_0g: 281 279 ptl2gen 512 0 282 280 283 # Page table for pages in the 2nd gigabyte. 284 .align 4096 281 # Page table for pages in the second gigabyte. 282 .align 4096 283 .global ptl_2_1g 285 284 ptl_2_1g: 286 285 ptl2gen 512 1 287 286 288 # Page table for pages in the 3rd gigabyte. 289 .align 4096 287 # Page table for pages in the third gigabyte. 288 .align 4096 289 .global ptl_2_2g 290 290 ptl_2_2g: 291 291 ptl2gen 512 2 292 292 293 # Page table for pages in the 4th gigabyte. 294 .align 4096 293 # Page table for pages in the fourth gigabyte. 294 .align 4096 295 .global ptl_2_3g 295 296 ptl_2_3g: 296 297 ptl2gen 512 3 297 298 298 # Page table for pages in the 5th gigabyte. 299 .align 4096 300 ptl_2_4g: 301 ptl2gen 512 3 302 303 # Page table for pages in the 6th gigabyte. 304 .align 4096 305 ptl_2_5g: 306 ptl2gen 512 3 307 308 # Page table for pages in the 7th gigabyte. 309 .align 4096 310 ptl_2_6g: 311 ptl2gen 512 3 312 313 # Page table for pages in the 8th gigabyte. 314 .align 4096 315 ptl_2_7g: 316 ptl2gen 512 3 317 318 .align 4096 299 .align 4096 300 .global ptl_1 319 301 ptl_1: 320 # Identity mapping for [0; 8G)302 # Identity mapping for [0; 4G) 321 303 .quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT) 322 .quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT) 304 .quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT) 323 305 .quad ptl_2_2g + (PTL_WRITABLE | PTL_PRESENT) 324 306 .quad ptl_2_3g + (PTL_WRITABLE | PTL_PRESENT) 325 .quad ptl_2_4g + (PTL_WRITABLE | PTL_PRESENT) 326 .quad ptl_2_5g + (PTL_WRITABLE | PTL_PRESENT) 327 .quad ptl_2_6g + (PTL_WRITABLE | PTL_PRESENT) 328 .quad ptl_2_7g + (PTL_WRITABLE | PTL_PRESENT) 329 .fill 504, 8, 0 307 .fill 506, 8, 0 308 # Mapping of [0; 1G) at -2G 309 .quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT) 310 .fill 1, 8, 0 330 311 331 312 .align 4096 … … 333 314 ptl_0: 334 315 .quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT) 335 .fill 255, 8,0316 .fill 255,8,0 336 317 .quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT) 337 .fill 255, 8, 0 318 .fill 254,8,0 319 .quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT) 338 320 339 321 .section K_DATA_START, "aw", @progbits -
kernel/arch/amd64/src/context.S
rf56e897f re4a4b44 41 41 context_save_arch: 42 42 movq (%rsp), %rdx # the caller's return %eip 43 44 # In %edi is passed 1st argument 45 CONTEXT_SAVE_ARCH_CORE %rdi %rdx 43 46 44 # 1st argument passed in %edi 45 CONTEXT_SAVE_ARCH_CORE %rdi %rdx 46 47 xorq %rax, %rax # context_save returns 1 47 xorq %rax,%rax # context_save returns 1 48 48 incq %rax 49 49 ret … … 55 55 # pointed by the 1st argument. Returns 0 in EAX. 56 56 # 57 context_restore_arch: 57 context_restore_arch: 58 58 59 CONTEXT_RESTORE_ARCH_CORE %rdi %rdx 59 60 movq %rdx, 61 62 xorq %rax, %rax# context_restore returns 060 61 movq %rdx,(%rsp) 62 63 xorq %rax,%rax # context_restore returns 0 63 64 ret -
kernel/arch/amd64/src/cpu/cpu.c
rf56e897f re4a4b44 47 47 * Contains only non-MP-Specification specific SMP code. 48 48 */ 49 #define AMD_CPUID_EBX 50 #define AMD_CPUID_ECX 51 #define AMD_CPUID_EDX 49 #define AMD_CPUID_EBX 0x68747541 50 #define AMD_CPUID_ECX 0x444d4163 51 #define AMD_CPUID_EDX 0x69746e65 52 52 53 #define INTEL_CPUID_EBX 54 #define INTEL_CPUID_ECX 55 #define INTEL_CPUID_EDX 53 #define INTEL_CPUID_EBX 0x756e6547 54 #define INTEL_CPUID_ECX 0x6c65746e 55 #define INTEL_CPUID_EDX 0x49656e69 56 56 57 57 … … 127 127 { 128 128 cpu_info_t info; 129 129 130 130 CPU->arch.vendor = VendorUnknown; 131 131 if (has_cpuid()) { 132 132 cpuid(INTEL_CPUID_LEVEL, &info); 133 133 134 134 /* 135 135 * Check for AMD processor. 136 136 */ 137 if ( (info.cpuid_ebx == AMD_CPUID_EBX)&&138 (info.cpuid_ecx == AMD_CPUID_ECX)&&139 (info.cpuid_edx == AMD_CPUID_EDX)) {137 if (info.cpuid_ebx == AMD_CPUID_EBX && 138 info.cpuid_ecx == AMD_CPUID_ECX && 139 info.cpuid_edx == AMD_CPUID_EDX) { 140 140 CPU->arch.vendor = VendorAMD; 141 141 } 142 142 143 143 /* 144 144 * Check for Intel processor. 145 */ 146 if ( (info.cpuid_ebx == INTEL_CPUID_EBX)&&147 (info.cpuid_ecx == INTEL_CPUID_ECX)&&148 (info.cpuid_edx == INTEL_CPUID_EDX)) {145 */ 146 if (info.cpuid_ebx == INTEL_CPUID_EBX && 147 info.cpuid_ecx == INTEL_CPUID_ECX && 148 info.cpuid_edx == INTEL_CPUID_EDX) { 149 149 CPU->arch.vendor = VendorIntel; 150 150 } 151 151 152 152 cpuid(INTEL_CPUID_STANDARD, &info); 153 153 CPU->arch.family = (info.cpuid_eax >> 8) & 0xf; 154 154 CPU->arch.model = (info.cpuid_eax >> 4) & 0xf; 155 CPU->arch.stepping = (info.cpuid_eax >> 0) & 0xf; 155 CPU->arch.stepping = (info.cpuid_eax >> 0) & 0xf; 156 156 } 157 157 } -
kernel/arch/amd64/src/debug/stacktrace.c
rf56e897f re4a4b44 37 37 #include <typedefs.h> 38 38 39 #define FRAME_OFFSET_FP_PREV 40 #define FRAME_OFFSET_RA 39 #define FRAME_OFFSET_FP_PREV 0 40 #define FRAME_OFFSET_RA 1 41 41 42 42 bool kernel_frame_pointer_validate(uintptr_t fp) … … 49 49 uint64_t *stack = (void *) fp; 50 50 *prev = stack[FRAME_OFFSET_FP_PREV]; 51 52 51 return true; 53 52 } … … 57 56 uint64_t *stack = (void *) fp; 58 57 *ra = stack[FRAME_OFFSET_RA]; 59 60 58 return true; 61 59 } -
kernel/arch/amd64/src/delay.S
rf56e897f re4a4b44 37 37 38 38 asm_delay_loop: 39 0: 40 dec %rdi 41 jnz 0b 42 39 0: dec %rdi 40 jnz 0b 43 41 ret 44 42 45 43 asm_fake_loop: 46 0: 47 dec %rdi 48 jz 0b 49 44 0: dec %rdi 45 jz 0b 50 46 ret -
kernel/arch/amd64/src/fpu_context.c
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup amd64 29 /** @addtogroup amd64 30 30 * @{ 31 31 */ -
kernel/arch/amd64/src/interrupt.c
rf56e897f re4a4b44 202 202 exc_register(12, "ss_fault", true, (iroutine_t) ss_fault); 203 203 exc_register(13, "gp_fault", true, (iroutine_t) gp_fault); 204 exc_register(14, "ident_mapper", true, (iroutine_t) ident_page_fault); 204 205 205 206 #ifdef CONFIG_SMP -
kernel/arch/amd64/src/mm/page.c
rf56e897f re4a4b44 39 39 #include <mm/frame.h> 40 40 #include <mm/as.h> 41 #include <arch/interrupt.h> 41 42 #include <arch/asm.h> 42 43 #include <config.h> … … 47 48 #include <align.h> 48 49 50 /* Definitions for identity page mapper */ 51 pte_t helper_ptl1[512] __attribute__((aligned (PAGE_SIZE))); 52 pte_t helper_ptl2[512] __attribute__((aligned (PAGE_SIZE))); 53 pte_t helper_ptl3[512] __attribute__((aligned (PAGE_SIZE))); 54 extern pte_t ptl_0; /* From boot.S */ 55 56 #define PTL1_PRESENT(ptl0, page) (!(GET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) 57 #define PTL2_PRESENT(ptl1, page) (!(GET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) 58 #define PTL3_PRESENT(ptl2, page) (!(GET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) 59 60 #define PTL1_ADDR(ptl0, page) ((pte_t *)PA2KA(GET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page)))) 61 #define PTL2_ADDR(ptl1, page) ((pte_t *)PA2KA(GET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page)))) 62 #define PTL3_ADDR(ptl2, page) ((pte_t *)PA2KA(GET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page)))) 63 64 #define SETUP_PTL1(ptl0, page, tgt) { \ 65 SET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \ 66 SET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ 67 } 68 #define SETUP_PTL2(ptl1, page, tgt) { \ 69 SET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \ 70 SET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ 71 } 72 #define SETUP_PTL3(ptl2, page, tgt) { \ 73 SET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \ 74 SET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ 75 } 76 #define SETUP_FRAME(ptl3, page, tgt) { \ 77 SET_FRAME_ADDRESS_ARCH(ptl3, PTL3_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \ 78 SET_FRAME_FLAGS_ARCH(ptl3, PTL3_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ 79 } 80 81 49 82 void page_arch_init(void) 50 83 { 84 uintptr_t cur; 85 unsigned int i; 86 int identity_flags = PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE; 87 51 88 if (config.cpu_active == 1) { 52 uintptr_t cur;53 unsigned int identity_flags =54 PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;55 56 89 page_mapping_operations = &pt_mapping_operations; 57 90 58 91 page_table_lock(AS_KERNEL, true); 59 92 60 93 /* 61 94 * PA2KA(identity) mapping for all frames. 62 95 */ 63 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) 96 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) { 97 /* Standard identity mapping */ 64 98 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags); 99 } 65 100 101 /* Upper kernel mapping 102 * - from zero to top of kernel (include bottom addresses 103 * because some are needed for init) 104 */ 105 for (cur = PA2KA_CODE(0); cur < config.base + config.kernel_size; cur += FRAME_SIZE) 106 page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags); 107 108 for (cur = config.stack_base; cur < config.stack_base + config.stack_size; cur += FRAME_SIZE) 109 page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags); 110 111 for (i = 0; i < init.cnt; i++) { 112 for (cur = init.tasks[i].addr; cur < init.tasks[i].addr + init.tasks[i].size; cur += FRAME_SIZE) 113 page_mapping_insert(AS_KERNEL, PA2KA_CODE(KA2PA(cur)), KA2PA(cur), identity_flags); 114 } 115 66 116 page_table_unlock(AS_KERNEL, true); 67 117 68 118 exc_register(14, "page_fault", true, (iroutine_t) page_fault); 69 119 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); … … 72 122 } 73 123 124 125 /** Identity page mapper 126 * 127 * We need to map whole physical memory identically before the page subsystem 128 * is initializaed. This thing clears page table and fills in the specific 129 * items. 130 */ 131 void ident_page_fault(unsigned int n, istate_t *istate) 132 { 133 uintptr_t page; 134 static uintptr_t oldpage = 0; 135 pte_t *aptl_1, *aptl_2, *aptl_3; 136 137 page = read_cr2(); 138 if (oldpage) { 139 /* Unmap old address */ 140 aptl_1 = PTL1_ADDR(&ptl_0, oldpage); 141 aptl_2 = PTL2_ADDR(aptl_1, oldpage); 142 aptl_3 = PTL3_ADDR(aptl_2, oldpage); 143 144 SET_FRAME_FLAGS_ARCH(aptl_3, PTL3_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 145 if (KA2PA(aptl_3) == KA2PA(helper_ptl3)) 146 SET_PTL3_FLAGS_ARCH(aptl_2, PTL2_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 147 if (KA2PA(aptl_2) == KA2PA(helper_ptl2)) 148 SET_PTL2_FLAGS_ARCH(aptl_1, PTL1_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 149 if (KA2PA(aptl_1) == KA2PA(helper_ptl1)) 150 SET_PTL1_FLAGS_ARCH(&ptl_0, PTL0_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 151 } 152 if (PTL1_PRESENT(&ptl_0, page)) 153 aptl_1 = PTL1_ADDR(&ptl_0, page); 154 else { 155 SETUP_PTL1(&ptl_0, page, helper_ptl1); 156 aptl_1 = helper_ptl1; 157 } 158 159 if (PTL2_PRESENT(aptl_1, page)) 160 aptl_2 = PTL2_ADDR(aptl_1, page); 161 else { 162 SETUP_PTL2(aptl_1, page, helper_ptl2); 163 aptl_2 = helper_ptl2; 164 } 165 166 if (PTL3_PRESENT(aptl_2, page)) 167 aptl_3 = PTL3_ADDR(aptl_2, page); 168 else { 169 SETUP_PTL3(aptl_2, page, helper_ptl3); 170 aptl_3 = helper_ptl3; 171 } 172 173 SETUP_FRAME(aptl_3, page, page); 174 175 oldpage = page; 176 } 177 178 74 179 void page_fault(unsigned int n, istate_t *istate) 75 180 { 76 uintptr_t page = read_cr2(); 181 uintptr_t page; 182 pf_access_t access; 183 184 page = read_cr2(); 77 185 78 186 if (istate->error_word & PFERR_CODE_RSVD) 79 187 panic("Reserved bit set in page table entry."); 80 81 pf_access_t access;82 188 83 189 if (istate->error_word & PFERR_CODE_RW) … … 94 200 } 95 201 202 96 203 uintptr_t hw_map(uintptr_t physaddr, size_t size) 97 204 { 98 205 if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) 99 panic("Unable to map physical memory %p (% " PRIs "bytes).", physaddr,206 panic("Unable to map physical memory %p (%d bytes).", physaddr, 100 207 size); 101 208 102 209 uintptr_t virtaddr = PA2KA(last_frame); 103 210 pfn_t i; 104 211 105 212 page_table_lock(AS_KERNEL, true); 106 107 213 for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) 108 214 page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE); 109 110 215 page_table_unlock(AS_KERNEL, true); 111 216 -
kernel/arch/amd64/src/proc/scheduler.c
rf56e897f re4a4b44 38 38 #include <proc/thread.h> 39 39 #include <arch.h> 40 #include <arch/context.h> 40 #include <arch/context.h> /* SP_DELTA */ 41 41 #include <arch/asm.h> 42 42 #include <print.h> … … 58 58 CPU->arch.tss->rsp0 = 59 59 (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA]; 60 60 61 61 /* 62 62 * Syscall support. 63 63 */ 64 64 swapgs(); 65 write_msr(AMD_MSR_GS, (uintptr_t) 65 write_msr(AMD_MSR_GS, (uintptr_t)THREAD->arch.syscall_rsp); 66 66 swapgs(); 67 67 68 68 /* TLS support - set FS to thread local storage */ 69 69 write_msr(AMD_MSR_FS, THREAD->arch.tls); -
kernel/arch/amd64/src/proc/task.c
rf56e897f re4a4b44 39 39 /** Perform amd64 specific task initialization. 40 40 * 41 * @param task Task to be initialized. 42 * 41 * @param t Task to be initialized. 43 42 */ 44 void task_create_arch(task_t *t ask)43 void task_create_arch(task_t *t) 45 44 { 46 t ask->arch.iomapver = 0;47 bitmap_initialize(&t ask->arch.iomap, NULL, 0);45 t->arch.iomapver = 0; 46 bitmap_initialize(&t->arch.iomap, NULL, 0); 48 47 } 49 48 50 49 /** Perform amd64 specific task destruction. 51 50 * 52 * @param task Task to be initialized. 53 * 51 * @param t Task to be initialized. 54 52 */ 55 void task_destroy_arch(task_t *t ask)53 void task_destroy_arch(task_t *t) 56 54 { 57 if (t ask->arch.iomap.map)58 free(t ask->arch.iomap.map);55 if (t->arch.iomap.map) 56 free(t->arch.iomap.map); 59 57 } 60 58 -
kernel/arch/amd64/src/proc/thread.c
rf56e897f re4a4b44 37 37 /** Perform amd64 specific thread initialization. 38 38 * 39 * @param thread Thread to be initialized. 40 * 39 * @param t Thread to be initialized. 41 40 */ 42 void thread_create_arch(thread_t *t hread)41 void thread_create_arch(thread_t *t) 43 42 { 44 thread->arch.tls = 0; 45 thread->arch.syscall_rsp[SYSCALL_USTACK_RSP] = 0; 46 43 t->arch.tls = 0; 44 t->arch.syscall_rsp[SYSCALL_USTACK_RSP] = 0; 47 45 /* 48 46 * Kernel RSP can be precalculated at thread creation time. 49 47 */ 50 t hread->arch.syscall_rsp[SYSCALL_KSTACK_RSP] =51 (uintptr_t) &t hread->kstack[PAGE_SIZE - sizeof(uint64_t)];48 t->arch.syscall_rsp[SYSCALL_KSTACK_RSP] = 49 (uintptr_t) &t->kstack[PAGE_SIZE - sizeof(uint64_t)]; 52 50 } 53 51 -
kernel/arch/amd64/src/smp/ap.S
rf56e897f re4a4b44 55 55 xorw %ax, %ax 56 56 movw %ax, %ds 57 58 lgdtl ap_gdtr 57 58 lgdtl ap_gdtr # initialize Global Descriptor Table register 59 59 60 60 movl %cr0, %eax 61 61 orl $1, %eax 62 movl %eax, %cr0 62 movl %eax, %cr0 # switch to protected mode 63 63 jmpl $gdtselector(KTEXT32_DES), $jump_to_kernel - BOOT_OFFSET + AP_BOOT_OFFSET 64 64 65 65 jump_to_kernel: 66 66 .code32 … … 72 72 movw %ax, %gs 73 73 74 # Enable 64-bit page transaltion entries (CR4.PAE = 1).74 # Enable 64-bit page transaltion entries - CR4.PAE = 1. 75 75 # Paging is not enabled until after long mode is enabled 76 76 … … 78 78 btsl $5, %eax 79 79 movl %eax, %cr4 80 80 81 81 leal ptl_0, %eax 82 82 movl %eax, %cr3 83 83 84 84 # Enable long mode 85 movl $EFER_MSR_NUM, %ecx 86 rdmsr 87 btsl $AMD_LME_FLAG, %eax 88 wrmsr 85 movl $EFER_MSR_NUM, %ecx # EFER MSR number 86 rdmsr # Read EFER 87 btsl $AMD_LME_FLAG, %eax # Set LME=1 88 wrmsr # Write EFER 89 89 90 # Enable paging to activate long mode (set CR0.PG =1)90 # Enable paging to activate long mode (set CR0.PG=1) 91 91 movl %cr0, %eax 92 92 btsl $31, %eax … … 98 98 .code64 99 99 start64: 100 movabsq $ctx, %rsp 101 movq (%rsp), %rsp 102 100 movq (ctx), %rsp 103 101 pushq $0 104 102 movq %rsp, %rbp 105 106 movabsq $main_ap, %rax 107 callq *%rax # never returns 103 call main_ap - AP_BOOT_OFFSET + BOOT_OFFSET # never returns 108 104 109 105 #endif /* CONFIG_SMP */ -
kernel/arch/ia32/include/bios/bios.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 38 38 #include <typedefs.h> 39 39 40 #define BIOS_EBDA_PTR 40 #define BIOS_EBDA_PTR 0x40e 41 41 42 42 extern uintptr_t ebda; -
kernel/arch/ia32/include/drivers/i8259.h
rf56e897f re4a4b44 48 48 49 49 extern void i8259_init(void); 50 extern void pic_enable_irqs(uint16_t );51 extern void pic_disable_irqs(uint16_t );50 extern void pic_enable_irqs(uint16_t irqmask); 51 extern void pic_disable_irqs(uint16_t irqmask); 52 52 extern void pic_eoi(void); 53 53 -
kernel/arch/ia32/include/fpu_context.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 38 38 #include <typedefs.h> 39 39 40 #define FPU_CONTEXT_ALIGN 16 40 #define FPU_CONTEXT_ALIGN 16 41 42 void fpu_fxsr(void); 43 void fpu_fsr(void); 44 41 45 42 46 typedef struct { 43 uint8_t fpu[512]; 47 uint8_t fpu[512]; /* FXSAVE & FXRSTOR storage area */ 44 48 } fpu_context_t; 45 46 extern void fpu_fxsr(void);47 extern void fpu_fsr(void);48 49 49 50 #endif -
kernel/arch/ia32/include/mm/asid.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup ia32mm 29 /** @addtogroup ia32mm 30 30 * @{ 31 31 */ … … 47 47 typedef int32_t asid_t; 48 48 49 #define ASID_MAX_ARCH 49 #define ASID_MAX_ARCH 3 50 50 51 #define asid_get() 51 #define asid_get() (ASID_START + 1) 52 52 #define asid_put(asid) 53 53 -
kernel/arch/ia32/include/smp/mps.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 41 41 #include <arch/smp/smp.h> 42 42 43 #define CT_EXT_ENTRY_TYPE 44 #define CT_EXT_ENTRY_LEN 43 #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 reserved;72 uint8_t xxx; 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 reserved[2];83 uint32_t xxx[2]; 84 84 } __attribute__ ((packed)); 85 85 … … 102 102 uint8_t intr_type; 103 103 uint8_t poel; 104 uint8_t reserved;104 uint8_t xxx; 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 reserved;115 uint8_t xxx; 116 116 uint8_t src_bus_id; 117 117 uint8_t src_bus_irq; -
kernel/arch/ia32/include/smp/smp.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 40 40 /** SMP config opertaions interface. */ 41 41 struct smp_config_operations { 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); 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. */ 53 47 }; 54 48 55 extern int smp_irq_to_pin(unsigned int );49 extern int smp_irq_to_pin(unsigned int irq); 56 50 57 51 #endif -
kernel/arch/ia32/src/bios/bios.c
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ -
kernel/arch/ia32/src/ia32.c
rf56e897f re4a4b44 139 139 { 140 140 #ifdef CONFIG_SMP 141 141 if (config.cpu_active > 1) { 142 142 l_apic_init(); 143 143 l_apic_debug(); -
kernel/arch/ia32/src/mm/as.c
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup ia32mm 29 /** @addtogroup ia32mm 30 30 * @{ 31 31 */ -
kernel/arch/ia32/src/mm/frame.c
rf56e897f re4a4b44 47 47 #include <print.h> 48 48 49 #define PHYSMEM_LIMIT32 0x07c000000ull50 #define PHYSMEM_LIMIT64 0x200000000ull51 52 49 size_t hardcoded_unmapped_ktext_size = 0; 53 50 size_t hardcoded_unmapped_kdata_size = 0; … … 58 55 { 59 56 unsigned int i; 60 57 61 58 for (i = 0; i < e820counter; i++) { 62 59 uint64_t base = e820table[i].base_address; … … 64 61 65 62 #ifdef __32_BITS__ 66 /* 67 * XXX FIXME: 68 * 69 * Ignore zones which start above PHYSMEM_LIMIT32 70 * or clip zones which go beyond PHYSMEM_LIMIT32. 71 * 72 * The PHYSMEM_LIMIT32 (2 GB - 64 MB) is a rather 73 * arbitrary constant which allows to have at 74 * least 64 MB in the kernel address space to 75 * map hardware resources. 76 * 77 * The kernel uses fixed 1:1 identity mapping 78 * of the physical memory with 2:2 GB split. 79 * This is a severe limitation of the current 80 * kernel memory management. 81 * 82 */ 83 84 if (base > PHYSMEM_LIMIT32) 63 /* Ignore physical memory above 4 GB */ 64 if ((base >> 32) != 0) 85 65 continue; 86 66 87 if (base + size > PHYSMEM_LIMIT32) 88 size = PHYSMEM_LIMIT32 - base; 67 /* Clip regions above 4 GB */ 68 if (((base + size) >> 32) != 0) 69 size = 0xffffffff - base; 89 70 #endif 90 91 #ifdef __64_BITS__ 92 /* 93 * XXX FIXME: 94 * 95 * Ignore zones which start above PHYSMEM_LIMIT64 96 * or clip zones which go beyond PHYSMEM_LIMIT64. 97 * 98 * The PHYSMEM_LIMIT64 (8 GB) is the size of the 99 * fixed 1:1 identically mapped physical memory 100 * accessible during the bootstrap process. 101 * This is a severe limitation of the current 102 * kernel memory management. 103 * 104 */ 105 106 if (base > PHYSMEM_LIMIT64) 107 continue; 108 109 if (base + size > PHYSMEM_LIMIT64) 110 size = PHYSMEM_LIMIT64 - base; 111 #endif 71 72 pfn_t pfn; 73 size_t count; 112 74 113 75 if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) { 114 /* To be safe, make the available zone possibly smaller */ 115 uint64_t new_base = ALIGN_UP(base, FRAME_SIZE); 116 uint64_t new_size = ALIGN_DOWN(size - (new_base - base), 117 FRAME_SIZE); 118 119 pfn_t pfn = ADDR2PFN(new_base); 120 size_t count = SIZE2FRAMES(new_size); 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)); 121 79 122 80 pfn_t conf; … … 129 87 130 88 // XXX this has to be removed 131 if (last_frame < ALIGN_UP( new_base + new_size, FRAME_SIZE))132 last_frame = ALIGN_UP( new_base + new_size, FRAME_SIZE);89 if (last_frame < ALIGN_UP(base + size, FRAME_SIZE)) 90 last_frame = ALIGN_UP(base + size, FRAME_SIZE); 133 91 } 134 92 135 93 if (e820table[i].type == MEMMAP_MEMORY_RESERVED) { 136 /* To be safe, make the reserved zone possibly larger */ 137 uint64_t new_base = ALIGN_DOWN(base, FRAME_SIZE); 138 uint64_t new_size = ALIGN_UP(size + (base - new_base), 139 FRAME_SIZE); 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)); 140 97 141 zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0, 142 ZONE_RESERVED); 98 zone_create(pfn, count, 0, ZONE_RESERVED); 143 99 } 144 100 145 101 if (e820table[i].type == MEMMAP_MEMORY_ACPI) { 146 /* To be safe, make the firmware zone possibly larger */ 147 uint64_t new_base = ALIGN_DOWN(base, FRAME_SIZE); 148 uint64_t new_size = ALIGN_UP(size + (base - new_base), 149 FRAME_SIZE); 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)); 150 105 151 zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0, 152 ZONE_FIRMWARE); 106 zone_create(pfn, count, 0, ZONE_FIRMWARE); 153 107 } 154 108 } … … 167 121 { 168 122 unsigned int i; 169 printf("[base ] [size ] [name ]\n");123 const char *name; 170 124 125 printf("[base ] [size ] [name\n"); 126 171 127 for (i = 0; i < e820counter; i++) { 172 const char *name;173 174 128 if (e820table[i].type <= MEMMAP_MEMORY_UNUSABLE) 175 129 name = e820names[e820table[i].type]; … … 177 131 name = "invalid"; 178 132 179 printf("%# 018" PRIx64 " %#018" PRIx64"%s\n", e820table[i].base_address,133 printf("%#18llx %#18llx %s\n", e820table[i].base_address, 180 134 e820table[i].size, name); 181 135 } … … 195 149 hardcoded_unmapped_kdata_size)); 196 150 #endif 197 151 198 152 init_e820_memory(minconf); 199 153 -
kernel/arch/ia32/src/mm/tlb.c
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup ia32mm 29 /** @addtogroup ia32mm 30 30 * @{ 31 31 */ -
kernel/arch/ia32/src/smp/mps.c
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 52 52 */ 53 53 54 #define FS_SIGNATURE 0x5f504d5f 55 #define CT_SIGNATURE 0x504d4350 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); 56 70 57 71 static struct mps_fs *fs; 58 72 static struct mps_ct *ct; 59 73 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 get_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 is_cpu_enabled(size_t i) 82 { 83 ASSERT(i < processor_entry_cnt); 84 85 /* 86 * FIXME: The current local APIC driver limits usable 87 * APIC IDs to 8. 88 * 89 */ 90 if (get_cpu_apic_id(i) > 7) 91 return false; 92 93 return (bool) ((processor_entries[i].cpu_flags & 0x01) == 0x01); 94 } 95 96 static bool is_bsp(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 */ 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 119 95 struct smp_config_operations mps_config_operations = { 96 .cpu_count = get_cpu_count, 120 97 .cpu_enabled = is_cpu_enabled, 121 98 .cpu_bootstrap = is_bsp, … … 124 101 }; 125 102 126 /** Check the integrity of the MP Floating Structure. 127 * 128 */ 129 static bool mps_fs_check(uint8_t *base) 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) 130 131 { 131 132 unsigned int i; … … 135 136 sum = (uint8_t) (sum + base[i]); 136 137 137 return (sum == 0);138 } 139 140 /* * Check the integrity of the MP Configuration Table.141 * 142 */ 143 static boolmps_ct_check(void)138 return !sum; 139 } 140 141 /* 142 * Used to check the integrity of the MP Configuration Table. 143 */ 144 int mps_ct_check(void) 144 145 { 145 146 uint8_t *base = (uint8_t *) ct; 146 147 uint8_t *ext = base + ct->base_table_length; 147 148 uint8_t sum; 148 uint16_t i;149 150 /* Computethe checksum for the base table */151 for (i = 0, 149 int i; 150 151 /* count the checksum for the base table */ 152 for (i = 0,sum = 0; i < ct->base_table_length; i++) 152 153 sum = (uint8_t) (sum + base[i]); 153 154 154 155 if (sum) 155 return false;156 157 /* Computethe checksum for the extended table */156 return 0; 157 158 /* count the checksum for the extended table */ 158 159 for (i = 0, sum = 0; i < ct->ext_table_length; i++) 159 160 sum = (uint8_t) (sum + ext[i]); 160 161 return (sum == ct->ext_table_checksum); 162 } 163 164 static void ct_processor_entry(struct __processor_entry *pr) 165 { 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 166 171 /* 167 * Ignore processors which are not marked enabled. 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 168 176 */ 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; 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 } 186 } 187 } 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 { 328 211 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]); 336 } 337 } 338 } 339 340 static void configure_via_ct(void) 341 { 212 unsigned int i, cnt; 213 342 214 if (ct->signature != CT_SIGNATURE) { 343 printf("MPS: Wrong ct->signature\n"); 344 return; 345 } 346 215 printf("%s: bad ct->signature\n", __func__); 216 return 1; 217 } 347 218 if (!mps_ct_check()) { 348 printf("MPS: Wrong ct checksum\n"); 349 return; 350 } 351 219 printf("%s: bad ct checksum\n", __func__); 220 return 1; 221 } 352 222 if (ct->oem_table) { 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 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]; 362 231 for (i = 0; i < ct->entry_count; i++) { 363 232 switch (*cur) { 364 case 0: /* Processor entry */ 233 /* Processor entry */ 234 case 0: 365 235 processor_entries = processor_entries ? 366 236 processor_entries : 367 237 (struct __processor_entry *) cur; 368 238 processor_entry_cnt++; 369 ct_processor_entry((struct __processor_entry *) cur); 239 cnt += ct_processor_entry((struct __processor_entry *) 240 cur); 370 241 cur += 20; 371 242 break; 372 case 1: /* Bus entry */ 243 244 /* Bus entry */ 245 case 1: 373 246 bus_entries = bus_entries ? 374 247 bus_entries : (struct __bus_entry *) cur; … … 377 250 cur += 8; 378 251 break; 379 case 2: /* I/O APIC */ 252 253 /* I/O Apic */ 254 case 2: 380 255 io_apic_entries = io_apic_entries ? 381 256 io_apic_entries : (struct __io_apic_entry *) cur; 382 io_apic_entry_cnt++;257 io_apic_entry_cnt++; 383 258 ct_io_apic_entry((struct __io_apic_entry *) cur); 384 259 cur += 8; 385 260 break; 386 case 3: /* I/O Interrupt Assignment */ 261 262 /* I/O Interrupt Assignment */ 263 case 3: 387 264 io_intr_entries = io_intr_entries ? 388 265 io_intr_entries : (struct __io_intr_entry *) cur; … … 391 268 cur += 8; 392 269 break; 393 case 4: /* Local Interrupt Assignment */ 270 271 /* Local Interrupt Assignment */ 272 case 4: 394 273 l_intr_entries = l_intr_entries ? 395 274 l_intr_entries : (struct __l_intr_entry *) cur; … … 398 277 cur += 8; 399 278 break; 279 400 280 default: 401 281 /* 402 282 * Something is wrong. Fallback to UP mode. 403 283 */ 404 printf("MPS: ct badness %" PRIu8 "\n", *cur); 405 return; 284 285 printf("%s: ct badness\n", __func__); 286 return 1; 406 287 } 407 288 } … … 411 292 */ 412 293 ct_extended_entries(); 413 } 414 415 static void configure_via_default(uint8_t n __attribute__((unused))) 294 return cnt; 295 } 296 297 int configure_via_default(uint8_t n __attribute__((unused))) 416 298 { 417 299 /* 418 300 * Not yet implemented. 419 301 */ 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) }; 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 { 309 /* 310 * Ignore processors which are not marked enabled. 311 */ 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; 471 } 472 } 473 } 474 475 int mps_irq_to_pin(unsigned int irq) 476 { 426 477 unsigned int i; 427 unsigned int j; 428 unsigned int length[2] = { 1024, 64 * 1024 }; 429 430 /* 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 435 */ 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 } 445 } 446 } 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; 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; 466 486 } 467 487 -
kernel/arch/ia32/src/smp/smp.c
rf56e897f re4a4b44 62 62 void smp_init(void) 63 63 { 64 uintptr_t l_apic_address; 65 uintptr_t io_apic_address; 66 64 uintptr_t l_apic_address, io_apic_address; 65 67 66 if (acpi_madt) { 68 67 acpi_madt_parse(); 69 68 ops = &madt_config_operations; 70 69 } 71 72 70 if (config.cpu_count == 1) { 73 71 mps_init(); 74 72 ops = &mps_config_operations; 75 73 } 76 74 77 75 l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, 78 76 FRAME_ATOMIC | FRAME_KA); 79 77 if (!l_apic_address) 80 78 panic("Cannot allocate address for l_apic."); 81 79 82 80 io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, 83 81 FRAME_ATOMIC | FRAME_KA); 84 82 if (!io_apic_address) 85 83 panic("Cannot allocate address for io_apic."); 86 84 87 85 if (config.cpu_count > 1) { 88 86 page_table_lock(AS_KERNEL, true); … … 92 90 (uintptr_t) io_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE); 93 91 page_table_unlock(AS_KERNEL, true); 94 92 95 93 l_apic = (uint32_t *) l_apic_address; 96 94 io_apic = (uint32_t *) io_apic_address; … … 110 108 111 109 ASSERT(ops != NULL); 112 110 113 111 /* 114 112 * We need to access data in frame 0. 115 113 * We boldly make use of kernel address space mapping. 116 114 */ 117 115 118 116 /* 119 117 * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot() 120 118 */ 121 119 *((uint16_t *) (PA2KA(0x467 + 0))) = 122 (uint16_t) (((uintptr_t) ap_boot) >> 4); 123 *((uint16_t *) (PA2KA(0x467 + 2))) = 0; 120 (uint16_t) (((uintptr_t) ap_boot) >> 4); /* segment */ 121 *((uint16_t *) (PA2KA(0x467 + 2))) = 0; /* offset */ 124 122 125 123 /* … … 127 125 * BIOS will not do the POST after the INIT signal. 128 126 */ 129 pio_write_8((ioport8_t *) 130 pio_write_8((ioport8_t *) 131 127 pio_write_8((ioport8_t *)0x70, 0xf); 128 pio_write_8((ioport8_t *)0x71, 0xa); 129 132 130 pic_disable_irqs(0xffff); 133 131 apic_init(); 134 132 135 133 uint8_t apic = l_apic_id(); 136 137 for (i = 0; i < config.cpu_count; i++) { 134 135 for (i = 0; i < ops->cpu_count(); i++) { 136 descriptor_t *gdt_new; 137 138 138 /* 139 139 * Skip processors marked unusable. … … 141 141 if (!ops->cpu_enabled(i)) 142 142 continue; 143 143 144 144 /* 145 145 * The bootstrap processor is already up. … … 147 147 if (ops->cpu_bootstrap(i)) 148 148 continue; 149 149 150 150 if (ops->cpu_apic_id(i) == apic) { 151 151 printf("%s: bad processor entry #%u, will not send IPI " … … 162 162 * the memory subsystem 163 163 */ 164 descriptor_t *gdt_new = 165 (descriptor_t *) malloc(GDT_ITEMS * sizeof(descriptor_t), 166 FRAME_ATOMIC); 164 gdt_new = (descriptor_t *) malloc(GDT_ITEMS * 165 sizeof(descriptor_t), FRAME_ATOMIC); 167 166 if (!gdt_new) 168 167 panic("Cannot allocate memory for GDT."); 169 168 170 169 memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(descriptor_t)); 171 170 memsetb(&gdt_new[TSS_DES], sizeof(descriptor_t), 0); … … 173 172 protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new); 174 173 gdtr.base = (uintptr_t) gdt_new; 175 174 176 175 if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) { 177 176 /* … … 182 181 if (waitq_sleep_timeout(&ap_completion_wq, 1000000, 183 182 SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) { 183 unsigned int cpu = (config.cpu_active > i) ? 184 config.cpu_active : i; 184 185 printf("%s: waiting for cpu%u (APIC ID = %d) " 185 "timed out\n", __FUNCTION__, i,186 "timed out\n", __FUNCTION__, cpu, 186 187 ops->cpu_apic_id(i)); 187 188 } -
kernel/arch/ppc32/src/mm/frame.c
rf56e897f re4a4b44 60 60 61 61 for (i = 0; i < memmap.cnt; i++) { 62 /* To be safe, make the available zone possibly smaller */ 63 uintptr_t new_start = ALIGN_UP((uintptr_t) memmap.zones[i].start, 64 FRAME_SIZE); 65 size_t new_size = ALIGN_DOWN(memmap.zones[i].size - 66 (new_start - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE); 67 68 pfn_t pfn = ADDR2PFN(new_start); 69 size_t count = SIZE2FRAMES(new_size); 62 pfn_t start = ADDR2PFN(ALIGN_UP((uintptr_t) memmap.zones[i].start, 63 FRAME_SIZE)); 64 size_t size = SIZE2FRAMES(ALIGN_DOWN(memmap.zones[i].size, FRAME_SIZE)); 70 65 71 66 pfn_t conf; 72 if ((minconf < pfn) || (minconf >= pfn + count))73 conf = pfn;67 if ((minconf < start) || (minconf >= start + size)) 68 conf = start; 74 69 else 75 70 conf = minconf; 76 71 77 zone_create(pfn, count, conf, 0); 78 79 if (last_frame < ALIGN_UP(new_start + new_size, FRAME_SIZE)) 80 last_frame = ALIGN_UP(new_start + new_size, FRAME_SIZE); 72 zone_create(start, size, conf, 0); 73 if (last_frame < ALIGN_UP((uintptr_t) memmap.zones[i].start 74 + memmap.zones[i].size, FRAME_SIZE)) 75 last_frame = ALIGN_UP((uintptr_t) memmap.zones[i].start 76 + memmap.zones[i].size, FRAME_SIZE); 81 77 } 82 78 -
kernel/arch/sparc64/src/mm/sun4u/frame.c
rf56e897f re4a4b44 49 49 void frame_arch_init(void) 50 50 { 51 unsigned int i; 52 pfn_t confdata; 53 51 54 if (config.cpu_active == 1) { 52 unsigned int i;53 54 55 for (i = 0; i < memmap.cnt; i++) { 55 /* To be safe, make the available zone possibly smaller */ 56 uintptr_t new_start = ALIGN_UP((uintptr_t) memmap.zones[i].start, 57 FRAME_SIZE); 58 size_t new_size = ALIGN_DOWN(memmap.zones[i].size - 59 (new_start - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE); 60 56 uintptr_t start = (uintptr_t) memmap.zones[i].start; 57 size_t size = memmap.zones[i].size; 58 61 59 /* 62 60 * The memmap is created by HelenOS boot loader. 63 61 * It already contains no holes. 64 62 */ 65 66 pfn_t confdata = ADDR2PFN(new_start); 67 63 64 confdata = ADDR2PFN(start); 68 65 if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0)))) 69 66 confdata = ADDR2PFN(KA2PA(PFN2ADDR(2))); 70 71 zone_create(ADDR2PFN(new_start), SIZE2FRAMES(new_size),67 zone_create(ADDR2PFN(start), 68 SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)), 72 69 confdata, 0); 73 74 last_frame = max(last_frame, new_start + new_size);70 last_frame = max(last_frame, start + ALIGN_UP(size, 71 FRAME_SIZE)); 75 72 } 76 73 77 74 /* 78 75 * On sparc64, physical memory can start on a non-zero address. … … 83 80 frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1); 84 81 } 85 82 86 83 end_of_identity = PA2KA(last_frame); 87 84 } -
kernel/arch/sparc64/src/mm/sun4v/frame.c
rf56e897f re4a4b44 47 47 void frame_arch_init(void) 48 48 { 49 unsigned int i; 50 pfn_t confdata; 51 49 52 if (config.cpu_active == 1) { 50 unsigned int i;51 52 53 for (i = 0; i < memmap.cnt; i++) { 53 /* To be safe, make the available zone possibly smaller */ 54 uintptr_t new_start = ALIGN_UP((uintptr_t) memmap.zones[i].start, 55 FRAME_SIZE); 56 size_t new_size = ALIGN_DOWN(memmap.zones[i].size - 57 (new_start - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE); 58 54 uintptr_t start = (uintptr_t) memmap.zones[i].start; 55 size_t size = memmap.zones[i].size; 56 59 57 /* 60 58 * The memmap is created by HelenOS boot loader. 61 59 * It already contains no holes. 62 60 */ 63 64 pfn_t confdata = ADDR2PFN(new_start); 65 61 62 confdata = ADDR2PFN(start); 66 63 if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0)))) 67 64 confdata = ADDR2PFN(KA2PA(PFN2ADDR(2))); 68 69 zone_create(ADDR2PFN(new_start), SIZE2FRAMES(new_size),65 zone_create(ADDR2PFN(start), 66 SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)), 70 67 confdata, 0); 71 68 } 72 69 73 70 /* 74 71 * On sparc64, physical memory can start on a non-zero address. -
kernel/genarch/include/acpi/acpi.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup genarch 29 /** @addtogroup genarch 30 30 * @{ 31 31 */ … … 62 62 uint32_t creator_id; 63 63 uint32_t creator_revision; 64 } __attribute__ ((packed)); 64 } __attribute__ ((packed));; 65 65 66 66 struct acpi_signature_map { … … 74 74 struct acpi_sdt_header header; 75 75 uint32_t entry[]; 76 } __attribute__ ((packed)); 76 } __attribute__ ((packed));; 77 77 78 78 /* Extended System Description Table */ … … 80 80 struct acpi_sdt_header header; 81 81 uint64_t entry[]; 82 } __attribute__ ((packed)); 82 } __attribute__ ((packed));; 83 83 84 84 extern struct acpi_rsdp *acpi_rsdp; -
kernel/genarch/include/acpi/madt.h
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup genarch 29 /** @addtogroup genarch 30 30 * @{ 31 31 */ … … 40 40 #include <arch/smp/smp.h> 41 41 42 #define MADT_L_APIC043 #define MADT_IO_APIC 44 #define MADT_INTR_SRC_OVRD 45 #define MADT_NMI_SRC 46 #define MADT_L_APIC_NMI 47 #define MADT_L_APIC_ADDR_OVRD 48 #define MADT_IO_SAPIC 49 #define MADT_L_SAPIC 50 #define MADT_PLATFORM_INTR_SRC 51 #define MADT_RESERVED_SKIP_BEGIN 52 #define MADT_RESERVED_SKIP_END 53 #define MADT_RESERVED_OEM_BEGIN 42 #define MADT_L_APIC 0 43 #define MADT_IO_APIC 1 44 #define MADT_INTR_SRC_OVRD 2 45 #define MADT_NMI_SRC 3 46 #define MADT_L_APIC_NMI 4 47 #define MADT_L_APIC_ADDR_OVRD 5 48 #define MADT_IO_SAPIC 6 49 #define MADT_L_SAPIC 7 50 #define MADT_PLATFORM_INTR_SRC 8 51 #define MADT_RESERVED_SKIP_BEGIN 9 52 #define MADT_RESERVED_SKIP_END 127 53 #define MADT_RESERVED_OEM_BEGIN 128 54 54 55 55 struct madt_apic_header { … … 57 57 uint8_t length; 58 58 } __attribute__ ((packed)); 59 59 60 60 61 /* Multiple APIC Description Table */ … … 70 71 uint8_t acpi_id; 71 72 uint8_t apic_id; 72 uint32_t flags; 73 uint32_t flags; 73 74 } __attribute__ ((packed)); 74 75 … … 77 78 uint8_t io_apic_id; 78 79 uint8_t reserved; 79 uint32_t io_apic_address; 80 uint32_t io_apic_address; 80 81 uint32_t global_intr_base; 81 82 } __attribute__ ((packed)); … … 113 114 uint8_t reserved; 114 115 uint32_t global_intr_base; 115 uint64_t io_apic_address; 116 uint64_t io_apic_address; 116 117 } __attribute__ ((packed)); 117 118 -
kernel/genarch/src/acpi/acpi.c
rf56e897f re4a4b44 33 33 /** 34 34 * @file 35 * @brief 36 */ 37 35 * @brief Advanced Configuration and Power Interface (ACPI) initialization. 36 */ 37 38 38 #include <genarch/acpi/acpi.h> 39 39 #include <genarch/acpi/madt.h> … … 43 43 #include <print.h> 44 44 45 #define RSDP_SIGNATURE 46 #define RSDP_REVISION_OFFS 45 #define RSDP_SIGNATURE "RSD PTR " 46 #define RSDP_REVISION_OFFS 15 47 47 48 48 #define CMP_SIGNATURE(left, right) \ … … 64 64 }; 65 65 66 static int rsdp_check(uint8_t *_rsdp) { 67 struct acpi_rsdp *rsdp = (struct acpi_rsdp *) _rsdp; 68 uint8_t sum = 0; 69 uint32_t i; 70 71 for (i = 0; i < 20; i++) 72 sum = (uint8_t) (sum + _rsdp[i]); 73 74 if (sum) 75 return 0; /* bad checksum */ 76 77 if (rsdp->revision == 0) 78 return 1; /* ACPI 1.0 */ 79 80 for (; i < rsdp->length; i++) 81 sum = (uint8_t) (sum + _rsdp[i]); 82 83 return !sum; 84 } 85 86 int acpi_sdt_check(uint8_t *sdt) 87 { 88 struct acpi_sdt_header *hdr = (struct acpi_sdt_header *) sdt; 66 static int rsdp_check(uint8_t *rsdp) { 67 struct acpi_rsdp *r = (struct acpi_rsdp *) rsdp; 89 68 uint8_t sum = 0; 90 69 unsigned int i; 91 70 92 for (i = 0; i < hdr->length; i++) 71 for (i = 0; i < 20; i++) 72 sum = (uint8_t) (sum + rsdp[i]); 73 74 if (sum) 75 return 0; /* bad checksum */ 76 77 if (r->revision == 0) 78 return 1; /* ACPI 1.0 */ 79 80 for (; i < r->length; i++) 81 sum = (uint8_t) (sum + rsdp[i]); 82 83 return !sum; 84 85 } 86 87 int acpi_sdt_check(uint8_t *sdt) 88 { 89 struct acpi_sdt_header *h = (struct acpi_sdt_header *) sdt; 90 uint8_t sum = 0; 91 unsigned int i; 92 93 for (i = 0; i < h->length; i++) 93 94 sum = (uint8_t) (sum + sdt[i]); 94 95 95 96 return !sum; 96 97 } … … 99 100 { 100 101 page_table_lock(AS_KERNEL, true); 101 page_mapping_insert(AS_KERNEL, (uintptr_t) sdt, (uintptr_t) sdt, 102 PAGE_NOT_CACHEABLE | PAGE_WRITE); 102 page_mapping_insert(AS_KERNEL, (uintptr_t) sdt, (uintptr_t) sdt, PAGE_NOT_CACHEABLE | PAGE_WRITE); 103 103 map_structure((uintptr_t) sdt, sdt->length); 104 104 page_table_unlock(AS_KERNEL, true); … … 107 107 static void configure_via_rsdt(void) 108 108 { 109 size_t i; 110 size_t j; 111 size_t cnt = (acpi_rsdt->header.length - sizeof(struct acpi_sdt_header)) 112 / sizeof(uint32_t); 109 unsigned int i, j, cnt = (acpi_rsdt->header.length - sizeof(struct acpi_sdt_header)) / sizeof(uint32_t); 113 110 114 111 for (i = 0; i < cnt; i++) { 115 for (j = 0; j < sizeof(signature_map) 116 / sizeof(struct acpi_signature_map); j++) { 117 struct acpi_sdt_header *hdr = 118 (struct acpi_sdt_header *) (unative_t) acpi_rsdt->entry[i]; 119 120 map_sdt(hdr); 121 if (CMP_SIGNATURE(hdr->signature, signature_map[j].signature)) { 122 if (!acpi_sdt_check((uint8_t *) hdr)) 123 break; 124 125 *signature_map[j].sdt_ptr = hdr; 126 LOG("%p: ACPI %s", *signature_map[j].sdt_ptr, 127 signature_map[j].description); 112 for (j = 0; j < sizeof(signature_map) / sizeof(struct acpi_signature_map); j++) { 113 struct acpi_sdt_header *h = (struct acpi_sdt_header *) (unative_t) acpi_rsdt->entry[i]; 114 115 map_sdt(h); 116 if (CMP_SIGNATURE(h->signature, signature_map[j].signature)) { 117 if (!acpi_sdt_check((uint8_t *) h)) 118 goto next; 119 *signature_map[j].sdt_ptr = h; 120 LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description); 128 121 } 129 122 } 123 next: 124 ; 130 125 } 131 126 } … … 133 128 static void configure_via_xsdt(void) 134 129 { 135 size_t i; 136 size_t j; 137 size_t cnt = (acpi_xsdt->header.length - sizeof(struct acpi_sdt_header)) 138 / sizeof(uint64_t); 130 unsigned int i, j, cnt = (acpi_xsdt->header.length - sizeof(struct acpi_sdt_header)) / sizeof(uint64_t); 139 131 140 132 for (i = 0; i < cnt; i++) { 141 for (j = 0; j < sizeof(signature_map) 142 / sizeof(struct acpi_signature_map); j++) { 143 struct acpi_sdt_header *hdr = 144 (struct acpi_sdt_header *) ((uintptr_t) acpi_xsdt->entry[i]); 145 146 map_sdt(hdr); 147 if (CMP_SIGNATURE(hdr->signature, signature_map[j].signature)) { 148 if (!acpi_sdt_check((uint8_t *) hdr)) 149 break; 150 151 *signature_map[j].sdt_ptr = hdr; 152 LOG("%p: ACPI %s", *signature_map[j].sdt_ptr, 153 signature_map[j].description); 133 for (j = 0; j < sizeof(signature_map) / sizeof(struct acpi_signature_map); j++) { 134 struct acpi_sdt_header *h = (struct acpi_sdt_header *) ((uintptr_t) acpi_rsdt->entry[i]); 135 136 map_sdt(h); 137 if (CMP_SIGNATURE(h->signature, signature_map[j].signature)) { 138 if (!acpi_sdt_check((uint8_t *) h)) 139 goto next; 140 *signature_map[j].sdt_ptr = h; 141 LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description); 154 142 } 155 143 } 156 } 144 next: 145 ; 146 } 147 157 148 } 158 149 … … 160 151 { 161 152 uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xe0000) }; 162 unsigned int i; 163 unsigned int j; 164 unsigned int length[2] = { 1024, 128 * 1024 }; 153 int i, j, length[2] = { 1024, 128*1024 }; 165 154 uint64_t *sig = (uint64_t *) RSDP_SIGNATURE; 166 155 167 156 /* 168 157 * Find Root System Description Pointer … … 170 159 * 2. search 128K starting at 0xe0000 171 160 */ 172 161 173 162 addr[0] = (uint8_t *) PA2KA(ebda); 174 163 for (i = (ebda ? 0 : 1); i < 2; i++) { 175 164 for (j = 0; j < length[i]; j += 16) { 176 if ((*((uint64_t *) &addr[i][j]) == *sig) 177 && (rsdp_check(&addr[i][j]))) { 165 if (*((uint64_t *) &addr[i][j]) == *sig && rsdp_check(&addr[i][j])) { 178 166 acpi_rsdp = (struct acpi_rsdp *) &addr[i][j]; 179 167 goto rsdp_found; … … 181 169 } 182 170 } 183 171 184 172 return; 185 173 186 174 rsdp_found: 187 LOG("%p: ACPI Root System Description Pointer ", acpi_rsdp);188 189 acpi_rsdt = (struct acpi_rsdt *) ( (uintptr_t) acpi_rsdp->rsdt_address);175 LOG("%p: ACPI Root System Description Pointer\n", acpi_rsdp); 176 177 acpi_rsdt = (struct acpi_rsdt *) (unative_t) acpi_rsdp->rsdt_address; 190 178 if (acpi_rsdp->revision) 191 179 acpi_xsdt = (struct acpi_xsdt *) ((uintptr_t) acpi_rsdp->xsdt_address); 192 180 193 181 if (acpi_rsdt) 194 182 map_sdt((struct acpi_sdt_header *) acpi_rsdt); 195 196 183 if (acpi_xsdt) 197 184 map_sdt((struct acpi_sdt_header *) acpi_xsdt); 198 199 if ( (acpi_rsdt) && (!acpi_sdt_check((uint8_t *) acpi_rsdt))) {185 186 if (acpi_rsdt && !acpi_sdt_check((uint8_t *) acpi_rsdt)) { 200 187 printf("RSDT: bad checksum\n"); 201 188 return; 202 189 } 203 204 if ((acpi_xsdt) && (!acpi_sdt_check((uint8_t *) acpi_xsdt))) { 190 if (acpi_xsdt && !acpi_sdt_check((uint8_t *) acpi_xsdt)) { 205 191 printf("XSDT: bad checksum\n"); 206 192 return; 207 193 } 208 194 209 195 if (acpi_xsdt) 210 196 configure_via_xsdt(); 211 197 else if (acpi_rsdt) 212 198 configure_via_rsdt(); 199 213 200 } 214 201 -
kernel/genarch/src/acpi/madt.c
rf56e897f re4a4b44 27 27 */ 28 28 29 /** @addtogroup genarch 29 /** @addtogroup genarch 30 30 * @{ 31 31 */ 32 32 /** 33 33 * @file 34 * @brief 34 * @brief Multiple APIC Description Table (MADT) parsing. 35 35 */ 36 36 … … 52 52 #ifdef CONFIG_SMP 53 53 54 /** 55 * Standard ISA IRQ map; can be overriden by 56 * Interrupt Source Override entries of MADT. 57 */ 58 static int isa_irq_map[] = 59 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; 54 /** Standard ISA IRQ map; can be overriden by Interrupt Source Override entries of MADT. */ 55 int isa_irq_map[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; 56 57 static void madt_l_apic_entry(struct madt_l_apic *la, uint32_t index); 58 static void madt_io_apic_entry(struct madt_io_apic *ioa, uint32_t index); 59 static void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, uint32_t index); 60 static int madt_cmp(void * a, void * b); 60 61 61 62 struct madt_l_apic *madt_l_apic_entries = NULL; 62 63 struct madt_io_apic *madt_io_apic_entries = NULL; 63 64 64 static size_t madt_l_apic_entry_index = 0; 65 static size_t madt_io_apic_entry_index = 0; 66 static size_t madt_l_apic_entry_cnt = 0; 67 static size_t madt_io_apic_entry_cnt = 0; 68 69 static struct madt_apic_header **madt_entries_index = NULL; 65 size_t madt_l_apic_entry_index = 0; 66 size_t madt_io_apic_entry_index = 0; 67 size_t madt_l_apic_entry_cnt = 0; 68 size_t madt_io_apic_entry_cnt = 0; 69 size_t cpu_count = 0; 70 71 struct madt_apic_header * * madt_entries_index = NULL; 72 unsigned int madt_entries_index_cnt = 0; 70 73 71 74 const char *entry[] = { … … 81 84 }; 82 85 83 static uint8_t madt_cpu_apic_id(size_t i) 84 { 85 ASSERT(i < madt_l_apic_entry_cnt); 86 87 return ((struct madt_l_apic *) 88 madt_entries_index[madt_l_apic_entry_index + i])->apic_id; 89 } 90 91 static bool madt_cpu_enabled(size_t i) 92 { 93 ASSERT(i < madt_l_apic_entry_cnt); 94 95 /* 96 * FIXME: The current local APIC driver limits usable 97 * APIC IDs to 8. 98 * 99 */ 100 if (madt_cpu_apic_id(i) > 7) 101 return false; 102 103 return ((struct madt_l_apic *) 104 madt_entries_index[madt_l_apic_entry_index + i])->flags & 0x1; 105 } 106 107 static bool madt_cpu_bootstrap(size_t i) 108 { 109 ASSERT(i < madt_l_apic_entry_cnt); 110 111 return ((struct madt_l_apic *) 112 madt_entries_index[madt_l_apic_entry_index + i])->apic_id == 113 l_apic_id(); 114 } 115 116 static int madt_irq_to_pin(unsigned int irq) 117 { 118 ASSERT(irq < sizeof(isa_irq_map) / sizeof(int)); 119 120 return isa_irq_map[irq]; 121 } 122 123 /** ACPI MADT Implementation of SMP configuration interface. 124 * 125 */ 86 /* 87 * ACPI MADT Implementation of SMP configuration interface. 88 */ 89 static size_t madt_cpu_count(void); 90 static bool madt_cpu_enabled(size_t i); 91 static bool madt_cpu_bootstrap(size_t i); 92 static uint8_t madt_cpu_apic_id(size_t i); 93 static int madt_irq_to_pin(unsigned int irq); 94 126 95 struct smp_config_operations madt_config_operations = { 96 .cpu_count = madt_cpu_count, 127 97 .cpu_enabled = madt_cpu_enabled, 128 98 .cpu_bootstrap = madt_cpu_bootstrap, … … 131 101 }; 132 102 133 static int madt_cmp(void *a, void *b) 134 { 135 uint8_t typea = ((struct madt_apic_header *) a)->type; 136 uint8_t typeb = ((struct madt_apic_header *) b)->type; 137 138 if (typea > typeb) 139 return 1; 140 141 if (typea < typeb) 142 return -1; 143 144 return 0; 145 } 146 147 static void madt_l_apic_entry(struct madt_l_apic *la, size_t i) 148 { 149 if (!madt_l_apic_entry_cnt++) 150 madt_l_apic_entry_index = i; 151 103 size_t madt_cpu_count(void) 104 { 105 return madt_l_apic_entry_cnt; 106 } 107 108 bool madt_cpu_enabled(size_t i) 109 { 110 ASSERT(i < madt_l_apic_entry_cnt); 111 return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->flags & 0x1; 112 113 } 114 115 bool madt_cpu_bootstrap(size_t i) 116 { 117 ASSERT(i < madt_l_apic_entry_cnt); 118 return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id == l_apic_id(); 119 } 120 121 uint8_t madt_cpu_apic_id(size_t i) 122 { 123 ASSERT(i < madt_l_apic_entry_cnt); 124 return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id; 125 } 126 127 int madt_irq_to_pin(unsigned int irq) 128 { 129 ASSERT(irq < sizeof(isa_irq_map) / sizeof(int)); 130 return isa_irq_map[irq]; 131 } 132 133 int madt_cmp(void * a, void * b) 134 { 135 return 136 (((struct madt_apic_header *) a)->type > ((struct madt_apic_header *) b)->type) ? 137 1 : 138 ((((struct madt_apic_header *) a)->type < ((struct madt_apic_header *) b)->type) ? -1 : 0); 139 } 140 141 void acpi_madt_parse(void) 142 { 143 struct madt_apic_header *end = (struct madt_apic_header *) (((uint8_t *) acpi_madt) + acpi_madt->header.length); 144 struct madt_apic_header *h; 145 146 l_apic = (uint32_t *) (unative_t) acpi_madt->l_apic_address; 147 148 /* calculate madt entries */ 149 for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((uint8_t *) h) + h->length)) { 150 madt_entries_index_cnt++; 151 } 152 153 /* create madt apic entries index array */ 154 madt_entries_index = (struct madt_apic_header * *) malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header * *), FRAME_ATOMIC); 155 if (!madt_entries_index) 156 panic("Memory allocation error."); 157 158 uint32_t index = 0; 159 160 for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((uint8_t *) h) + h->length)) { 161 madt_entries_index[index++] = h; 162 } 163 164 /* Quicksort MADT index structure */ 165 qsort(madt_entries_index, madt_entries_index_cnt, sizeof(uintptr_t), &madt_cmp); 166 167 /* Parse MADT entries */ 168 if (madt_entries_index_cnt > 0) { 169 for (index = 0; index < madt_entries_index_cnt - 1; index++) { 170 h = madt_entries_index[index]; 171 switch (h->type) { 172 case MADT_L_APIC: 173 madt_l_apic_entry((struct madt_l_apic *) h, index); 174 break; 175 case MADT_IO_APIC: 176 madt_io_apic_entry((struct madt_io_apic *) h, index); 177 break; 178 case MADT_INTR_SRC_OVRD: 179 madt_intr_src_ovrd_entry((struct madt_intr_src_ovrd *) h, index); 180 break; 181 case MADT_NMI_SRC: 182 case MADT_L_APIC_NMI: 183 case MADT_L_APIC_ADDR_OVRD: 184 case MADT_IO_SAPIC: 185 case MADT_L_SAPIC: 186 case MADT_PLATFORM_INTR_SRC: 187 printf("MADT: skipping %s entry (type=%" PRIu8 ")\n", entry[h->type], h->type); 188 break; 189 190 default: 191 if (h->type >= MADT_RESERVED_SKIP_BEGIN && h->type <= MADT_RESERVED_SKIP_END) { 192 printf("MADT: skipping reserved entry (type=%" PRIu8 ")\n", h->type); 193 } 194 if (h->type >= MADT_RESERVED_OEM_BEGIN) { 195 printf("MADT: skipping OEM entry (type=%" PRIu8 ")\n", h->type); 196 } 197 break; 198 } 199 } 200 } 201 202 if (cpu_count) 203 config.cpu_count = cpu_count; 204 } 205 206 207 void madt_l_apic_entry(struct madt_l_apic *la, uint32_t index) 208 { 209 if (!madt_l_apic_entry_cnt++) { 210 madt_l_apic_entry_index = index; 211 } 212 152 213 if (!(la->flags & 0x1)) { 153 214 /* Processor is unusable, skip it. */ … … 155 216 } 156 217 157 apic_id_mask |= 1 << la->apic_id; 158 } 159 160 static void madt_io_apic_entry(struct madt_io_apic *ioa, size_t i) 218 cpu_count++; 219 apic_id_mask |= 1<<la->apic_id; 220 } 221 222 void madt_io_apic_entry(struct madt_io_apic *ioa, uint32_t index) 161 223 { 162 224 if (!madt_io_apic_entry_cnt++) { 163 /* Remember index of the first io apic entry */164 madt_io_apic_entry_index = i ;225 /* remember index of the first io apic entry */ 226 madt_io_apic_entry_index = index; 165 227 io_apic = (uint32_t *) (unative_t) ioa->io_apic_address; 166 228 } else { 167 /* Currently not supported */168 }169 }170 171 static void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, 172 size_t i)229 /* currently not supported */ 230 return; 231 } 232 } 233 234 void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, uint32_t index) 173 235 { 174 236 ASSERT(override->source < sizeof(isa_irq_map) / sizeof(int)); 175 176 printf("MADT: Ignoring %s entry: bus=%" PRIu8 ", source=%" PRIu8 177 ", global_int=%" PRIu32 ", flags=%#" PRIx16 "\n", 178 entry[override->header.type], override->bus, override->source, 179 override->global_int, override->flags); 180 } 181 182 void acpi_madt_parse(void) 183 { 184 struct madt_apic_header *end = (struct madt_apic_header *) 185 (((uint8_t *) acpi_madt) + acpi_madt->header.length); 186 struct madt_apic_header *hdr; 187 188 l_apic = (uint32_t *) (unative_t) acpi_madt->l_apic_address; 189 190 /* Count MADT entries */ 191 unsigned int madt_entries_index_cnt = 0; 192 for (hdr = &acpi_madt->apic_header[0]; hdr < end; 193 hdr = (struct madt_apic_header *) (((uint8_t *) hdr) + hdr->length)) 194 madt_entries_index_cnt++; 195 196 /* Create MADT APIC entries index array */ 197 madt_entries_index = (struct madt_apic_header **) 198 malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header **), 199 FRAME_ATOMIC); 200 if (!madt_entries_index) 201 panic("Memory allocation error."); 202 203 size_t i = 0; 204 205 for (hdr = &acpi_madt->apic_header[0]; hdr < end; 206 hdr = (struct madt_apic_header *) (((uint8_t *) hdr) + hdr->length)) 207 madt_entries_index[i++] = hdr; 208 209 /* Sort MADT index structure */ 210 qsort(madt_entries_index, madt_entries_index_cnt, sizeof(uintptr_t), 211 &madt_cmp); 212 213 /* Parse MADT entries */ 214 for (i = 0; i < madt_entries_index_cnt; i++) { 215 hdr = madt_entries_index[i]; 216 217 switch (hdr->type) { 218 case MADT_L_APIC: 219 madt_l_apic_entry((struct madt_l_apic *) hdr, i); 220 break; 221 case MADT_IO_APIC: 222 madt_io_apic_entry((struct madt_io_apic *) hdr, i); 223 break; 224 case MADT_INTR_SRC_OVRD: 225 madt_intr_src_ovrd_entry((struct madt_intr_src_ovrd *) hdr, i); 226 break; 227 case MADT_NMI_SRC: 228 case MADT_L_APIC_NMI: 229 case MADT_L_APIC_ADDR_OVRD: 230 case MADT_IO_SAPIC: 231 case MADT_L_SAPIC: 232 case MADT_PLATFORM_INTR_SRC: 233 printf("MADT: Skipping %s entry (type=%" PRIu8 ")\n", 234 entry[hdr->type], hdr->type); 235 break; 236 default: 237 if ((hdr->type >= MADT_RESERVED_SKIP_BEGIN) 238 && (hdr->type <= MADT_RESERVED_SKIP_END)) 239 printf("MADT: Skipping reserved entry (type=%" PRIu8 ")\n", 240 hdr->type); 241 242 if (hdr->type >= MADT_RESERVED_OEM_BEGIN) 243 printf("MADT: Skipping OEM entry (type=%" PRIu8 ")\n", 244 hdr->type); 245 246 break; 247 } 248 } 249 250 if (madt_l_apic_entry_cnt > 0) 251 config.cpu_count = madt_l_apic_entry_cnt; 237 printf("MADT: ignoring %s entry: bus=%" PRIu8 ", source=%" PRIu8 ", global_int=%" PRIu32 ", flags=%#" PRIx16 "\n", 238 entry[override->header.type], override->bus, override->source, 239 override->global_int, override->flags); 252 240 } 253 241 -
kernel/generic/include/atomic.h
rf56e897f re4a4b44 41 41 42 42 ATOMIC static inline void atomic_set(atomic_t *val, atomic_count_t i) 43 WRITES(&val->count)44 REQUIRES_EXTENT_MUTABLE(val)45 43 { 46 44 val->count = i; … … 48 46 49 47 ATOMIC static inline atomic_count_t atomic_get(atomic_t *val) 50 REQUIRES_EXTENT_MUTABLE(val)51 48 { 52 49 return val->count; -
kernel/generic/include/config.h
rf56e897f re4a4b44 70 70 71 71 uintptr_t base; 72 size_t kernel_size; /**< Size of memory in bytes taken by kernel and stack */72 size_t kernel_size; /**< Size of memory in bytes taken by kernel and stack */ 73 73 74 uintptr_t stack_base; /**< Base adddress of initial stack */75 size_t stack_size; /**< Size of initial stack */74 uintptr_t stack_base; /**< Base adddress of initial stack */ 75 size_t stack_size; /**< Size of initial stack */ 76 76 } config_t; 77 77 -
kernel/generic/include/smp/ipi.h
rf56e897f re4a4b44 43 43 #else 44 44 45 #define ipi_broadcast(ipi)45 #define ipi_broadcast(ipi) 46 46 47 47 #endif /* CONFIG_SMP */ -
kernel/generic/include/verify.h
rf56e897f re4a4b44 39 39 #ifdef CONFIG_VERIFY_VCC 40 40 41 #define ATOMIC __specification_attr("atomic_inline", "") 42 43 #define READS(ptr) __specification(reads(ptr)) 44 #define WRITES(ptr) __specification(writes(ptr)) 45 #define REQUIRES(...) __specification(requires __VA_ARGS__) 46 47 #define EXTENT(ptr) \extent(ptr) 48 #define ARRAY_RANGE(ptr, nmemb) \array_range(ptr, nmemb) 49 50 #define REQUIRES_EXTENT_MUTABLE(ptr) \ 51 REQUIRES(\extent_mutable(ptr)) 52 53 #define REQUIRES_ARRAY_MUTABLE(ptr, nmemb) \ 54 REQUIRES(\mutable_array(ptr, nmemb)) 41 #define ATOMIC __spec_attr("atomic_inline", "") 42 #define REQUIRES(...) __requires(__VA_ARGS__) 55 43 56 44 #else /* CONFIG_VERIFY_VCC */ 57 45 58 46 #define ATOMIC 59 60 #define READS(ptr)61 #define WRITES(ptr)62 47 #define REQUIRES(...) 63 64 #define EXTENT(ptr)65 #define ARRAY_RANGE(ptr, nmemb)66 67 #define REQUIRES_EXTENT_MUTABLE(ptr)68 #define REQUIRES_ARRAY_MUTABLE(ptr, nmemb)69 48 70 49 #endif /* CONFIG_VERIFY_VCC */ -
kernel/generic/src/debug/symtab.c
rf56e897f re4a4b44 46 46 /** Get name of a symbol that seems most likely to correspond to address. 47 47 * 48 * @param addr 49 * @param name 50 * @param offset 48 * @param addr Address. 49 * @param name Place to store pointer to the symbol name. 50 * @param offset Place to store offset from the symbol address. 51 51 * 52 52 * @return Zero on success or negative error code, ENOENT if not found, … … 83 83 /** Lookup symbol by address and format for display. 84 84 * 85 * Returns name of closest corresponding symbol, 86 * "unknown" if none exists and "N/A" if no symbol 87 * information is available. 85 * Returns name of closest corresponding symbol, "Not found" if none exists 86 * or "N/A" if no symbol information is available. 88 87 * 89 88 * @param addr Address. … … 102 101 return name; 103 102 case ENOENT: 104 return " unknown";103 return "Not found"; 105 104 default: 106 105 return "N/A"; -
kernel/generic/src/interrupt/interrupt.c
rf56e897f re4a4b44 143 143 uint64_t end_cycle = get_cycle(); 144 144 145 irq_spinlock_lock(&exctbl_lock, false);146 145 exc_table[n].cycles += end_cycle - begin_cycle; 147 146 exc_table[n].count++; 148 irq_spinlock_unlock(&exctbl_lock, false);149 147 150 148 /* Do not charge THREAD for exception cycles */ -
kernel/generic/src/ipc/sysipc.c
rf56e897f re4a4b44 1150 1150 return (unative_t) rc; 1151 1151 1152 LOG("sys_ipc_connect_kbox(%" PRIu64 ") ", taskid_arg.value);1152 LOG("sys_ipc_connect_kbox(%" PRIu64 ")\n", taskid_arg.value); 1153 1153 1154 1154 return ipc_connect_kbox(taskid_arg.value); -
kernel/generic/src/main/kinit.c
rf56e897f re4a4b44 107 107 if (config.cpu_count > 1) { 108 108 waitq_initialize(&ap_completion_wq); 109 110 109 /* 111 110 * Create the kmp thread and wait for its completion. … … 125 124 thread_join(thread); 126 125 thread_detach(thread); 126 } 127 128 if (config.cpu_count > 1) { 129 size_t i; 127 130 128 131 /* 129 132 * For each CPU, create its load balancing thread. 130 133 */ 131 size_t i;132 133 134 for (i = 0; i < config.cpu_count; i++) { 134 135 thread = thread_create(kcpulb, NULL, TASK, THREAD_FLAG_WIRED, "kcpulb", true); -
kernel/generic/src/mm/frame.c
rf56e897f re4a4b44 1234 1234 { 1235 1235 #ifdef __32_BITS__ 1236 printf("[nr] [base addr ] [frames ] [flags ] [free frames ] [busy frames ]\n");1236 printf("[nr] [base addr ] [frames ] [flags ] [free frames ] [busy frames ]\n"); 1237 1237 #endif 1238 1238 1239 1239 #ifdef __64_BITS__ 1240 printf("[nr] [base address ] [frames ] [flags ] [free frames ] [busy frames ]\n");1240 printf("[nr] [base address ] [frames ] [flags ] [free frames ] [busy frames ]\n"); 1241 1241 #endif 1242 1242 … … 1274 1274 1275 1275 #ifdef __32_BITS__ 1276 printf(" %10p", base);1276 printf(" %10p", base); 1277 1277 #endif 1278 1278 1279 1279 #ifdef __64_BITS__ 1280 printf(" %18p", base);1280 printf(" %18p", base); 1281 1281 #endif 1282 1282 -
kernel/generic/src/mm/tlb.c
rf56e897f re4a4b44 73 73 * to all other processors. 74 74 * 75 * @param type 76 * @param asid 77 * @param page 78 * @param count 75 * @param type Type describing scope of shootdown. 76 * @param asid Address space, if required by type. 77 * @param page Virtual page address, if required by type. 78 * @param count Number of pages, if required by type. 79 79 * 80 80 * @return The interrupt priority level as it existed prior to this call. 81 *82 81 */ 83 82 ipl_t tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, 84 83 uintptr_t page, size_t count) 85 84 { 86 ipl_t ipl = interrupts_disable(); 85 ipl_t ipl; 86 87 ipl = interrupts_disable(); 87 88 CPU->tlb_active = false; 88 89 irq_spinlock_lock(&tlblock, false); … … 90 91 size_t i; 91 92 for (i = 0; i < config.cpu_count; i++) { 93 cpu_t *cpu; 94 92 95 if (i == CPU->id) 93 96 continue; 94 97 95 cpu_t *cpu = &cpus[i]; 96 98 cpu = &cpus[i]; 97 99 irq_spinlock_lock(&cpu->lock, false); 98 100 if (cpu->tlb_messages_count == TLB_MESSAGE_QUEUE_LEN) { … … 122 124 123 125 busy_wait: 124 for (i = 0; i < config.cpu_count; i++) {126 for (i = 0; i < config.cpu_count; i++) 125 127 if (cpus[i].tlb_active) 126 128 goto busy_wait; 127 } 128 129 129 130 return ipl; 130 131 } … … 132 133 /** Finish TLB shootdown sequence. 133 134 * 134 * @param ipl Previous interrupt priority level. 135 * 135 * @param ipl Previous interrupt priority level. 136 136 */ 137 137 void tlb_shootdown_finalize(ipl_t ipl) -
kernel/generic/src/proc/program.c
rf56e897f re4a4b44 145 145 146 146 program_loader = image_addr; 147 LOG("Registered program loader at 0x%" PRIp ,147 LOG("Registered program loader at 0x%" PRIp "\n", 148 148 image_addr); 149 149 -
kernel/generic/src/smp/ipi.c
rf56e897f re4a4b44 47 47 * @param ipi Message to broadcast. 48 48 * 49 * @bug The decision whether to actually send the IPI must be based 50 * on a different criterion. The current version has 51 * problems when some of the detected CPUs are marked 52 * disabled in machine configuration. 49 53 */ 50 54 void ipi_broadcast(int ipi) … … 56 60 */ 57 61 58 if ( config.cpu_count > 1)62 if ((config.cpu_active > 1) && (config.cpu_active == config.cpu_count)) 59 63 ipi_broadcast_arch(ipi); 60 64 } -
tools/checkers/vcc.py
rf56e897f re4a4b44 45 45 re_va_list = re.compile("__builtin_va_list") 46 46 47 specification = ""48 49 47 def usage(prname): 50 48 "Print usage syntax" … … 59 57 "Preprocess source using GCC preprocessor and compatibility tweaks" 60 58 61 global specification62 63 59 args = ['gcc', '-E'] 64 60 args.extend(options.split()) … … 73 69 74 70 tmpf = file(tmpfname, "w") 75 tmpf.write(specification) 71 72 tmpf.write("__specification(const char * const \\declspec_atomic_inline;)\n\n"); 73 74 tmpf.write("#define __spec_attr(key, value) \\\n"); 75 tmpf.write(" __declspec(System.Diagnostics.Contracts.CodeContract.StringVccAttr, \\\n"); 76 tmpf.write(" key, value)\n\n"); 76 77 77 78 for line in preproc.splitlines(): … … 154 155 # Run Vcc 155 156 print " -- %s --" % srcfname 156 retval = subprocess.Popen([vcc_path, '/pointersize:32', '/newsyntax',cygpath(tmpfqname)]).wait()157 retval = subprocess.Popen([vcc_path, '/pointersize:32', cygpath(tmpfqname)]).wait() 157 158 158 159 if (retval != 0): … … 169 170 170 171 def main(): 171 global specification172 173 172 if (len(sys.argv) < 2): 174 173 usage(sys.argv[0]) … … 193 192 return 194 193 195 specpath = os.path.join(rootdir, "tools/checkers/vcc.h")196 if (not os.path.isfile(specpath)):197 print "%s not found." % config198 return199 200 specfile = file(specpath, "r")201 specification = specfile.read()202 specfile.close()203 204 194 for job in jobs: 205 195 if (not vcc(vcc_path, rootdir, job)):
Note:
See TracChangeset
for help on using the changeset viewer.