| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: cpu.c,v 1.209 2023/07/16 19:55:43 riastradh Exp $ */ | | 1 | /* $NetBSD: cpu.c,v 1.210 2024/04/22 23:07:47 andvar Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2000-2020 NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2000-2020 NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Bill Sommerfeld of RedBack Networks Inc, and by Andrew Doran. | | 8 | * by Bill Sommerfeld of RedBack Networks Inc, and by Andrew Doran. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -52,27 +52,27 @@ | | | @@ -52,27 +52,27 @@ |
52 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 52 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
53 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 53 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
54 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE | | 54 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE |
55 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 55 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
56 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 56 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
57 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 57 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
58 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 58 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
59 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 59 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
60 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 60 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
61 | * SUCH DAMAGE. | | 61 | * SUCH DAMAGE. |
62 | */ | | 62 | */ |
63 | | | 63 | |
64 | #include <sys/cdefs.h> | | 64 | #include <sys/cdefs.h> |
65 | __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.209 2023/07/16 19:55:43 riastradh Exp $"); | | 65 | __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.210 2024/04/22 23:07:47 andvar Exp $"); |
66 | | | 66 | |
67 | #include "opt_ddb.h" | | 67 | #include "opt_ddb.h" |
68 | #include "opt_mpbios.h" /* for MPDEBUG */ | | 68 | #include "opt_mpbios.h" /* for MPDEBUG */ |
69 | #include "opt_mtrr.h" | | 69 | #include "opt_mtrr.h" |
70 | #include "opt_multiprocessor.h" | | 70 | #include "opt_multiprocessor.h" |
71 | #include "opt_svs.h" | | 71 | #include "opt_svs.h" |
72 | | | 72 | |
73 | #include "lapic.h" | | 73 | #include "lapic.h" |
74 | #include "ioapic.h" | | 74 | #include "ioapic.h" |
75 | #include "acpica.h" | | 75 | #include "acpica.h" |
76 | #include "hpet.h" | | 76 | #include "hpet.h" |
77 | | | 77 | |
78 | #include <sys/param.h> | | 78 | #include <sys/param.h> |
| @@ -1124,52 +1124,51 @@ cpu_copy_trampoline(paddr_t pdir_pa) | | | @@ -1124,52 +1124,51 @@ cpu_copy_trampoline(paddr_t pdir_pa) |
1124 | /* Copy smp_data at the end */ | | 1124 | /* Copy smp_data at the end */ |
1125 | memcpy((void *)(mp_trampoline_vaddr + PAGE_SIZE - sizeof(smp_data)), | | 1125 | memcpy((void *)(mp_trampoline_vaddr + PAGE_SIZE - sizeof(smp_data)), |
1126 | &smp_data, sizeof(smp_data)); | | 1126 | &smp_data, sizeof(smp_data)); |
1127 | | | 1127 | |
1128 | pmap_kremove(mp_trampoline_vaddr, PAGE_SIZE); | | 1128 | pmap_kremove(mp_trampoline_vaddr, PAGE_SIZE); |
1129 | pmap_update(pmap_kernel()); | | 1129 | pmap_update(pmap_kernel()); |
1130 | uvm_km_free(kernel_map, mp_trampoline_vaddr, PAGE_SIZE, UVM_KMF_VAONLY); | | 1130 | uvm_km_free(kernel_map, mp_trampoline_vaddr, PAGE_SIZE, UVM_KMF_VAONLY); |
1131 | } | | 1131 | } |
1132 | #endif | | 1132 | #endif |
1133 | | | 1133 | |
1134 | int | | 1134 | int |
1135 | mp_cpu_start(struct cpu_info *ci, paddr_t target) | | 1135 | mp_cpu_start(struct cpu_info *ci, paddr_t target) |
1136 | { | | 1136 | { |
| | | 1137 | #if NLAPIC > 0 |
1137 | int error; | | 1138 | int error; |
1138 | | | 1139 | |
1139 | /* | | 1140 | /* |
1140 | * Bootstrap code must be addressable in real mode | | 1141 | * Bootstrap code must be addressable in real mode |
1141 | * and it must be page aligned. | | 1142 | * and it must be page aligned. |
1142 | */ | | 1143 | */ |
1143 | KASSERT(target < 0x10000 && target % PAGE_SIZE == 0); | | 1144 | KASSERT(target < 0x10000 && target % PAGE_SIZE == 0); |
1144 | | | 1145 | |
1145 | /* | | 1146 | /* |
1146 | * "The BSP must initialize CMOS shutdown code to 0Ah ..." | | 1147 | * "The BSP must initialize CMOS shutdown code to 0Ah ..." |
1147 | */ | | 1148 | */ |
1148 | | | 1149 | |
1149 | outb(IO_RTC, NVRAM_RESET); | | 1150 | outb(IO_RTC, NVRAM_RESET); |
1150 | outb(IO_RTC+1, NVRAM_RESET_JUMP); | | 1151 | outb(IO_RTC+1, NVRAM_RESET_JUMP); |
1151 | | | 1152 | |
1152 | #if NLAPIC > 0 | | | |
1153 | /* | | 1153 | /* |
1154 | * "and the warm reset vector (DWORD based at 40:67) to point | | 1154 | * "and the warm reset vector (DWORD based at 40:67) to point |
1155 | * to the AP startup code ..." | | 1155 | * to the AP startup code ..." |
1156 | */ | | 1156 | */ |
1157 | unsigned short dwordptr[2]; | | 1157 | unsigned short dwordptr[2]; |
1158 | dwordptr[0] = 0; | | 1158 | dwordptr[0] = 0; |
1159 | dwordptr[1] = target >> 4; | | 1159 | dwordptr[1] = target >> 4; |
1160 | | | 1160 | |
1161 | memcpy((uint8_t *)cmos_data_mapping + 0x467, dwordptr, 4); | | 1161 | memcpy((uint8_t *)cmos_data_mapping + 0x467, dwordptr, 4); |
1162 | #endif | | | |
1163 | | | 1162 | |
1164 | if ((cpu_feature[0] & CPUID_APIC) == 0) { | | 1163 | if ((cpu_feature[0] & CPUID_APIC) == 0) { |
1165 | aprint_error("mp_cpu_start: CPU does not have APIC\n"); | | 1164 | aprint_error("mp_cpu_start: CPU does not have APIC\n"); |
1166 | return ENODEV; | | 1165 | return ENODEV; |
1167 | } | | 1166 | } |
1168 | | | 1167 | |
1169 | /* | | 1168 | /* |
1170 | * ... prior to executing the following sequence:". We'll also add in | | 1169 | * ... prior to executing the following sequence:". We'll also add in |
1171 | * local cache flush, in case the BIOS has left the AP with its cache | | 1170 | * local cache flush, in case the BIOS has left the AP with its cache |
1172 | * disabled. It may not be able to cope with MP coherency. | | 1171 | * disabled. It may not be able to cope with MP coherency. |
1173 | */ | | 1172 | */ |
1174 | wbinvd(); | | 1173 | wbinvd(); |
1175 | | | 1174 | |
| @@ -1190,26 +1189,29 @@ mp_cpu_start(struct cpu_info *ci, paddr_ | | | @@ -1190,26 +1189,29 @@ mp_cpu_start(struct cpu_info *ci, paddr_ |
1190 | } | | 1189 | } |
1191 | delay_func(200); | | 1190 | delay_func(200); |
1192 | | | 1191 | |
1193 | error = x86_ipi_startup(ci->ci_cpuid, target / PAGE_SIZE); | | 1192 | error = x86_ipi_startup(ci->ci_cpuid, target / PAGE_SIZE); |
1194 | if (error != 0) { | | 1193 | if (error != 0) { |
1195 | aprint_error_dev(ci->ci_dev, "%s: IPI not taken (3)\n", | | 1194 | aprint_error_dev(ci->ci_dev, "%s: IPI not taken (3)\n", |
1196 | __func__); | | 1195 | __func__); |
1197 | return error; | | 1196 | return error; |
1198 | } | | 1197 | } |
1199 | delay_func(200); | | 1198 | delay_func(200); |
1200 | } | | 1199 | } |
1201 | | | 1200 | |
1202 | return 0; | | 1201 | return 0; |
| | | 1202 | #else |
| | | 1203 | return ENODEV; |
| | | 1204 | #endif /* NLAPIC > 0 */ |
1203 | } | | 1205 | } |
1204 | | | 1206 | |
1205 | void | | 1207 | void |
1206 | mp_cpu_start_cleanup(struct cpu_info *ci) | | 1208 | mp_cpu_start_cleanup(struct cpu_info *ci) |
1207 | { | | 1209 | { |
1208 | /* | | 1210 | /* |
1209 | * Ensure the NVRAM reset byte contains something vaguely sane. | | 1211 | * Ensure the NVRAM reset byte contains something vaguely sane. |
1210 | */ | | 1212 | */ |
1211 | | | 1213 | |
1212 | outb(IO_RTC, NVRAM_RESET); | | 1214 | outb(IO_RTC, NVRAM_RESET); |
1213 | outb(IO_RTC+1, NVRAM_RESET_RST); | | 1215 | outb(IO_RTC+1, NVRAM_RESET_RST); |
1214 | } | | 1216 | } |
1215 | #endif | | 1217 | #endif |