Changeset f56e897f in mainline for kernel/arch/ia32
- Timestamp:
- 2010-06-29T17:43:38Z (16 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. - Location:
- kernel/arch/ia32
- Files:
-
- 13 edited
-
include/bios/bios.h (modified) (2 diffs)
-
include/drivers/i8259.h (modified) (1 diff)
-
include/fpu_context.h (modified) (2 diffs)
-
include/mm/asid.h (modified) (2 diffs)
-
include/smp/mps.h (modified) (6 diffs)
-
include/smp/smp.h (modified) (2 diffs)
-
src/bios/bios.c (modified) (1 diff)
-
src/ia32.c (modified) (1 diff)
-
src/mm/as.c (modified) (1 diff)
-
src/mm/frame.c (modified) (7 diffs)
-
src/mm/tlb.c (modified) (1 diff)
-
src/smp/mps.c (modified) (8 diffs)
-
src/smp/smp.c (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
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 0x40e40 #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]; /* FXSAVE & FXRSTOR storage area */43 uint8_t fpu[512]; /* FXSAVE & FXRSTOR storage area */ 48 44 } fpu_context_t; 45 46 extern void fpu_fxsr(void); 47 extern void fpu_fsr(void); 49 48 50 49 #endif -
kernel/arch/ia32/include/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 349 #define ASID_MAX_ARCH 3 50 50 51 #define asid_get() (ASID_START + 1)51 #define asid_get() (ASID_START + 1) 52 52 #define asid_put(asid) 53 53 -
kernel/arch/ia32/include/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 044 #define CT_EXT_ENTRY_LEN 143 #define CT_EXT_ENTRY_TYPE 0 44 #define CT_EXT_ENTRY_LEN 1 45 45 46 46 struct mps_fs { … … 70 70 uint16_t ext_table_length; 71 71 uint8_t ext_table_checksum; 72 uint8_t xxx;72 uint8_t reserved; 73 73 uint8_t base_table[0]; 74 74 } __attribute__ ((packed)); … … 81 81 uint8_t cpu_signature[4]; 82 82 uint32_t feature_flags; 83 uint32_t xxx[2];83 uint32_t reserved[2]; 84 84 } __attribute__ ((packed)); 85 85 … … 102 102 uint8_t intr_type; 103 103 uint8_t poel; 104 uint8_t xxx;104 uint8_t reserved; 105 105 uint8_t src_bus_id; 106 106 uint8_t src_bus_irq; … … 113 113 uint8_t intr_type; 114 114 uint8_t poel; 115 uint8_t xxx;115 uint8_t reserved; 116 116 uint8_t src_bus_id; 117 117 uint8_t src_bus_irq; -
kernel/arch/ia32/include/smp/smp.h
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 if (config.cpu_active > 1) {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 io_apic_entry_cnt++;382 io_apic_entry_cnt++; 258 383 ct_io_apic_entry((struct __io_apic_entry *) cur); 259 384 cur += 8; 260 385 break; 261 262 /* I/O Interrupt Assignment */ 263 case 3: 386 case 3: /* I/O Interrupt Assignment */ 264 387 io_intr_entries = io_intr_entries ? 265 388 io_intr_entries : (struct __io_intr_entry *) cur; … … 268 391 cur += 8; 269 392 break; 270 271 /* Local Interrupt Assignment */ 272 case 4: 393 case 4: /* Local Interrupt Assignment */ 273 394 l_intr_entries = l_intr_entries ? 274 395 l_intr_entries : (struct __l_intr_entry *) cur; … … 277 398 cur += 8; 278 399 break; 279 280 400 default: 281 401 /* 282 402 * Something is wrong. Fallback to UP mode. 283 403 */ 284 285 printf("%s: ct badness\n", __func__); 286 return 1; 404 printf("MPS: ct badness %" PRIu8 "\n", *cur); 405 return; 287 406 } 288 407 } … … 292 411 */ 293 412 ct_extended_entries(); 294 return cnt; 295 } 296 297 int configure_via_default(uint8_t n __attribute__((unused))) 413 } 414 415 static void configure_via_default(uint8_t n __attribute__((unused))) 298 416 { 299 417 /* 300 418 * Not yet implemented. 301 419 */ 302 printf("%s: not supported\n", __func__); 303 return 1; 304 } 305 306 307 int ct_processor_entry(struct __processor_entry *pr __attribute__((unused))) 308 { 420 printf("MPS: Default configuration not supported\n"); 421 } 422 423 void mps_init(void) 424 { 425 uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xf0000) }; 426 unsigned int i; 427 unsigned int j; 428 unsigned int length[2] = { 1024, 64 * 1024 }; 429 309 430 /* 310 * Ignore processors which are not marked enabled. 431 * Find MP Floating Pointer Structure 432 * 1a. search first 1K of EBDA 433 * 1b. if EBDA is undefined, search last 1K of base memory 434 * 2. search 64K starting at 0xf0000 311 435 */ 312 if ((pr->cpu_flags & (1 << 0)) == 0) 313 return 0; 314 315 apic_id_mask |= (1 << pr->l_apic_id); 316 return 1; 317 } 318 319 void ct_bus_entry(struct __bus_entry *bus __attribute__((unused))) 320 { 321 #ifdef MPSCT_VERBOSE 322 char buf[7]; 323 memcpy((void *) buf, (void *) bus->bus_type, 6); 324 buf[6] = 0; 325 printf("bus%d: %s\n", bus->bus_id, buf); 326 #endif 327 } 328 329 void ct_io_apic_entry(struct __io_apic_entry *ioa) 330 { 331 static unsigned int io_apic_count = 0; 332 333 /* this ioapic is marked unusable */ 334 if ((ioa->io_apic_flags & 1) == 0) 335 return; 336 337 if (io_apic_count++ > 0) { 338 /* 339 * Multiple IO APIC's are currently not supported. 340 */ 341 return; 342 } 343 344 io_apic = (uint32_t *)(uintptr_t)ioa->io_apic; 345 } 346 347 //#define MPSCT_VERBOSE 348 void ct_io_intr_entry(struct __io_intr_entry *iointr __attribute__((unused))) 349 { 350 #ifdef MPSCT_VERBOSE 351 switch (iointr->intr_type) { 352 case 0: 353 printf("INT"); 354 break; 355 case 1: 356 printf("NMI"); 357 break; 358 case 2: 359 printf("SMI"); 360 break; 361 case 3: 362 printf("ExtINT"); 363 break; 364 } 365 putchar(','); 366 switch (iointr->poel & 3) { 367 case 0: 368 printf("bus-like"); 369 break; 370 case 1: 371 printf("active high"); 372 break; 373 case 2: 374 printf("reserved"); 375 break; 376 case 3: 377 printf("active low"); 378 break; 379 } 380 putchar(','); 381 switch ((iointr->poel >> 2) & 3) { 382 case 0: 383 printf("bus-like"); 384 break; 385 case 1: 386 printf("edge-triggered"); 387 break; 388 case 2: 389 printf("reserved"); 390 break; 391 case 3: 392 printf("level-triggered"); 393 break; 394 } 395 putchar(','); 396 printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq); 397 putchar(','); 398 printf("io_apic%d,pin%d", iointr->dst_io_apic_id, 399 iointr->dst_io_apic_pin); 400 putchar('\n'); 401 #endif 402 } 403 404 void ct_l_intr_entry(struct __l_intr_entry *lintr __attribute__((unused))) 405 { 406 #ifdef MPSCT_VERBOSE 407 switch (lintr->intr_type) { 408 case 0: 409 printf("INT"); 410 break; 411 case 1: 412 printf("NMI"); 413 break; 414 case 2: 415 printf("SMI"); 416 break; 417 case 3: 418 printf("ExtINT"); 419 break; 420 } 421 putchar(','); 422 switch (lintr->poel & 3) { 423 case 0: 424 printf("bus-like"); 425 break; 426 case 1: 427 printf("active high"); 428 break; 429 case 2: 430 printf("reserved"); 431 break; 432 case 3: 433 printf("active low"); 434 break; 435 } 436 putchar(','); 437 switch ((lintr->poel >> 2) & 3) { 438 case 0: 439 printf("bus-like"); 440 break; 441 case 1: 442 printf("edge-triggered"); 443 break; 444 case 2: 445 printf("reserved"); 446 break; 447 case 3: 448 printf("level-triggered"); 449 break; 450 } 451 putchar(','); 452 printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq); 453 putchar(','); 454 printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin); 455 putchar('\n'); 456 #endif 457 } 458 459 void ct_extended_entries(void) 460 { 461 uint8_t *ext = (uint8_t *) ct + ct->base_table_length; 462 uint8_t *cur; 463 464 for (cur = ext; cur < ext + ct->ext_table_length; 465 cur += cur[CT_EXT_ENTRY_LEN]) { 466 switch (cur[CT_EXT_ENTRY_TYPE]) { 467 default: 468 printf("%p: skipping MP Configuration Table extended " 469 "entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]); 470 break; 436 437 addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024); 438 for (i = 0; i < 2; i++) { 439 for (j = 0; j < length[i]; j += 16) { 440 if ((*((uint32_t *) &addr[i][j]) == 441 FS_SIGNATURE) && (mps_fs_check(&addr[i][j]))) { 442 fs = (struct mps_fs *) &addr[i][j]; 443 goto fs_found; 444 } 471 445 } 472 446 } 473 } 474 475 int mps_irq_to_pin(unsigned int irq) 476 { 477 unsigned int i; 478 479 for (i = 0; i < io_intr_entry_cnt; i++) { 480 if (io_intr_entries[i].src_bus_irq == irq && 481 io_intr_entries[i].intr_type == 0) 482 return io_intr_entries[i].dst_io_apic_pin; 483 } 484 485 return -1; 447 448 return; 449 450 fs_found: 451 printf("%p: MPS Floating Pointer Structure\n", fs); 452 453 if ((fs->config_type == 0) && (fs->configuration_table)) { 454 if (fs->mpfib2 >> 7) { 455 printf("MPS: PIC mode not supported\n"); 456 return; 457 } 458 459 ct = (struct mps_ct *) PA2KA((uintptr_t) fs->configuration_table); 460 configure_via_ct(); 461 } else 462 configure_via_default(fs->config_type); 463 464 if (processor_entry_cnt > 0) 465 config.cpu_count = processor_entry_cnt; 486 466 } 487 467 -
kernel/arch/ia32/src/smp/smp.c
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); /* segment */121 *((uint16_t *) (PA2KA(0x467 + 2))) = 0; /* offset */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 }
Note:
See TracChangeset
for help on using the changeset viewer.
