Changeset f56e897f in mainline
- Timestamp:
- 2010-06-29T17:43:38Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6473d41
- Parents:
- e4a4b44 (diff), 793cf029 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 1 added
- 64 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/abs32le/include/atomic.h
re4a4b44 rf56e897f 42 42 43 43 ATOMIC static inline void atomic_inc(atomic_t *val) 44 WRITES(&val->count) 45 REQUIRES_EXTENT_MUTABLE(val) 44 46 REQUIRES(val->count < ATOMIC_COUNT_MAX) 45 47 { … … 51 53 52 54 ATOMIC static inline void atomic_dec(atomic_t *val) 55 WRITES(&val->count) 56 REQUIRES_EXTENT_MUTABLE(val) 53 57 REQUIRES(val->count > ATOMIC_COUNT_MIN) 54 58 { … … 60 64 61 65 ATOMIC static inline atomic_count_t atomic_postinc(atomic_t *val) 66 WRITES(&val->count) 67 REQUIRES_EXTENT_MUTABLE(val) 62 68 REQUIRES(val->count < ATOMIC_COUNT_MAX) 63 69 { … … 73 79 74 80 ATOMIC static inline atomic_count_t atomic_postdec(atomic_t *val) 81 WRITES(&val->count) 82 REQUIRES_EXTENT_MUTABLE(val) 75 83 REQUIRES(val->count > ATOMIC_COUNT_MIN) 76 84 { … … 89 97 90 98 ATOMIC static inline atomic_count_t test_and_set(atomic_t *val) 99 WRITES(&val->count) 100 REQUIRES_EXTENT_MUTABLE(val) 91 101 { 92 102 /* On real hardware the retrieving of the original … … 99 109 } 100 110 101 ATOMIC static inline atomic_count_t arch_atomic_get(atomic_t *val)102 {103 /* This function is not needed on real hardware, it just104 duplicates the functionality of atomic_get(). It is105 defined here because atomic_get() is an inline function106 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) 112 114 { 113 115 do { 114 while ( arch_atomic_get(val));116 while (val->count); 115 117 } while (test_and_set(val)); 116 118 } -
kernel/arch/abs32le/include/interrupt.h
re4a4b44 rf56e897f 54 54 55 55 static inline int istate_from_uspace(istate_t *istate) 56 REQUIRES_EXTENT_MUTABLE(istate) 56 57 { 57 58 /* On real hardware this checks whether the interrupted … … 62 63 63 64 static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr) 65 WRITES(&istate->ip) 64 66 { 65 67 /* On real hardware this sets the instruction pointer. */ … … 69 71 70 72 static inline unative_t istate_get_pc(istate_t *istate) 73 REQUIRES_EXTENT_MUTABLE(istate) 71 74 { 72 75 /* On real hardware this returns the instruction pointer. */ … … 76 79 77 80 static inline unative_t istate_get_fp(istate_t *istate) 81 REQUIRES_EXTENT_MUTABLE(istate) 78 82 { 79 83 /* On real hardware this returns the frame pointer. */ -
kernel/arch/abs32le/include/mm/page.h
re4a4b44 rf56e897f 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) 142 143 { 143 144 pte_t *p = &pt[i]; … … 155 156 156 157 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) 157 160 { 158 161 pte_t *p = &pt[i]; -
kernel/arch/amd64/Makefile.inc
re4a4b44 rf56e897f 33 33 34 34 FPU_NO_CFLAGS = -mno-sse -mno-sse2 35 CMN1 = -m64 -mcmodel= kernel-mno-red-zone -fno-unwind-tables -fno-omit-frame-pointer35 CMN1 = -m64 -mcmodel=large -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
re4a4b44 rf56e897f 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.*); 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 65 64 #endif /* CONFIG_SMP */ 66 65 67 66 } -
kernel/arch/amd64/include/arch.h
re4a4b44 rf56e897f 27 27 */ 28 28 29 /** @addtogroup amd64 29 /** @addtogroup amd64 30 30 * @{ 31 31 */ -
kernel/arch/amd64/include/boot/boot.h
re4a4b44 rf56e897f 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 0x800040 #define BOOT_STACK_SIZE 0x40038 #define BOOT_OFFSET 0x108000 39 #define AP_BOOT_OFFSET 0x008000 40 #define BOOT_STACK_SIZE 0x000400 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
re4a4b44 rf56e897f 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
re4a4b44 rf56e897f 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
re4a4b44 rf56e897f 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
re4a4b44 rf56e897f 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 121 118 #endif 122 119 -
kernel/arch/amd64/include/mm/as.h
re4a4b44 rf56e897f 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) 0xffffffff80000000 42 #define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000 43 #define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0x00007fffffffffff 40 #define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0xffff800000000000 41 #define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffffffffffff 44 42 45 #define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1)) 43 #define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000 44 #define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0x00007fffffffffff 46 45 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) 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 50 52 #define as_install_arch(as) 51 53 #define as_deinstall_arch(as) -
kernel/arch/amd64/include/mm/page.h
re4a4b44 rf56e897f 35 35 /** Paging on AMD64 36 36 * 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 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 * 45 42 */ 46 43 … … 50 47 #include <arch/mm/frame.h> 51 48 52 #define PAGE_WIDTH 53 #define PAGE_SIZE 49 #define PAGE_WIDTH FRAME_WIDTH 50 #define PAGE_SIZE FRAME_SIZE 54 51 55 52 #ifdef KERNEL 56 53 57 54 #ifndef __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 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__ */ 77 65 78 66 /* Number of entries in each level. */ 79 #define PTL0_ENTRIES_ARCH 80 #define PTL1_ENTRIES_ARCH 81 #define PTL2_ENTRIES_ARCH 82 #define PTL3_ENTRIES_ARCH 67 #define PTL0_ENTRIES_ARCH 512 68 #define PTL1_ENTRIES_ARCH 512 69 #define PTL2_ENTRIES_ARCH 512 70 #define PTL3_ENTRIES_ARCH 512 83 71 84 72 /* Page table sizes for each level. */ 85 #define PTL0_SIZE_ARCH 86 #define PTL1_SIZE_ARCH 87 #define PTL2_SIZE_ARCH 88 #define PTL3_SIZE_ARCH 73 #define PTL0_SIZE_ARCH ONE_FRAME 74 #define PTL1_SIZE_ARCH ONE_FRAME 75 #define PTL2_SIZE_ARCH ONE_FRAME 76 #define PTL3_SIZE_ARCH ONE_FRAME 89 77 90 78 /* Macros calculating indices into page tables in each level. */ 91 #define PTL0_INDEX_ARCH(vaddr) 92 #define PTL1_INDEX_ARCH(vaddr) 93 #define PTL2_INDEX_ARCH(vaddr) 94 #define PTL3_INDEX_ARCH(vaddr) 79 #define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 39) & 0x1ff) 80 #define PTL1_INDEX_ARCH(vaddr) (((vaddr) >> 30) & 0x1ff) 81 #define PTL2_INDEX_ARCH(vaddr) (((vaddr) >> 21) & 0x1ff) 82 #define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x1ff) 95 83 96 84 /* Get PTE address accessors for each level. */ … … 156 144 #ifndef __ASM__ 157 145 146 #include <mm/mm.h> 147 #include <arch/interrupt.h> 148 #include <typedefs.h> 149 158 150 /* Page fault error codes. */ 159 151 … … 161 153 * page. 162 154 */ 163 #define PFERR_CODE_P (1 << 0)155 #define PFERR_CODE_P (1 << 0) 164 156 165 157 /** When bit on this position is 1, the page fault was caused by a write. */ 166 #define PFERR_CODE_RW 158 #define PFERR_CODE_RW (1 << 1) 167 159 168 160 /** When bit on this position is 1, the page fault was caused in user mode. */ 169 #define PFERR_CODE_US 161 #define PFERR_CODE_US (1 << 2) 170 162 171 163 /** When bit on this position is 1, a reserved bit was set in page directory. */ 172 #define PFERR_CODE_RSVD 164 #define PFERR_CODE_RSVD (1 << 3) 173 165 174 166 /** When bit on this position os 1, the page fault was caused during instruction 175 167 * fecth. 176 168 */ 177 #define PFERR_CODE_ID 169 #define PFERR_CODE_ID (1 << 4) 178 170 179 171 /** Page Table Entry. */ 180 172 typedef struct { 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;173 unsigned int present : 1; 174 unsigned int writeable : 1; 175 unsigned int uaccessible : 1; 176 unsigned int page_write_through : 1; 177 unsigned int page_cache_disable : 1; 178 unsigned int accessed : 1; 179 unsigned int dirty : 1; 180 unsigned int unused: 1; 181 unsigned int global : 1; 182 unsigned int soft_valid : 1; /**< Valid content even if present bit is cleared. */ 183 unsigned int avl : 2; 184 unsigned int addr_12_31 : 30; 185 unsigned int addr_32_51 : 21; 186 unsigned int no_execute : 1; 195 187 } __attribute__ ((packed)) pte_t; 196 188 … … 211 203 { 212 204 pte_t *p = &pt[i]; 213 205 214 206 p->addr_12_31 = (a >> 12) & 0xfffff; 215 207 p->addr_32_51 = a >> 32; -
kernel/arch/amd64/include/mm/ptl.h
re4a4b44 rf56e897f 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 145 #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
re4a4b44 rf56e897f 27 27 */ 28 28 29 /** @addtogroup amd64mm 29 /** @addtogroup amd64mm 30 30 * @{ 31 31 */ -
kernel/arch/amd64/include/pm.h
re4a4b44 rf56e897f 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
re4a4b44 rf56e897f 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
re4a4b44 rf56e897f 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 262 263 return 0; 263 264 } -
kernel/arch/amd64/src/asm_utils.S
re4a4b44 rf56e897f 27 27 # 28 28 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 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 45 46 46 47 #include <arch/pm.h> 47 48 #include <arch/mm/page.h> 48 49 49 50 .text 50 51 .global interrupt_handlers 51 52 .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 * 91 92 */ 92 93 memcpy: … … 94 95 memcpy_to_uspace: 95 96 movq MEMCPY_DST, %rax 96 97 97 98 movq MEMCPY_SIZE, %rcx 98 shrq $3, %rcx 99 100 rep movsq 101 99 shrq $3, %rcx /* size / 8 */ 100 101 rep movsq /* copy as much as possible word by word */ 102 102 103 movq MEMCPY_SIZE, %rcx 103 andq $7, %rcx 104 andq $7, %rcx /* size % 8 */ 104 105 jz 0f 105 106 106 rep movsb 107 108 0:109 ret/* return MEMCPY_SRC, success */107 rep movsb /* copy the rest byte by byte */ 108 109 0: 110 ret /* return MEMCPY_SRC, success */ 110 111 111 112 memcpy_from_uspace_failover_address: 112 113 memcpy_to_uspace_failover_address: 113 xorq %rax, %rax 114 xorq %rax, %rax /* return 0, failure */ 114 115 ret 115 116 … … 119 120 # 120 121 has_cpuid: 121 pushfq 122 popq %rax 123 movq %rax, %rdx# copy flags124 btcl $21, %edx# swap the ID bit122 pushfq # store flags 123 popq %rax # read flags 124 movq %rax, %rdx # copy flags 125 btcl $21, %edx # swap the ID bit 125 126 pushq %rdx 126 popfq 127 popfq # propagate the change into flags 127 128 pushfq 128 popq %rdx # read flags129 andl $(1 <<21),%eax# interested only in ID bit130 andl $(1 <<21),%edx131 xorl %edx, %eax# 0 if not supported, 1 if supported129 popq %rdx # read flags 130 andl $(1 << 21), %eax # interested only in ID bit 131 andl $(1 << 21), %edx 132 xorl %edx, %eax # 0 if not supported, 1 if supported 132 133 ret 133 134 134 135 cpuid: 135 movq %rbx, %r10 # we have to preserve rbx across function calls136 137 movl %edi,%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 136 movq %rbx, %r10 # we have to preserve rbx across function calls 137 138 movl %edi,%eax # load the command into %eax 139 140 cpuid 141 movl %eax, 0(%rsi) 142 movl %ebx, 4(%rsi) 143 movl %ecx, 8(%rsi) 144 movl %edx, 12(%rsi) 145 145 146 movq %r10, %rbx 146 147 ret … … 152 153 wrmsr 153 154 ret 154 155 155 156 read_efer_flag: 156 157 movq $0xc0000080, %rcx 157 158 rdmsr 158 ret 159 ret 159 160 160 161 # Push all volatile general purpose registers on stack … … 185 186 .endm 186 187 187 #define INTERRUPT_ALIGN 128188 188 #define INTERRUPT_ALIGN 128 189 189 190 ## Declare interrupt handlers 190 191 # … … 195 196 # 196 197 .macro handler i n 197 198 198 199 /* 199 200 * Choose between version with error code and version without error … … 204 205 * Therefore we align the interrupt handlers. 205 206 */ 206 207 207 208 .iflt \i-32 208 209 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST … … 215 216 * Version without error word, 216 217 */ 217 subq $(IREGISTER_SPACE +8), %rsp218 subq $(IREGISTER_SPACE + 8), %rsp 218 219 .endif 219 220 .else … … 221 222 * Version without error word, 222 223 */ 223 subq $(IREGISTER_SPACE +8), %rsp224 .endif 225 224 subq $(IREGISTER_SPACE + 8), %rsp 225 .endif 226 226 227 save_all_gpr 227 228 cld … … 241 242 restore_all_gpr 242 243 # $8 = Skip error word 243 addq $(IREGISTER_SPACE +8), %rsp244 addq $(IREGISTER_SPACE + 8), %rsp 244 245 iretq 245 246 246 247 .align INTERRUPT_ALIGN 247 .if (\n -\i)-1248 handler "(\i+1)",\n248 .if (\n - \i) - 1 249 handler "(\i + 1)", \n 249 250 .endif 250 251 .endm … … 252 253 .align INTERRUPT_ALIGN 253 254 interrupt_handlers: 254 h_start:255 handler 0 IDT_ITEMS256 h_end:255 h_start: 256 handler 0 IDT_ITEMS 257 h_end: 257 258 258 259 ## Low-level syscall handler 259 # 260 # 260 261 # Registers on entry: 261 262 # 262 # @param rcx 263 # @param r11 264 # 265 # @param rax 266 # @param rdi 267 # @param rsi 268 # @param rdx 269 # @param r10 4th syscall argument. Used instead of RCX because the270 # 271 # @param r8 272 # @param r9 273 # 274 # @return 263 # @param rcx Userspace return address. 264 # @param r11 Userspace RLFAGS. 265 # 266 # @param rax Syscall number. 267 # @param rdi 1st syscall argument. 268 # @param rsi 2nd syscall argument. 269 # @param rdx 3rd syscall argument. 270 # @param r10 4th syscall argument. Used instead of RCX because 271 # the SYSCALL instruction clobbers it. 272 # @param r8 5th syscall argument. 273 # @param r9 6th syscall argument. 274 # 275 # @return Return value is in rax. 275 276 # 276 277 syscall_entry: 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 278 swapgs # Switch to hidden gs 281 279 # 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 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 285 286 sti 286 287 … … 299 300 popq %r11 300 301 popq %rcx 301 302 302 303 cli 303 304 swapgs 304 movq %gs:0, %rsp 305 movq %gs:0, %rsp # Restore the user RSP 305 306 swapgs 306 307 307 308 sysretq 308 309 … … 310 311 .global interrupt_handler_size 311 312 312 interrupt_handler_size: .quad (h_end -h_start)/IDT_ITEMS313 interrupt_handler_size: .quad (h_end - h_start) / IDT_ITEMS -
kernel/arch/amd64/src/boot/boot.S
re4a4b44 rf56e897f 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 call arch_pre_main 174 175 movabsq $arch_pre_main, %rax 176 callq *%rax 175 177 176 178 # create the first stack frame 177 179 pushq $0 178 180 movq %rsp, %rbp 179 180 call main_bsp 181 182 movabsq $main_bsp, %rax 183 call *%rax 181 184 182 185 # not reached … … 256 259 # 257 260 # Macro for generating initial page table contents. 258 # @param cnt Number of entries to generat . Must be multiple of 8.261 # @param cnt Number of entries to generate. Must be multiple of 8. 259 262 # @param g Number of GB that will be added to the mapping. 260 263 # 261 .macro ptl2gen cnt g 262 .if \cnt263 ptl2gen "\cnt - 8" \g264 .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 .endif264 .macro ptl2gen cnt g 265 .if \cnt 266 ptl2gen "\cnt - 8" \g 267 .quad ((\cnt - 8) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 268 .quad ((\cnt - 7) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 269 .quad ((\cnt - 6) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 270 .quad ((\cnt - 5) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 271 .quad ((\cnt - 4) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 272 .quad ((\cnt - 3) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 273 .quad ((\cnt - 2) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 274 .quad ((\cnt - 1) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE) 275 .endif 273 276 .endm 274 277 275 # Page table for pages in the first gigabyte. 276 .align 4096 277 .global ptl_2_0g 278 ptl_2_0g: 278 # Page table for pages in the 1st gigabyte. 279 .align 4096 280 ptl_2_0g: 279 281 ptl2gen 512 0 280 282 281 # Page table for pages in the second gigabyte. 282 .align 4096 283 .global ptl_2_1g 283 # Page table for pages in the 2nd gigabyte. 284 .align 4096 284 285 ptl_2_1g: 285 286 ptl2gen 512 1 286 287 287 # Page table for pages in the third gigabyte. 288 .align 4096 289 .global ptl_2_2g 288 # Page table for pages in the 3rd gigabyte. 289 .align 4096 290 290 ptl_2_2g: 291 291 ptl2gen 512 2 292 292 293 # Page table for pages in the fourth gigabyte. 294 .align 4096 295 .global ptl_2_3g 293 # Page table for pages in the 4th gigabyte. 294 .align 4096 296 295 ptl_2_3g: 297 296 ptl2gen 512 3 298 297 299 .align 4096 300 .global ptl_1 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 301 319 ptl_1: 302 # Identity mapping for [0; 4G)320 # Identity mapping for [0; 8G) 303 321 .quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT) 304 .quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT) 322 .quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT) 305 323 .quad ptl_2_2g + (PTL_WRITABLE | PTL_PRESENT) 306 324 .quad ptl_2_3g + (PTL_WRITABLE | PTL_PRESENT) 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 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 311 330 312 331 .align 4096 … … 314 333 ptl_0: 315 334 .quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT) 316 .fill 255, 8,0335 .fill 255, 8, 0 317 336 .quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT) 318 .fill 254,8,0 319 .quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT) 337 .fill 255, 8, 0 320 338 321 339 .section K_DATA_START, "aw", @progbits -
kernel/arch/amd64/src/context.S
re4a4b44 rf56e897f 41 41 context_save_arch: 42 42 movq (%rsp), %rdx # the caller's return %eip 43 44 # In %edi is passed 1st argument45 CONTEXT_SAVE_ARCH_CORE %rdi %rdx46 43 47 xorq %rax,%rax # context_save returns 1 44 # 1st argument passed in %edi 45 CONTEXT_SAVE_ARCH_CORE %rdi %rdx 46 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: 58 57 context_restore_arch: 59 58 CONTEXT_RESTORE_ARCH_CORE %rdi %rdx 60 61 movq %rdx, (%rsp)62 63 xorq %rax, %rax# context_restore returns 059 60 movq %rdx, (%rsp) 61 62 xorq %rax, %rax # context_restore returns 0 64 63 ret -
kernel/arch/amd64/src/cpu/cpu.c
re4a4b44 rf56e897f 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 0x6c65746e55 #define INTEL_CPUID_EDX 0x49656e6953 #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
re4a4b44 rf56e897f 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 51 52 return true; 52 53 } … … 56 57 uint64_t *stack = (void *) fp; 57 58 *ra = stack[FRAME_OFFSET_RA]; 59 58 60 return true; 59 61 } -
kernel/arch/amd64/src/delay.S
re4a4b44 rf56e897f 37 37 38 38 asm_delay_loop: 39 0: dec %rdi 40 jnz 0b 39 0: 40 dec %rdi 41 jnz 0b 42 41 43 ret 42 44 43 45 asm_fake_loop: 44 0: dec %rdi 45 jz 0b 46 0: 47 dec %rdi 48 jz 0b 49 46 50 ret -
kernel/arch/amd64/src/fpu_context.c
re4a4b44 rf56e897f 27 27 */ 28 28 29 /** @addtogroup amd64 29 /** @addtogroup amd64 30 30 * @{ 31 31 */ -
kernel/arch/amd64/src/interrupt.c
re4a4b44 rf56e897f 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);205 204 206 205 #ifdef CONFIG_SMP -
kernel/arch/amd64/src/mm/page.c
re4a4b44 rf56e897f 39 39 #include <mm/frame.h> 40 40 #include <mm/as.h> 41 #include <arch/interrupt.h>42 41 #include <arch/asm.h> 43 42 #include <config.h> … … 48 47 #include <align.h> 49 48 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 82 49 void page_arch_init(void) 83 50 { 84 uintptr_t cur;85 unsigned int i;86 int identity_flags = PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;87 88 51 if (config.cpu_active == 1) { 52 uintptr_t cur; 53 unsigned int identity_flags = 54 PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE; 55 89 56 page_mapping_operations = &pt_mapping_operations; 90 57 91 58 page_table_lock(AS_KERNEL, true); 92 59 93 60 /* 94 61 * PA2KA(identity) mapping for all frames. 95 62 */ 96 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) { 97 /* Standard identity mapping */ 63 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) 98 64 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags); 99 }100 65 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); 66 page_table_unlock(AS_KERNEL, true); 107 67 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 116 page_table_unlock(AS_KERNEL, true);117 118 68 exc_register(14, "page_fault", true, (iroutine_t) page_fault); 119 69 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); … … 122 72 } 123 73 124 125 /** Identity page mapper126 *127 * We need to map whole physical memory identically before the page subsystem128 * is initializaed. This thing clears page table and fills in the specific129 * 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 179 74 void page_fault(unsigned int n, istate_t *istate) 180 75 { 181 uintptr_t page; 182 pf_access_t access; 183 184 page = read_cr2(); 76 uintptr_t page = read_cr2(); 185 77 186 78 if (istate->error_word & PFERR_CODE_RSVD) 187 79 panic("Reserved bit set in page table entry."); 80 81 pf_access_t access; 188 82 189 83 if (istate->error_word & PFERR_CODE_RW) … … 200 94 } 201 95 202 203 96 uintptr_t hw_map(uintptr_t physaddr, size_t size) 204 97 { 205 98 if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) 206 panic("Unable to map physical memory %p (% dbytes).", physaddr,99 panic("Unable to map physical memory %p (%" PRIs " bytes).", physaddr, 207 100 size); 208 101 209 102 uintptr_t virtaddr = PA2KA(last_frame); 210 103 pfn_t i; 211 104 212 105 page_table_lock(AS_KERNEL, true); 106 213 107 for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) 214 108 page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE); 109 215 110 page_table_unlock(AS_KERNEL, true); 216 111 -
kernel/arch/amd64/src/proc/scheduler.c
re4a4b44 rf56e897f 38 38 #include <proc/thread.h> 39 39 #include <arch.h> 40 #include <arch/context.h> /* SP_DELTA */40 #include <arch/context.h> 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) THREAD->arch.syscall_rsp);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
re4a4b44 rf56e897f 39 39 /** Perform amd64 specific task initialization. 40 40 * 41 * @param t Task to be initialized. 41 * @param task Task to be initialized. 42 * 42 43 */ 43 void task_create_arch(task_t *t )44 void task_create_arch(task_t *task) 44 45 { 45 t ->arch.iomapver = 0;46 bitmap_initialize(&t ->arch.iomap, NULL, 0);46 task->arch.iomapver = 0; 47 bitmap_initialize(&task->arch.iomap, NULL, 0); 47 48 } 48 49 49 50 /** Perform amd64 specific task destruction. 50 51 * 51 * @param t Task to be initialized. 52 * @param task Task to be initialized. 53 * 52 54 */ 53 void task_destroy_arch(task_t *t )55 void task_destroy_arch(task_t *task) 54 56 { 55 if (t ->arch.iomap.map)56 free(t ->arch.iomap.map);57 if (task->arch.iomap.map) 58 free(task->arch.iomap.map); 57 59 } 58 60 -
kernel/arch/amd64/src/proc/thread.c
re4a4b44 rf56e897f 37 37 /** Perform amd64 specific thread initialization. 38 38 * 39 * @param t Thread to be initialized. 39 * @param thread Thread to be initialized. 40 * 40 41 */ 41 void thread_create_arch(thread_t *t )42 void thread_create_arch(thread_t *thread) 42 43 { 43 t->arch.tls = 0; 44 t->arch.syscall_rsp[SYSCALL_USTACK_RSP] = 0; 44 thread->arch.tls = 0; 45 thread->arch.syscall_rsp[SYSCALL_USTACK_RSP] = 0; 46 45 47 /* 46 48 * Kernel RSP can be precalculated at thread creation time. 47 49 */ 48 t ->arch.syscall_rsp[SYSCALL_KSTACK_RSP] =49 (uintptr_t) &t ->kstack[PAGE_SIZE - sizeof(uint64_t)];50 thread->arch.syscall_rsp[SYSCALL_KSTACK_RSP] = 51 (uintptr_t) &thread->kstack[PAGE_SIZE - sizeof(uint64_t)]; 50 52 } 51 53 -
kernel/arch/amd64/src/smp/ap.S
re4a4b44 rf56e897f 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 movq (ctx), %rsp 100 movabsq $ctx, %rsp 101 movq (%rsp), %rsp 102 101 103 pushq $0 102 104 movq %rsp, %rbp 103 call main_ap - AP_BOOT_OFFSET + BOOT_OFFSET # never returns 105 106 movabsq $main_ap, %rax 107 callq *%rax # never returns 104 108 105 109 #endif /* CONFIG_SMP */ -
kernel/arch/ia32/include/bios/bios.h
re4a4b44 rf56e897f 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
re4a4b44 rf56e897f 48 48 49 49 extern void i8259_init(void); 50 extern void pic_enable_irqs(uint16_t irqmask);51 extern void pic_disable_irqs(uint16_t irqmask);50 extern void pic_enable_irqs(uint16_t); 51 extern void pic_disable_irqs(uint16_t); 52 52 extern void pic_eoi(void); 53 53 -
kernel/arch/ia32/include/fpu_context.h
re4a4b44 rf56e897f 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 41 42 void fpu_fxsr(void); 43 void fpu_fsr(void); 44 40 #define FPU_CONTEXT_ALIGN 16 45 41 46 42 typedef struct { 47 uint8_t fpu[512]; 43 uint8_t fpu[512]; /* FXSAVE & FXRSTOR storage area */ 48 44 } fpu_context_t; 45 46 extern void fpu_fxsr(void); 47 extern void fpu_fsr(void); 49 48 50 49 #endif -
kernel/arch/ia32/include/mm/asid.h
re4a4b44 rf56e897f 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
re4a4b44 rf56e897f 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 xxx;72 uint8_t reserved; 73 73 uint8_t base_table[0]; 74 74 } __attribute__ ((packed)); … … 81 81 uint8_t cpu_signature[4]; 82 82 uint32_t feature_flags; 83 uint32_t xxx[2];83 uint32_t reserved[2]; 84 84 } __attribute__ ((packed)); 85 85 … … 102 102 uint8_t intr_type; 103 103 uint8_t poel; 104 uint8_t xxx;104 uint8_t reserved; 105 105 uint8_t src_bus_id; 106 106 uint8_t src_bus_irq; … … 113 113 uint8_t intr_type; 114 114 uint8_t poel; 115 uint8_t xxx;115 uint8_t reserved; 116 116 uint8_t src_bus_id; 117 117 uint8_t src_bus_irq; -
kernel/arch/ia32/include/smp/smp.h
re4a4b44 rf56e897f 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 size_t (* cpu_count)(void); /**< Return number of detected processors. */ 43 bool (* cpu_enabled)(size_t i); /**< Check whether the processor of index i is enabled. */ 44 bool (*cpu_bootstrap)(size_t i); /**< Check whether the processor of index i is BSP. */ 45 uint8_t (*cpu_apic_id)(size_t i); /**< Return APIC ID of the processor of index i. */ 46 int (*irq_to_pin)(unsigned int irq); /**< Return mapping between irq and APIC pin. */ 42 /** Check whether a processor is enabled. */ 43 bool (* cpu_enabled)(size_t); 44 45 /** Check whether a processor is BSP. */ 46 bool (*cpu_bootstrap)(size_t); 47 48 /** Return APIC ID of a processor. */ 49 uint8_t (*cpu_apic_id)(size_t); 50 51 /** Return mapping between IRQ and APIC pin. */ 52 int (*irq_to_pin)(unsigned int); 47 53 }; 48 54 49 extern int smp_irq_to_pin(unsigned int irq);55 extern int smp_irq_to_pin(unsigned int); 50 56 51 57 #endif -
kernel/arch/ia32/src/bios/bios.c
re4a4b44 rf56e897f 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ -
kernel/arch/ia32/src/ia32.c
re4a4b44 rf56e897f 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
re4a4b44 rf56e897f 27 27 */ 28 28 29 /** @addtogroup ia32mm 29 /** @addtogroup ia32mm 30 30 * @{ 31 31 */ -
kernel/arch/ia32/src/mm/frame.c
re4a4b44 rf56e897f 47 47 #include <print.h> 48 48 49 #define PHYSMEM_LIMIT32 0x07c000000ull 50 #define PHYSMEM_LIMIT64 0x200000000ull 51 49 52 size_t hardcoded_unmapped_ktext_size = 0; 50 53 size_t hardcoded_unmapped_kdata_size = 0; … … 55 58 { 56 59 unsigned int i; 57 60 58 61 for (i = 0; i < e820counter; i++) { 59 62 uint64_t base = e820table[i].base_address; … … 61 64 62 65 #ifdef __32_BITS__ 63 /* Ignore physical memory above 4 GB */ 64 if ((base >> 32) != 0) 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) 65 85 continue; 66 86 67 /* Clip regions above 4 GB */ 68 if (((base + size) >> 32) != 0) 69 size = 0xffffffff - base; 70 #endif 71 72 pfn_t pfn; 73 size_t count; 87 if (base + size > PHYSMEM_LIMIT32) 88 size = PHYSMEM_LIMIT32 - base; 89 #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 74 112 75 113 if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) { 76 /* To be safe, make available zone possibly smaller */ 77 pfn = ADDR2PFN(ALIGN_UP(base, FRAME_SIZE)); 78 count = SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)); 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); 79 121 80 122 pfn_t conf; … … 87 129 88 130 // XXX this has to be removed 89 if (last_frame < ALIGN_UP( base +size, FRAME_SIZE))90 last_frame = ALIGN_UP( base +size, FRAME_SIZE);131 if (last_frame < ALIGN_UP(new_base + new_size, FRAME_SIZE)) 132 last_frame = ALIGN_UP(new_base + new_size, FRAME_SIZE); 91 133 } 92 134 93 135 if (e820table[i].type == MEMMAP_MEMORY_RESERVED) { 94 /* To be safe, make reserved zone possibly larger */ 95 pfn = ADDR2PFN(ALIGN_DOWN(base, FRAME_SIZE)); 96 count = SIZE2FRAMES(ALIGN_UP(size, FRAME_SIZE)); 97 98 zone_create(pfn, count, 0, ZONE_RESERVED); 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); 140 141 zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0, 142 ZONE_RESERVED); 99 143 } 100 144 101 145 if (e820table[i].type == MEMMAP_MEMORY_ACPI) { 102 /* To be safe, make firmware zone possibly larger */ 103 pfn = ADDR2PFN(ALIGN_DOWN(base, (uintptr_t) FRAME_SIZE)); 104 count = SIZE2FRAMES(ALIGN_UP(size, (uintptr_t) FRAME_SIZE)); 105 106 zone_create(pfn, count, 0, ZONE_FIRMWARE); 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); 150 151 zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0, 152 ZONE_FIRMWARE); 107 153 } 108 154 } … … 121 167 { 122 168 unsigned int i; 123 const char *name;169 printf("[base ] [size ] [name ]\n"); 124 170 125 printf("[base ] [size ] [name\n");126 127 171 for (i = 0; i < e820counter; i++) { 172 const char *name; 173 128 174 if (e820table[i].type <= MEMMAP_MEMORY_UNUSABLE) 129 175 name = e820names[e820table[i].type]; … … 131 177 name = "invalid"; 132 178 133 printf("%# 18llx %#18llx%s\n", e820table[i].base_address,179 printf("%#018" PRIx64 " %#018" PRIx64" %s\n", e820table[i].base_address, 134 180 e820table[i].size, name); 135 181 } … … 149 195 hardcoded_unmapped_kdata_size)); 150 196 #endif 151 197 152 198 init_e820_memory(minconf); 153 199 -
kernel/arch/ia32/src/mm/tlb.c
re4a4b44 rf56e897f 27 27 */ 28 28 29 /** @addtogroup ia32mm 29 /** @addtogroup ia32mm 30 30 * @{ 31 31 */ -
kernel/arch/ia32/src/smp/mps.c
re4a4b44 rf56e897f 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 56 57 static int mps_fs_check(uint8_t *base); 58 static int mps_ct_check(void); 59 60 static int configure_via_ct(void); 61 static int configure_via_default(uint8_t n); 62 63 static int ct_processor_entry(struct __processor_entry *pr); 64 static void ct_bus_entry(struct __bus_entry *bus); 65 static void ct_io_apic_entry(struct __io_apic_entry *ioa); 66 static void ct_io_intr_entry(struct __io_intr_entry *iointr); 67 static void ct_l_intr_entry(struct __l_intr_entry *lintr); 68 69 static void ct_extended_entries(void); 54 #define FS_SIGNATURE 0x5f504d5f 55 #define CT_SIGNATURE 0x504d4350 70 56 71 57 static struct mps_fs *fs; 72 58 static struct mps_ct *ct; 73 59 74 struct __processor_entry *processor_entries = NULL; 75 struct __bus_entry *bus_entries = NULL; 76 struct __io_apic_entry *io_apic_entries = NULL; 77 struct __io_intr_entry *io_intr_entries = NULL; 78 struct __l_intr_entry *l_intr_entries = NULL; 79 80 unsigned int processor_entry_cnt = 0; 81 unsigned int bus_entry_cnt = 0; 82 unsigned int io_apic_entry_cnt = 0; 83 unsigned int io_intr_entry_cnt = 0; 84 unsigned int l_intr_entry_cnt = 0; 85 86 /* 87 * Implementation of IA-32 SMP configuration interface. 88 */ 89 static size_t get_cpu_count(void); 90 static bool is_cpu_enabled(size_t i); 91 static bool is_bsp(size_t i); 92 static uint8_t get_cpu_apic_id(size_t i); 93 static int mps_irq_to_pin(unsigned int irq); 94 60 static struct __processor_entry *processor_entries = NULL; 61 static struct __bus_entry *bus_entries = NULL; 62 static struct __io_apic_entry *io_apic_entries = NULL; 63 static struct __io_intr_entry *io_intr_entries = NULL; 64 static struct __l_intr_entry *l_intr_entries = NULL; 65 66 static size_t io_apic_cnt = 0; 67 68 static size_t processor_entry_cnt = 0; 69 static size_t bus_entry_cnt = 0; 70 static size_t io_apic_entry_cnt = 0; 71 static size_t io_intr_entry_cnt = 0; 72 static size_t l_intr_entry_cnt = 0; 73 74 static uint8_t 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 */ 95 119 struct smp_config_operations mps_config_operations = { 96 .cpu_count = get_cpu_count,97 120 .cpu_enabled = is_cpu_enabled, 98 121 .cpu_bootstrap = is_bsp, … … 101 124 }; 102 125 103 size_t get_cpu_count(void) 104 { 105 return processor_entry_cnt; 106 } 107 108 bool is_cpu_enabled(size_t i) 109 { 110 ASSERT(i < processor_entry_cnt); 111 return (bool) ((processor_entries[i].cpu_flags & 0x01) == 0x01); 112 } 113 114 bool is_bsp(size_t i) 115 { 116 ASSERT(i < processor_entry_cnt); 117 return (bool) ((processor_entries[i].cpu_flags & 0x02) == 0x02); 118 } 119 120 uint8_t get_cpu_apic_id(size_t i) 121 { 122 ASSERT(i < processor_entry_cnt); 123 return processor_entries[i].l_apic_id; 124 } 125 126 127 /* 128 * Used to check the integrity of the MP Floating Structure. 129 */ 130 int mps_fs_check(uint8_t *base) 126 /** Check the integrity of the MP Floating Structure. 127 * 128 */ 129 static bool mps_fs_check(uint8_t *base) 131 130 { 132 131 unsigned int i; … … 136 135 sum = (uint8_t) (sum + base[i]); 137 136 138 return !sum;139 } 140 141 /* 142 * Used to check the integrity of the MP Configuration Table.143 */ 144 intmps_ct_check(void)137 return (sum == 0); 138 } 139 140 /** Check the integrity of the MP Configuration Table. 141 * 142 */ 143 static bool mps_ct_check(void) 145 144 { 146 145 uint8_t *base = (uint8_t *) ct; 147 146 uint8_t *ext = base + ct->base_table_length; 148 147 uint8_t sum; 149 int i;150 151 /* countthe checksum for the base table */152 for (i = 0, sum = 0; i < ct->base_table_length; i++)148 uint16_t i; 149 150 /* Compute the checksum for the base table */ 151 for (i = 0, sum = 0; i < ct->base_table_length; i++) 153 152 sum = (uint8_t) (sum + base[i]); 154 153 155 154 if (sum) 156 return 0;157 158 /* countthe checksum for the extended table */155 return false; 156 157 /* Compute the checksum for the extended table */ 159 158 for (i = 0, sum = 0; i < ct->ext_table_length; i++) 160 159 sum = (uint8_t) (sum + ext[i]); 161 162 return sum == ct->ext_table_checksum; 163 } 164 165 void mps_init(void) 166 { 167 uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xf0000) }; 168 unsigned int i, j, length[2] = { 1024, 64 * 1024 }; 169 170 160 161 return (sum == ct->ext_table_checksum); 162 } 163 164 static void ct_processor_entry(struct __processor_entry *pr) 165 { 171 166 /* 172 * Find MP Floating Pointer Structure 173 * 1a. search first 1K of EBDA 174 * 1b. if EBDA is undefined, search last 1K of base memory 175 * 2. search 64K starting at 0xf0000 167 * Ignore processors which are not marked enabled. 176 168 */ 177 178 addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024); 179 for (i = 0; i < 2; i++) { 180 for (j = 0; j < length[i]; j += 16) { 181 if (*((uint32_t *) &addr[i][j]) == 182 FS_SIGNATURE && mps_fs_check(&addr[i][j])) { 183 fs = (struct mps_fs *) &addr[i][j]; 184 goto fs_found; 185 } 169 if ((pr->cpu_flags & (1 << 0)) == 0) 170 return; 171 172 apic_id_mask |= (1 << pr->l_apic_id); 173 } 174 175 static void ct_bus_entry(struct __bus_entry *bus __attribute__((unused))) 176 { 177 #ifdef MPSCT_VERBOSE 178 char buf[7]; 179 180 memcpy((void *) buf, (void *) bus->bus_type, 6); 181 buf[6] = 0; 182 183 printf("MPS: bus=%" PRIu8 " (%s)\n", bus->bus_id, buf); 184 #endif 185 } 186 187 static void ct_io_apic_entry(struct __io_apic_entry *ioa) 188 { 189 /* This I/O APIC is marked unusable */ 190 if ((ioa->io_apic_flags & 1) == 0) 191 return; 192 193 if (io_apic_cnt++ > 0) { 194 /* 195 * Multiple I/O APICs are currently not supported. 196 */ 197 return; 198 } 199 200 io_apic = (uint32_t *) (uintptr_t) ioa->io_apic; 201 } 202 203 static void ct_io_intr_entry(struct __io_intr_entry *iointr 204 __attribute__((unused))) 205 { 206 #ifdef MPSCT_VERBOSE 207 printf("MPS: "); 208 209 switch (iointr->intr_type) { 210 case 0: 211 printf("INT"); 212 break; 213 case 1: 214 printf("NMI"); 215 break; 216 case 2: 217 printf("SMI"); 218 break; 219 case 3: 220 printf("ExtINT"); 221 break; 222 } 223 224 printf(", "); 225 226 switch (iointr->poel & 3) { 227 case 0: 228 printf("bus-like"); 229 break; 230 case 1: 231 printf("active high"); 232 break; 233 case 2: 234 printf("reserved"); 235 break; 236 case 3: 237 printf("active low"); 238 break; 239 } 240 241 printf(", "); 242 243 switch ((iointr->poel >> 2) & 3) { 244 case 0: 245 printf("bus-like"); 246 break; 247 case 1: 248 printf("edge-triggered"); 249 break; 250 case 2: 251 printf("reserved"); 252 break; 253 case 3: 254 printf("level-triggered"); 255 break; 256 } 257 258 printf(", bus=%" PRIu8 " irq=%" PRIu8 " io_apic=%" PRIu8" pin=%" 259 PRIu8 "\n", iointr->src_bus_id, iointr->src_bus_irq, 260 iointr->dst_io_apic_id, iointr->dst_io_apic_pin); 261 #endif 262 } 263 264 static void ct_l_intr_entry(struct __l_intr_entry *lintr 265 __attribute__((unused))) 266 { 267 #ifdef MPSCT_VERBOSE 268 printf("MPS: "); 269 270 switch (lintr->intr_type) { 271 case 0: 272 printf("INT"); 273 break; 274 case 1: 275 printf("NMI"); 276 break; 277 case 2: 278 printf("SMI"); 279 break; 280 case 3: 281 printf("ExtINT"); 282 break; 283 } 284 285 printf(", "); 286 287 switch (lintr->poel & 3) { 288 case 0: 289 printf("bus-like"); 290 break; 291 case 1: 292 printf("active high"); 293 break; 294 case 2: 295 printf("reserved"); 296 break; 297 case 3: 298 printf("active low"); 299 break; 300 } 301 302 printf(", "); 303 304 switch ((lintr->poel >> 2) & 3) { 305 case 0: 306 printf("bus-like"); 307 break; 308 case 1: 309 printf("edge-triggered"); 310 break; 311 case 2: 312 printf("reserved"); 313 break; 314 case 3: 315 printf("level-triggered"); 316 break; 317 } 318 319 printf(", bus=%" PRIu8 " irq=%" PRIu8 " l_apic=%" PRIu8" pin=%" 320 PRIu8 "\n", lintr->src_bus_id, lintr->src_bus_irq, 321 lintr->dst_l_apic_id, lintr->dst_l_apic_pin); 322 #endif 323 } 324 325 static void ct_extended_entries(void) 326 { 327 uint8_t *ext = (uint8_t *) ct + ct->base_table_length; 328 uint8_t *cur; 329 330 for (cur = ext; cur < ext + ct->ext_table_length; 331 cur += cur[CT_EXT_ENTRY_LEN]) { 332 switch (cur[CT_EXT_ENTRY_TYPE]) { 333 default: 334 printf("MPS: Skipping MP Configuration Table extended " 335 "entry type %" PRIu8 "\n", cur[CT_EXT_ENTRY_TYPE]); 186 336 } 187 337 } 188 189 return; 190 191 fs_found: 192 printf("%p: MPS Floating Pointer Structure\n", fs); 193 194 if (fs->config_type == 0 && fs->configuration_table) { 195 if (fs->mpfib2 >> 7) { 196 printf("%s: PIC mode not supported\n", __func__); 197 return; 198 } 199 200 ct = (struct mps_ct *)PA2KA((uintptr_t)fs->configuration_table); 201 config.cpu_count = configure_via_ct(); 202 } 203 else 204 config.cpu_count = configure_via_default(fs->config_type); 205 206 return; 207 } 208 209 int configure_via_ct(void) 210 { 211 uint8_t *cur; 212 unsigned int i, cnt; 213 338 } 339 340 static void configure_via_ct(void) 341 { 214 342 if (ct->signature != CT_SIGNATURE) { 215 printf("%s: bad ct->signature\n", __func__); 216 return 1; 217 } 343 printf("MPS: Wrong ct->signature\n"); 344 return; 345 } 346 218 347 if (!mps_ct_check()) { 219 printf("%s: bad ct checksum\n", __func__); 220 return 1; 221 } 348 printf("MPS: Wrong ct checksum\n"); 349 return; 350 } 351 222 352 if (ct->oem_table) { 223 printf("%s: ct->oem_table not supported\n", __func__); 224 return 1; 225 } 226 227 l_apic = (uint32_t *)(uintptr_t)ct->l_apic; 228 229 cnt = 0; 230 cur = &ct->base_table[0]; 353 printf("MPS: ct->oem_table not supported\n"); 354 return; 355 } 356 357 l_apic = (uint32_t *) (uintptr_t) ct->l_apic; 358 359 uint8_t *cur = &ct->base_table[0]; 360 uint16_t i; 361 231 362 for (i = 0; i < ct->entry_count; i++) { 232 363 switch (*cur) { 233 /* Processor entry */ 234 case 0: 364 case 0: /* Processor entry */ 235 365 processor_entries = processor_entries ? 236 366 processor_entries : 237 367 (struct __processor_entry *) cur; 238 368 processor_entry_cnt++; 239 cnt += ct_processor_entry((struct __processor_entry *) 240 cur); 369 ct_processor_entry((struct __processor_entry *) cur); 241 370 cur += 20; 242 371 break; 243 244 /* Bus entry */ 245 case 1: 372 case 1: /* Bus entry */ 246 373 bus_entries = bus_entries ? 247 374 bus_entries : (struct __bus_entry *) cur; … … 250 377 cur += 8; 251 378 break; 252 253 /* I/O Apic */ 254 case 2: 379 case 2: /* I/O APIC */ 255 380 io_apic_entries = io_apic_entries ? 256 381 io_apic_entries : (struct __io_apic_entry *) cur; 257 382 io_apic_entry_cnt++; 258 383 ct_io_apic_entry((struct __io_apic_entry *) cur); 259 384 cur += 8; 260 385 break; 261 262 /* I/O Interrupt Assignment */ 263 case 3: 386 case 3: /* I/O Interrupt Assignment */ 264 387 io_intr_entries = io_intr_entries ? 265 388 io_intr_entries : (struct __io_intr_entry *) cur; … … 268 391 cur += 8; 269 392 break; 270 271 /* Local Interrupt Assignment */ 272 case 4: 393 case 4: /* Local Interrupt Assignment */ 273 394 l_intr_entries = l_intr_entries ? 274 395 l_intr_entries : (struct __l_intr_entry *) cur; … … 277 398 cur += 8; 278 399 break; 279 280 400 default: 281 401 /* 282 402 * Something is wrong. Fallback to UP mode. 283 403 */ 284 285 printf("%s: ct badness\n", __func__); 286 return 1; 404 printf("MPS: ct badness %" PRIu8 "\n", *cur); 405 return; 287 406 } 288 407 } … … 292 411 */ 293 412 ct_extended_entries(); 294 return cnt; 295 } 296 297 int configure_via_default(uint8_t n __attribute__((unused))) 413 } 414 415 static void configure_via_default(uint8_t n __attribute__((unused))) 298 416 { 299 417 /* 300 418 * Not yet implemented. 301 419 */ 302 printf("%s: not supported\n", __func__); 303 return 1; 304 } 305 306 307 int ct_processor_entry(struct __processor_entry *pr __attribute__((unused))) 308 { 420 printf("MPS: Default configuration not supported\n"); 421 } 422 423 void mps_init(void) 424 { 425 uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xf0000) }; 426 unsigned int i; 427 unsigned int j; 428 unsigned int length[2] = { 1024, 64 * 1024 }; 429 309 430 /* 310 * Ignore processors which are not marked enabled. 431 * Find MP Floating Pointer Structure 432 * 1a. search first 1K of EBDA 433 * 1b. if EBDA is undefined, search last 1K of base memory 434 * 2. search 64K starting at 0xf0000 311 435 */ 312 if ((pr->cpu_flags & (1 << 0)) == 0) 313 return 0; 314 315 apic_id_mask |= (1 << pr->l_apic_id); 316 return 1; 317 } 318 319 void ct_bus_entry(struct __bus_entry *bus __attribute__((unused))) 320 { 321 #ifdef MPSCT_VERBOSE 322 char buf[7]; 323 memcpy((void *) buf, (void *) bus->bus_type, 6); 324 buf[6] = 0; 325 printf("bus%d: %s\n", bus->bus_id, buf); 326 #endif 327 } 328 329 void ct_io_apic_entry(struct __io_apic_entry *ioa) 330 { 331 static unsigned int io_apic_count = 0; 332 333 /* this ioapic is marked unusable */ 334 if ((ioa->io_apic_flags & 1) == 0) 335 return; 336 337 if (io_apic_count++ > 0) { 338 /* 339 * Multiple IO APIC's are currently not supported. 340 */ 341 return; 342 } 343 344 io_apic = (uint32_t *)(uintptr_t)ioa->io_apic; 345 } 346 347 //#define MPSCT_VERBOSE 348 void ct_io_intr_entry(struct __io_intr_entry *iointr __attribute__((unused))) 349 { 350 #ifdef MPSCT_VERBOSE 351 switch (iointr->intr_type) { 352 case 0: 353 printf("INT"); 354 break; 355 case 1: 356 printf("NMI"); 357 break; 358 case 2: 359 printf("SMI"); 360 break; 361 case 3: 362 printf("ExtINT"); 363 break; 364 } 365 putchar(','); 366 switch (iointr->poel & 3) { 367 case 0: 368 printf("bus-like"); 369 break; 370 case 1: 371 printf("active high"); 372 break; 373 case 2: 374 printf("reserved"); 375 break; 376 case 3: 377 printf("active low"); 378 break; 379 } 380 putchar(','); 381 switch ((iointr->poel >> 2) & 3) { 382 case 0: 383 printf("bus-like"); 384 break; 385 case 1: 386 printf("edge-triggered"); 387 break; 388 case 2: 389 printf("reserved"); 390 break; 391 case 3: 392 printf("level-triggered"); 393 break; 394 } 395 putchar(','); 396 printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq); 397 putchar(','); 398 printf("io_apic%d,pin%d", iointr->dst_io_apic_id, 399 iointr->dst_io_apic_pin); 400 putchar('\n'); 401 #endif 402 } 403 404 void ct_l_intr_entry(struct __l_intr_entry *lintr __attribute__((unused))) 405 { 406 #ifdef MPSCT_VERBOSE 407 switch (lintr->intr_type) { 408 case 0: 409 printf("INT"); 410 break; 411 case 1: 412 printf("NMI"); 413 break; 414 case 2: 415 printf("SMI"); 416 break; 417 case 3: 418 printf("ExtINT"); 419 break; 420 } 421 putchar(','); 422 switch (lintr->poel & 3) { 423 case 0: 424 printf("bus-like"); 425 break; 426 case 1: 427 printf("active high"); 428 break; 429 case 2: 430 printf("reserved"); 431 break; 432 case 3: 433 printf("active low"); 434 break; 435 } 436 putchar(','); 437 switch ((lintr->poel >> 2) & 3) { 438 case 0: 439 printf("bus-like"); 440 break; 441 case 1: 442 printf("edge-triggered"); 443 break; 444 case 2: 445 printf("reserved"); 446 break; 447 case 3: 448 printf("level-triggered"); 449 break; 450 } 451 putchar(','); 452 printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq); 453 putchar(','); 454 printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin); 455 putchar('\n'); 456 #endif 457 } 458 459 void ct_extended_entries(void) 460 { 461 uint8_t *ext = (uint8_t *) ct + ct->base_table_length; 462 uint8_t *cur; 463 464 for (cur = ext; cur < ext + ct->ext_table_length; 465 cur += cur[CT_EXT_ENTRY_LEN]) { 466 switch (cur[CT_EXT_ENTRY_TYPE]) { 467 default: 468 printf("%p: skipping MP Configuration Table extended " 469 "entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]); 470 break; 436 437 addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024); 438 for (i = 0; i < 2; i++) { 439 for (j = 0; j < length[i]; j += 16) { 440 if ((*((uint32_t *) &addr[i][j]) == 441 FS_SIGNATURE) && (mps_fs_check(&addr[i][j]))) { 442 fs = (struct mps_fs *) &addr[i][j]; 443 goto fs_found; 444 } 471 445 } 472 446 } 473 } 474 475 int mps_irq_to_pin(unsigned int irq) 476 { 477 unsigned int i; 478 479 for (i = 0; i < io_intr_entry_cnt; i++) { 480 if (io_intr_entries[i].src_bus_irq == irq && 481 io_intr_entries[i].intr_type == 0) 482 return io_intr_entries[i].dst_io_apic_pin; 483 } 484 485 return -1; 447 448 return; 449 450 fs_found: 451 printf("%p: MPS Floating Pointer Structure\n", fs); 452 453 if ((fs->config_type == 0) && (fs->configuration_table)) { 454 if (fs->mpfib2 >> 7) { 455 printf("MPS: PIC mode not supported\n"); 456 return; 457 } 458 459 ct = (struct mps_ct *) PA2KA((uintptr_t) fs->configuration_table); 460 configure_via_ct(); 461 } else 462 configure_via_default(fs->config_type); 463 464 if (processor_entry_cnt > 0) 465 config.cpu_count = processor_entry_cnt; 486 466 } 487 467 -
kernel/arch/ia32/src/smp/smp.c
re4a4b44 rf56e897f 62 62 void smp_init(void) 63 63 { 64 uintptr_t l_apic_address, io_apic_address; 65 64 uintptr_t l_apic_address; 65 uintptr_t io_apic_address; 66 66 67 if (acpi_madt) { 67 68 acpi_madt_parse(); 68 69 ops = &madt_config_operations; 69 70 } 71 70 72 if (config.cpu_count == 1) { 71 73 mps_init(); 72 74 ops = &mps_config_operations; 73 75 } 74 76 75 77 l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, 76 78 FRAME_ATOMIC | FRAME_KA); 77 79 if (!l_apic_address) 78 80 panic("Cannot allocate address for l_apic."); 79 81 80 82 io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, 81 83 FRAME_ATOMIC | FRAME_KA); 82 84 if (!io_apic_address) 83 85 panic("Cannot allocate address for io_apic."); 84 86 85 87 if (config.cpu_count > 1) { 86 88 page_table_lock(AS_KERNEL, true); … … 90 92 (uintptr_t) io_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE); 91 93 page_table_unlock(AS_KERNEL, true); 92 94 93 95 l_apic = (uint32_t *) l_apic_address; 94 96 io_apic = (uint32_t *) io_apic_address; … … 108 110 109 111 ASSERT(ops != NULL); 110 112 111 113 /* 112 114 * We need to access data in frame 0. 113 115 * We boldly make use of kernel address space mapping. 114 116 */ 115 117 116 118 /* 117 119 * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot() 118 120 */ 119 121 *((uint16_t *) (PA2KA(0x467 + 0))) = 120 (uint16_t) (((uintptr_t) ap_boot) >> 4); 121 *((uint16_t *) (PA2KA(0x467 + 2))) = 0; 122 (uint16_t) (((uintptr_t) ap_boot) >> 4); /* segment */ 123 *((uint16_t *) (PA2KA(0x467 + 2))) = 0; /* offset */ 122 124 123 125 /* … … 125 127 * BIOS will not do the POST after the INIT signal. 126 128 */ 127 pio_write_8((ioport8_t *) 0x70, 0xf);128 pio_write_8((ioport8_t *) 0x71, 0xa);129 129 pio_write_8((ioport8_t *) 0x70, 0xf); 130 pio_write_8((ioport8_t *) 0x71, 0xa); 131 130 132 pic_disable_irqs(0xffff); 131 133 apic_init(); 132 134 133 135 uint8_t apic = l_apic_id(); 134 135 for (i = 0; i < ops->cpu_count(); i++) { 136 descriptor_t *gdt_new; 137 136 137 for (i = 0; i < config.cpu_count; i++) { 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 gdt_new = (descriptor_t *) malloc(GDT_ITEMS * 165 sizeof(descriptor_t), FRAME_ATOMIC); 164 descriptor_t *gdt_new = 165 (descriptor_t *) malloc(GDT_ITEMS * sizeof(descriptor_t), 166 FRAME_ATOMIC); 166 167 if (!gdt_new) 167 168 panic("Cannot allocate memory for GDT."); 168 169 169 170 memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(descriptor_t)); 170 171 memsetb(&gdt_new[TSS_DES], sizeof(descriptor_t), 0); … … 172 173 protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new); 173 174 gdtr.base = (uintptr_t) gdt_new; 174 175 175 176 if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) { 176 177 /* … … 181 182 if (waitq_sleep_timeout(&ap_completion_wq, 1000000, 182 183 SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) { 183 unsigned int cpu = (config.cpu_active > i) ?184 config.cpu_active : i;185 184 printf("%s: waiting for cpu%u (APIC ID = %d) " 186 "timed out\n", __FUNCTION__, cpu,185 "timed out\n", __FUNCTION__, i, 187 186 ops->cpu_apic_id(i)); 188 187 } -
kernel/arch/ppc32/src/mm/frame.c
re4a4b44 rf56e897f 60 60 61 61 for (i = 0; i < memmap.cnt; i++) { 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)); 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); 65 70 66 71 pfn_t conf; 67 if ((minconf < start) || (minconf >= start + size))68 conf = start;72 if ((minconf < pfn) || (minconf >= pfn + count)) 73 conf = pfn; 69 74 else 70 75 conf = minconf; 71 76 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); 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); 77 81 } 78 82 -
kernel/arch/sparc64/src/mm/sun4u/frame.c
re4a4b44 rf56e897f 49 49 void frame_arch_init(void) 50 50 { 51 unsigned int i;52 pfn_t confdata;53 54 51 if (config.cpu_active == 1) { 52 unsigned int i; 53 55 54 for (i = 0; i < memmap.cnt; i++) { 56 uintptr_t start = (uintptr_t) memmap.zones[i].start; 57 size_t size = memmap.zones[i].size; 58 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 59 61 /* 60 62 * The memmap is created by HelenOS boot loader. 61 63 * It already contains no holes. 62 64 */ 63 64 confdata = ADDR2PFN(start); 65 66 pfn_t confdata = ADDR2PFN(new_start); 67 65 68 if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0)))) 66 69 confdata = ADDR2PFN(KA2PA(PFN2ADDR(2))); 67 zone_create(ADDR2PFN(start),68 SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)),70 71 zone_create(ADDR2PFN(new_start), SIZE2FRAMES(new_size), 69 72 confdata, 0); 70 last_frame = max(last_frame, start + ALIGN_UP(size,71 FRAME_SIZE));73 74 last_frame = max(last_frame, new_start + new_size); 72 75 } 73 76 74 77 /* 75 78 * On sparc64, physical memory can start on a non-zero address. … … 80 83 frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1); 81 84 } 82 85 83 86 end_of_identity = PA2KA(last_frame); 84 87 } -
kernel/arch/sparc64/src/mm/sun4v/frame.c
re4a4b44 rf56e897f 47 47 void frame_arch_init(void) 48 48 { 49 unsigned int i;50 pfn_t confdata;51 52 49 if (config.cpu_active == 1) { 50 unsigned int i; 51 53 52 for (i = 0; i < memmap.cnt; i++) { 54 uintptr_t start = (uintptr_t) memmap.zones[i].start; 55 size_t size = memmap.zones[i].size; 56 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 57 59 /* 58 60 * The memmap is created by HelenOS boot loader. 59 61 * It already contains no holes. 60 62 */ 61 62 confdata = ADDR2PFN(start); 63 64 pfn_t confdata = ADDR2PFN(new_start); 65 63 66 if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0)))) 64 67 confdata = ADDR2PFN(KA2PA(PFN2ADDR(2))); 65 zone_create(ADDR2PFN(start),66 SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)),68 69 zone_create(ADDR2PFN(new_start), SIZE2FRAMES(new_size), 67 70 confdata, 0); 68 71 } 69 72 70 73 /* 71 74 * On sparc64, physical memory can start on a non-zero address. -
kernel/genarch/include/acpi/acpi.h
re4a4b44 rf56e897f 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
re4a4b44 rf56e897f 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 60 59 61 60 /* Multiple APIC Description Table */ … … 71 70 uint8_t acpi_id; 72 71 uint8_t apic_id; 73 uint32_t flags; 72 uint32_t flags; 74 73 } __attribute__ ((packed)); 75 74 … … 78 77 uint8_t io_apic_id; 79 78 uint8_t reserved; 80 uint32_t io_apic_address; 79 uint32_t io_apic_address; 81 80 uint32_t global_intr_base; 82 81 } __attribute__ ((packed)); … … 114 113 uint8_t reserved; 115 114 uint32_t global_intr_base; 116 uint64_t io_apic_address; 115 uint64_t io_apic_address; 117 116 } __attribute__ ((packed)); 118 117 -
kernel/genarch/src/acpi/acpi.c
re4a4b44 rf56e897f 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 *r = (struct acpi_rsdp *) rsdp; 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; 68 89 uint8_t sum = 0; 69 90 unsigned int i; 70 91 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 92 for (i = 0; i < hdr->length; i++) 93 sum = (uint8_t) (sum + sdt[i]); 94 83 95 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++)94 sum = (uint8_t) (sum + sdt[i]);95 96 return !sum;97 96 } 98 97 … … 100 99 { 101 100 page_table_lock(AS_KERNEL, true); 102 page_mapping_insert(AS_KERNEL, (uintptr_t) sdt, (uintptr_t) sdt, PAGE_NOT_CACHEABLE | PAGE_WRITE); 101 page_mapping_insert(AS_KERNEL, (uintptr_t) sdt, (uintptr_t) sdt, 102 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 unsigned int i, j, cnt = (acpi_rsdt->header.length - sizeof(struct acpi_sdt_header)) / sizeof(uint32_t); 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); 110 113 111 114 for (i = 0; i < cnt; i++) { 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); 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); 121 128 } 122 129 } 123 next:124 ;125 130 } 126 131 } … … 128 133 static void configure_via_xsdt(void) 129 134 { 130 unsigned int i, j, cnt = (acpi_xsdt->header.length - sizeof(struct acpi_sdt_header)) / sizeof(uint64_t); 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); 131 139 132 140 for (i = 0; i < cnt; i++) { 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); 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); 142 154 } 143 155 } 144 next: 145 ; 146 } 147 156 } 148 157 } 149 158 … … 151 160 { 152 161 uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xe0000) }; 153 int i, j, length[2] = { 1024, 128*1024 }; 162 unsigned int i; 163 unsigned int j; 164 unsigned int length[2] = { 1024, 128 * 1024 }; 154 165 uint64_t *sig = (uint64_t *) RSDP_SIGNATURE; 155 166 156 167 /* 157 168 * Find Root System Description Pointer … … 159 170 * 2. search 128K starting at 0xe0000 160 171 */ 161 172 162 173 addr[0] = (uint8_t *) PA2KA(ebda); 163 174 for (i = (ebda ? 0 : 1); i < 2; i++) { 164 175 for (j = 0; j < length[i]; j += 16) { 165 if (*((uint64_t *) &addr[i][j]) == *sig && rsdp_check(&addr[i][j])) { 176 if ((*((uint64_t *) &addr[i][j]) == *sig) 177 && (rsdp_check(&addr[i][j]))) { 166 178 acpi_rsdp = (struct acpi_rsdp *) &addr[i][j]; 167 179 goto rsdp_found; … … 169 181 } 170 182 } 171 183 172 184 return; 173 185 174 186 rsdp_found: 175 LOG("%p: ACPI Root System Description Pointer \n", acpi_rsdp);176 177 acpi_rsdt = (struct acpi_rsdt *) ( unative_t) acpi_rsdp->rsdt_address;187 LOG("%p: ACPI Root System Description Pointer", acpi_rsdp); 188 189 acpi_rsdt = (struct acpi_rsdt *) ((uintptr_t) acpi_rsdp->rsdt_address); 178 190 if (acpi_rsdp->revision) 179 191 acpi_xsdt = (struct acpi_xsdt *) ((uintptr_t) acpi_rsdp->xsdt_address); 180 192 181 193 if (acpi_rsdt) 182 194 map_sdt((struct acpi_sdt_header *) acpi_rsdt); 195 183 196 if (acpi_xsdt) 184 197 map_sdt((struct acpi_sdt_header *) acpi_xsdt); 185 186 if ( acpi_rsdt && !acpi_sdt_check((uint8_t *) acpi_rsdt)) {198 199 if ((acpi_rsdt) && (!acpi_sdt_check((uint8_t *) acpi_rsdt))) { 187 200 printf("RSDT: bad checksum\n"); 188 201 return; 189 202 } 190 if (acpi_xsdt && !acpi_sdt_check((uint8_t *) acpi_xsdt)) { 203 204 if ((acpi_xsdt) && (!acpi_sdt_check((uint8_t *) acpi_xsdt))) { 191 205 printf("XSDT: bad checksum\n"); 192 206 return; 193 207 } 194 208 195 209 if (acpi_xsdt) 196 210 configure_via_xsdt(); 197 211 else if (acpi_rsdt) 198 212 configure_via_rsdt(); 199 200 213 } 201 214 -
kernel/genarch/src/acpi/madt.c
re4a4b44 rf56e897f 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 /** 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); 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 }; 61 60 62 61 struct madt_l_apic *madt_l_apic_entries = NULL; 63 62 struct madt_io_apic *madt_io_apic_entries = NULL; 64 63 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; 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; 73 70 74 71 const char *entry[] = { … … 84 81 }; 85 82 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 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 */ 95 126 struct smp_config_operations madt_config_operations = { 96 .cpu_count = madt_cpu_count,97 127 .cpu_enabled = madt_cpu_enabled, 98 128 .cpu_bootstrap = madt_cpu_bootstrap, … … 101 131 }; 102 132 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 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 213 152 if (!(la->flags & 0x1)) { 214 153 /* Processor is unusable, skip it. */ … … 216 155 } 217 156 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) 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) 223 161 { 224 162 if (!madt_io_apic_entry_cnt++) { 225 /* remember index of the first io apic entry */226 madt_io_apic_entry_index = i ndex;163 /* Remember index of the first io apic entry */ 164 madt_io_apic_entry_index = i; 227 165 io_apic = (uint32_t *) (unative_t) ioa->io_apic_address; 228 166 } else { 229 /* currently not supported */ 230 return; 167 /* Currently not supported */ 231 168 } 232 169 } 233 170 234 void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, uint32_t index) 171 static void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, 172 size_t i) 235 173 { 236 174 ASSERT(override->source < sizeof(isa_irq_map) / sizeof(int)); 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); 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; 240 252 } 241 253 -
kernel/generic/include/atomic.h
re4a4b44 rf56e897f 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) 43 45 { 44 46 val->count = i; … … 46 48 47 49 ATOMIC static inline atomic_count_t atomic_get(atomic_t *val) 50 REQUIRES_EXTENT_MUTABLE(val) 48 51 { 49 52 return val->count; -
kernel/generic/include/config.h
re4a4b44 rf56e897f 70 70 71 71 uintptr_t base; 72 size_t kernel_size; 72 size_t kernel_size; /**< Size of memory in bytes taken by kernel and stack */ 73 73 74 uintptr_t stack_base; 75 size_t stack_size; 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
re4a4b44 rf56e897f 43 43 #else 44 44 45 45 #define ipi_broadcast(ipi) 46 46 47 47 #endif /* CONFIG_SMP */ -
kernel/generic/include/verify.h
re4a4b44 rf56e897f 39 39 #ifdef CONFIG_VERIFY_VCC 40 40 41 #define ATOMIC __spec_attr("atomic_inline", "") 42 #define REQUIRES(...) __requires(__VA_ARGS__) 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)) 43 55 44 56 #else /* CONFIG_VERIFY_VCC */ 45 57 46 58 #define ATOMIC 59 60 #define READS(ptr) 61 #define WRITES(ptr) 47 62 #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) 48 69 49 70 #endif /* CONFIG_VERIFY_VCC */ -
kernel/generic/src/debug/symtab.c
re4a4b44 rf56e897f 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, "Not found" if none exists 86 * or "N/A" if no symbol information is available. 85 * Returns name of closest corresponding symbol, 86 * "unknown" if none exists and "N/A" if no symbol 87 * information is available. 87 88 * 88 89 * @param addr Address. … … 101 102 return name; 102 103 case ENOENT: 103 return " Not found";104 return "unknown"; 104 105 default: 105 106 return "N/A"; -
kernel/generic/src/interrupt/interrupt.c
re4a4b44 rf56e897f 143 143 uint64_t end_cycle = get_cycle(); 144 144 145 irq_spinlock_lock(&exctbl_lock, false); 145 146 exc_table[n].cycles += end_cycle - begin_cycle; 146 147 exc_table[n].count++; 148 irq_spinlock_unlock(&exctbl_lock, false); 147 149 148 150 /* Do not charge THREAD for exception cycles */ -
kernel/generic/src/ipc/sysipc.c
re4a4b44 rf56e897f 1150 1150 return (unative_t) rc; 1151 1151 1152 LOG("sys_ipc_connect_kbox(%" PRIu64 ") \n", taskid_arg.value);1152 LOG("sys_ipc_connect_kbox(%" PRIu64 ")", taskid_arg.value); 1153 1153 1154 1154 return ipc_connect_kbox(taskid_arg.value); -
kernel/generic/src/main/kinit.c
re4a4b44 rf56e897f 107 107 if (config.cpu_count > 1) { 108 108 waitq_initialize(&ap_completion_wq); 109 109 110 /* 110 111 * Create the kmp thread and wait for its completion. … … 124 125 thread_join(thread); 125 126 thread_detach(thread); 126 } 127 128 if (config.cpu_count > 1) { 127 128 /* 129 * For each CPU, create its load balancing thread. 130 */ 129 131 size_t i; 130 132 131 /*132 * For each CPU, create its load balancing thread.133 */134 133 for (i = 0; i < config.cpu_count; i++) { 135 134 thread = thread_create(kcpulb, NULL, TASK, THREAD_FLAG_WIRED, "kcpulb", true); -
kernel/generic/src/mm/frame.c
re4a4b44 rf56e897f 1234 1234 { 1235 1235 #ifdef __32_BITS__ 1236 printf("[nr] [base addr 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 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(" 1276 printf(" %10p", base); 1277 1277 #endif 1278 1278 1279 1279 #ifdef __64_BITS__ 1280 printf(" 1280 printf(" %18p", base); 1281 1281 #endif 1282 1282 -
kernel/generic/src/mm/tlb.c
re4a4b44 rf56e897f 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 * 81 82 */ 82 83 ipl_t tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, 83 84 uintptr_t page, size_t count) 84 85 { 85 ipl_t ipl; 86 87 ipl = interrupts_disable(); 86 ipl_t ipl = interrupts_disable(); 88 87 CPU->tlb_active = false; 89 88 irq_spinlock_lock(&tlblock, false); … … 91 90 size_t i; 92 91 for (i = 0; i < config.cpu_count; i++) { 93 cpu_t *cpu;94 95 92 if (i == CPU->id) 96 93 continue; 97 94 98 cpu = &cpus[i]; 95 cpu_t *cpu = &cpus[i]; 96 99 97 irq_spinlock_lock(&cpu->lock, false); 100 98 if (cpu->tlb_messages_count == TLB_MESSAGE_QUEUE_LEN) { … … 124 122 125 123 busy_wait: 126 for (i = 0; i < config.cpu_count; i++) 124 for (i = 0; i < config.cpu_count; i++) { 127 125 if (cpus[i].tlb_active) 128 126 goto busy_wait; 129 127 } 128 130 129 return ipl; 131 130 } … … 133 132 /** Finish TLB shootdown sequence. 134 133 * 135 * @param ipl Previous interrupt priority level. 134 * @param ipl Previous interrupt priority level. 135 * 136 136 */ 137 137 void tlb_shootdown_finalize(ipl_t ipl) -
kernel/generic/src/proc/program.c
re4a4b44 rf56e897f 145 145 146 146 program_loader = image_addr; 147 LOG("Registered program loader at 0x%" PRIp "\n",147 LOG("Registered program loader at 0x%" PRIp, 148 148 image_addr); 149 149 -
kernel/generic/src/smp/ipi.c
re4a4b44 rf56e897f 47 47 * @param ipi Message to broadcast. 48 48 * 49 * @bug The decision whether to actually send the IPI must be based50 * on a different criterion. The current version has51 * problems when some of the detected CPUs are marked52 * disabled in machine configuration.53 49 */ 54 50 void ipi_broadcast(int ipi) … … 60 56 */ 61 57 62 if ( (config.cpu_active > 1) && (config.cpu_active == config.cpu_count))58 if (config.cpu_count > 1) 63 59 ipi_broadcast_arch(ipi); 64 60 } -
tools/checkers/vcc.py
re4a4b44 rf56e897f 45 45 re_va_list = re.compile("__builtin_va_list") 46 46 47 specification = "" 48 47 49 def usage(prname): 48 50 "Print usage syntax" … … 57 59 "Preprocess source using GCC preprocessor and compatibility tweaks" 58 60 61 global specification 62 59 63 args = ['gcc', '-E'] 60 64 args.extend(options.split()) … … 69 73 70 74 tmpf = file(tmpfname, "w") 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"); 75 tmpf.write(specification) 77 76 78 77 for line in preproc.splitlines(): … … 155 154 # Run Vcc 156 155 print " -- %s --" % srcfname 157 retval = subprocess.Popen([vcc_path, '/pointersize:32', cygpath(tmpfqname)]).wait()156 retval = subprocess.Popen([vcc_path, '/pointersize:32', '/newsyntax', cygpath(tmpfqname)]).wait() 158 157 159 158 if (retval != 0): … … 170 169 171 170 def main(): 171 global specification 172 172 173 if (len(sys.argv) < 2): 173 174 usage(sys.argv[0]) … … 192 193 return 193 194 195 specpath = os.path.join(rootdir, "tools/checkers/vcc.h") 196 if (not os.path.isfile(specpath)): 197 print "%s not found." % config 198 return 199 200 specfile = file(specpath, "r") 201 specification = specfile.read() 202 specfile.close() 203 194 204 for job in jobs: 195 205 if (not vcc(vcc_path, rootdir, job)):
Note:
See TracChangeset
for help on using the changeset viewer.