diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-11 19:29:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-11 19:29:47 -0500 |
commit | 401221501af4b87b502eca36ece97b4191380082 (patch) | |
tree | d67687b4ceb8c78213296039cafe8602514e4cd3 /arch | |
parent | 63f45b80947cb0819673860f6970f483e2cab21d (diff) | |
parent | ff51224cab12845c8bd539ca1f2dc18cc851b445 (diff) |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ia64/Kconfig | 13 | ||||
-rw-r--r-- | arch/ia64/configs/sn2_defconfig | 2 | ||||
-rw-r--r-- | arch/ia64/defconfig | 2 | ||||
-rw-r--r-- | arch/ia64/kernel/ivt.S | 63 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/setup.c | 157 |
5 files changed, 218 insertions, 19 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index d4de8a4814be..8796e12c56f3 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -164,6 +164,19 @@ config IA64_PAGE_SIZE_64KB | |||
164 | 164 | ||
165 | endchoice | 165 | endchoice |
166 | 166 | ||
167 | choice | ||
168 | prompt "Page Table Levels" | ||
169 | default PGTABLE_3 | ||
170 | |||
171 | config PGTABLE_3 | ||
172 | bool "3 Levels" | ||
173 | |||
174 | config PGTABLE_4 | ||
175 | depends on !IA64_PAGE_SIZE_64KB | ||
176 | bool "4 Levels" | ||
177 | |||
178 | endchoice | ||
179 | |||
167 | source kernel/Kconfig.hz | 180 | source kernel/Kconfig.hz |
168 | 181 | ||
169 | config IA64_BRL_EMU | 182 | config IA64_BRL_EMU |
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index 08112ab38468..87cfd31a4a39 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig | |||
@@ -80,6 +80,8 @@ CONFIG_MCKINLEY=y | |||
80 | # CONFIG_IA64_PAGE_SIZE_8KB is not set | 80 | # CONFIG_IA64_PAGE_SIZE_8KB is not set |
81 | CONFIG_IA64_PAGE_SIZE_16KB=y | 81 | CONFIG_IA64_PAGE_SIZE_16KB=y |
82 | # CONFIG_IA64_PAGE_SIZE_64KB is not set | 82 | # CONFIG_IA64_PAGE_SIZE_64KB is not set |
83 | # CONFIG_PGTABLE_3 is not set | ||
84 | CONFIG_PGTABLE_4=y | ||
83 | # CONFIG_HZ_100 is not set | 85 | # CONFIG_HZ_100 is not set |
84 | CONFIG_HZ_250=y | 86 | CONFIG_HZ_250=y |
85 | # CONFIG_HZ_1000 is not set | 87 | # CONFIG_HZ_1000 is not set |
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig index 6e3f147e03e5..275a26c6e5aa 100644 --- a/arch/ia64/defconfig +++ b/arch/ia64/defconfig | |||
@@ -82,6 +82,8 @@ CONFIG_MCKINLEY=y | |||
82 | # CONFIG_IA64_PAGE_SIZE_8KB is not set | 82 | # CONFIG_IA64_PAGE_SIZE_8KB is not set |
83 | CONFIG_IA64_PAGE_SIZE_16KB=y | 83 | CONFIG_IA64_PAGE_SIZE_16KB=y |
84 | # CONFIG_IA64_PAGE_SIZE_64KB is not set | 84 | # CONFIG_IA64_PAGE_SIZE_64KB is not set |
85 | CONFIG_PGTABLE_3=y | ||
86 | # CONFIG_PGTABLE_4 is not set | ||
85 | # CONFIG_HZ_100 is not set | 87 | # CONFIG_HZ_100 is not set |
86 | CONFIG_HZ_250=y | 88 | CONFIG_HZ_250=y |
87 | # CONFIG_HZ_1000 is not set | 89 | # CONFIG_HZ_1000 is not set |
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index c13ca0d49c4a..e06f21f60dc5 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S | |||
@@ -114,7 +114,7 @@ ENTRY(vhpt_miss) | |||
114 | shl r21=r16,3 // shift bit 60 into sign bit | 114 | shl r21=r16,3 // shift bit 60 into sign bit |
115 | shr.u r17=r16,61 // get the region number into r17 | 115 | shr.u r17=r16,61 // get the region number into r17 |
116 | ;; | 116 | ;; |
117 | shr r22=r21,3 | 117 | shr.u r22=r21,3 |
118 | #ifdef CONFIG_HUGETLB_PAGE | 118 | #ifdef CONFIG_HUGETLB_PAGE |
119 | extr.u r26=r25,2,6 | 119 | extr.u r26=r25,2,6 |
120 | ;; | 120 | ;; |
@@ -140,20 +140,34 @@ ENTRY(vhpt_miss) | |||
140 | (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 | 140 | (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 |
141 | (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) | 141 | (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) |
142 | cmp.eq p7,p6=0,r21 // unused address bits all zeroes? | 142 | cmp.eq p7,p6=0,r21 // unused address bits all zeroes? |
143 | shr.u r18=r22,PMD_SHIFT // shift L2 index into position | 143 | #ifdef CONFIG_PGTABLE_4 |
144 | shr.u r28=r22,PUD_SHIFT // shift L2 index into position | ||
145 | #else | ||
146 | shr.u r18=r22,PMD_SHIFT // shift L3 index into position | ||
147 | #endif | ||
144 | ;; | 148 | ;; |
145 | ld8 r17=[r17] // fetch the L1 entry (may be 0) | 149 | ld8 r17=[r17] // fetch the L1 entry (may be 0) |
146 | ;; | 150 | ;; |
147 | (p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? | 151 | (p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? |
148 | dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry | 152 | #ifdef CONFIG_PGTABLE_4 |
153 | dep r28=r28,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry | ||
154 | ;; | ||
155 | shr.u r18=r22,PMD_SHIFT // shift L3 index into position | ||
156 | (p7) ld8 r29=[r28] // fetch the L2 entry (may be 0) | ||
149 | ;; | 157 | ;; |
150 | (p7) ld8 r20=[r17] // fetch the L2 entry (may be 0) | 158 | (p7) cmp.eq.or.andcm p6,p7=r29,r0 // was L2 entry NULL? |
151 | shr.u r19=r22,PAGE_SHIFT // shift L3 index into position | 159 | dep r17=r18,r29,3,(PAGE_SHIFT-3) // compute address of L3 page table entry |
160 | #else | ||
161 | dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L3 page table entry | ||
162 | #endif | ||
152 | ;; | 163 | ;; |
153 | (p7) cmp.eq.or.andcm p6,p7=r20,r0 // was L2 entry NULL? | 164 | (p7) ld8 r20=[r17] // fetch the L3 entry (may be 0) |
154 | dep r21=r19,r20,3,(PAGE_SHIFT-3) // compute address of L3 page table entry | 165 | shr.u r19=r22,PAGE_SHIFT // shift L4 index into position |
155 | ;; | 166 | ;; |
156 | (p7) ld8 r18=[r21] // read the L3 PTE | 167 | (p7) cmp.eq.or.andcm p6,p7=r20,r0 // was L3 entry NULL? |
168 | dep r21=r19,r20,3,(PAGE_SHIFT-3) // compute address of L4 page table entry | ||
169 | ;; | ||
170 | (p7) ld8 r18=[r21] // read the L4 PTE | ||
157 | mov r19=cr.isr // cr.isr bit 0 tells us if this is an insn miss | 171 | mov r19=cr.isr // cr.isr bit 0 tells us if this is an insn miss |
158 | ;; | 172 | ;; |
159 | (p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared? | 173 | (p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared? |
@@ -192,14 +206,21 @@ ENTRY(vhpt_miss) | |||
192 | * between reading the pagetable and the "itc". If so, flush the entry we | 206 | * between reading the pagetable and the "itc". If so, flush the entry we |
193 | * inserted and retry. | 207 | * inserted and retry. |
194 | */ | 208 | */ |
195 | ld8 r25=[r21] // read L3 PTE again | 209 | ld8 r25=[r21] // read L4 entry again |
196 | ld8 r26=[r17] // read L2 entry again | 210 | ld8 r26=[r17] // read L3 PTE again |
211 | #ifdef CONFIG_PGTABLE_4 | ||
212 | ld8 r18=[r28] // read L2 entry again | ||
213 | #endif | ||
214 | cmp.ne p6,p7=r0,r0 | ||
197 | ;; | 215 | ;; |
198 | cmp.ne p6,p7=r26,r20 // did L2 entry change | 216 | cmp.ne.or.andcm p6,p7=r26,r20 // did L3 entry change |
217 | #ifdef CONFIG_PGTABLE_4 | ||
218 | cmp.ne.or.andcm p6,p7=r29,r18 // did L4 PTE change | ||
219 | #endif | ||
199 | mov r27=PAGE_SHIFT<<2 | 220 | mov r27=PAGE_SHIFT<<2 |
200 | ;; | 221 | ;; |
201 | (p6) ptc.l r22,r27 // purge PTE page translation | 222 | (p6) ptc.l r22,r27 // purge PTE page translation |
202 | (p7) cmp.ne.or.andcm p6,p7=r25,r18 // did L3 PTE change | 223 | (p7) cmp.ne.or.andcm p6,p7=r25,r18 // did L4 PTE change |
203 | ;; | 224 | ;; |
204 | (p6) ptc.l r16,r27 // purge translation | 225 | (p6) ptc.l r16,r27 // purge translation |
205 | #endif | 226 | #endif |
@@ -432,18 +453,30 @@ ENTRY(nested_dtlb_miss) | |||
432 | (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 | 453 | (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 |
433 | (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) | 454 | (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) |
434 | cmp.eq p7,p6=0,r21 // unused address bits all zeroes? | 455 | cmp.eq p7,p6=0,r21 // unused address bits all zeroes? |
435 | shr.u r18=r22,PMD_SHIFT // shift L2 index into position | 456 | #ifdef CONFIG_PGTABLE_4 |
457 | shr.u r18=r22,PUD_SHIFT // shift L2 index into position | ||
458 | #else | ||
459 | shr.u r18=r22,PMD_SHIFT // shift L3 index into position | ||
460 | #endif | ||
436 | ;; | 461 | ;; |
437 | ld8 r17=[r17] // fetch the L1 entry (may be 0) | 462 | ld8 r17=[r17] // fetch the L1 entry (may be 0) |
438 | ;; | 463 | ;; |
439 | (p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? | 464 | (p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? |
440 | dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry | 465 | dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry |
441 | ;; | 466 | ;; |
467 | #ifdef CONFIG_PGTABLE_4 | ||
442 | (p7) ld8 r17=[r17] // fetch the L2 entry (may be 0) | 468 | (p7) ld8 r17=[r17] // fetch the L2 entry (may be 0) |
443 | shr.u r19=r22,PAGE_SHIFT // shift L3 index into position | 469 | shr.u r18=r22,PMD_SHIFT // shift L3 index into position |
444 | ;; | 470 | ;; |
445 | (p7) cmp.eq.or.andcm p6,p7=r17,r0 // was L2 entry NULL? | 471 | (p7) cmp.eq.or.andcm p6,p7=r17,r0 // was L2 entry NULL? |
446 | dep r17=r19,r17,3,(PAGE_SHIFT-3) // compute address of L3 page table entry | 472 | dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry |
473 | ;; | ||
474 | #endif | ||
475 | (p7) ld8 r17=[r17] // fetch the L3 entry (may be 0) | ||
476 | shr.u r19=r22,PAGE_SHIFT // shift L4 index into position | ||
477 | ;; | ||
478 | (p7) cmp.eq.or.andcm p6,p7=r17,r0 // was L3 entry NULL? | ||
479 | dep r17=r19,r17,3,(PAGE_SHIFT-3) // compute address of L4 page table entry | ||
447 | (p6) br.cond.spnt page_fault | 480 | (p6) br.cond.spnt page_fault |
448 | mov b0=r30 | 481 | mov b0=r30 |
449 | br.sptk.many b0 // return to continuation point | 482 | br.sptk.many b0 // return to continuation point |
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 0fb579ef18c2..e510dce9971f 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/root_dev.h> | 30 | #include <linux/root_dev.h> |
31 | #include <linux/nodemask.h> | 31 | #include <linux/nodemask.h> |
32 | #include <linux/pm.h> | 32 | #include <linux/pm.h> |
33 | #include <linux/efi.h> | ||
33 | 34 | ||
34 | #include <asm/io.h> | 35 | #include <asm/io.h> |
35 | #include <asm/sal.h> | 36 | #include <asm/sal.h> |
@@ -242,6 +243,135 @@ static void __init sn_check_for_wars(void) | |||
242 | } | 243 | } |
243 | } | 244 | } |
244 | 245 | ||
246 | /* | ||
247 | * Scan the EFI PCDP table (if it exists) for an acceptable VGA console | ||
248 | * output device. If one exists, pick it and set sn_legacy_{io,mem} to | ||
249 | * reflect the bus offsets needed to address it. | ||
250 | * | ||
251 | * Since pcdp support in SN is not supported in the 2.4 kernel (or at least | ||
252 | * the one lbs is based on) just declare the needed structs here. | ||
253 | * | ||
254 | * Reference spec http://www.dig64.org/specifications/DIG64_PCDPv20.pdf | ||
255 | * | ||
256 | * Returns 0 if no acceptable vga is found, !0 otherwise. | ||
257 | * | ||
258 | * Note: This stuff is duped here because Altix requires the PCDP to | ||
259 | * locate a usable VGA device due to lack of proper ACPI support. Structures | ||
260 | * could be used from drivers/firmware/pcdp.h, but it was decided that moving | ||
261 | * this file to a more public location just for Altix use was undesireable. | ||
262 | */ | ||
263 | |||
264 | struct hcdp_uart_desc { | ||
265 | u8 pad[45]; | ||
266 | }; | ||
267 | |||
268 | struct pcdp { | ||
269 | u8 signature[4]; /* should be 'HCDP' */ | ||
270 | u32 length; | ||
271 | u8 rev; /* should be >=3 for pcdp, <3 for hcdp */ | ||
272 | u8 sum; | ||
273 | u8 oem_id[6]; | ||
274 | u64 oem_tableid; | ||
275 | u32 oem_rev; | ||
276 | u32 creator_id; | ||
277 | u32 creator_rev; | ||
278 | u32 num_type0; | ||
279 | struct hcdp_uart_desc uart[0]; /* num_type0 of these */ | ||
280 | /* pcdp descriptors follow */ | ||
281 | } __attribute__((packed)); | ||
282 | |||
283 | struct pcdp_device_desc { | ||
284 | u8 type; | ||
285 | u8 primary; | ||
286 | u16 length; | ||
287 | u16 index; | ||
288 | /* interconnect specific structure follows */ | ||
289 | /* device specific structure follows that */ | ||
290 | } __attribute__((packed)); | ||
291 | |||
292 | struct pcdp_interface_pci { | ||
293 | u8 type; /* 1 == pci */ | ||
294 | u8 reserved; | ||
295 | u16 length; | ||
296 | u8 segment; | ||
297 | u8 bus; | ||
298 | u8 dev; | ||
299 | u8 fun; | ||
300 | u16 devid; | ||
301 | u16 vendid; | ||
302 | u32 acpi_interrupt; | ||
303 | u64 mmio_tra; | ||
304 | u64 ioport_tra; | ||
305 | u8 flags; | ||
306 | u8 translation; | ||
307 | } __attribute__((packed)); | ||
308 | |||
309 | struct pcdp_vga_device { | ||
310 | u8 num_eas_desc; | ||
311 | /* ACPI Extended Address Space Desc follows */ | ||
312 | } __attribute__((packed)); | ||
313 | |||
314 | /* from pcdp_device_desc.primary */ | ||
315 | #define PCDP_PRIMARY_CONSOLE 0x01 | ||
316 | |||
317 | /* from pcdp_device_desc.type */ | ||
318 | #define PCDP_CONSOLE_INOUT 0x0 | ||
319 | #define PCDP_CONSOLE_DEBUG 0x1 | ||
320 | #define PCDP_CONSOLE_OUT 0x2 | ||
321 | #define PCDP_CONSOLE_IN 0x3 | ||
322 | #define PCDP_CONSOLE_TYPE_VGA 0x8 | ||
323 | |||
324 | #define PCDP_CONSOLE_VGA (PCDP_CONSOLE_TYPE_VGA | PCDP_CONSOLE_OUT) | ||
325 | |||
326 | /* from pcdp_interface_pci.type */ | ||
327 | #define PCDP_IF_PCI 1 | ||
328 | |||
329 | /* from pcdp_interface_pci.translation */ | ||
330 | #define PCDP_PCI_TRANS_IOPORT 0x02 | ||
331 | #define PCDP_PCI_TRANS_MMIO 0x01 | ||
332 | |||
333 | static void | ||
334 | sn_scan_pcdp(void) | ||
335 | { | ||
336 | u8 *bp; | ||
337 | struct pcdp *pcdp; | ||
338 | struct pcdp_device_desc device; | ||
339 | struct pcdp_interface_pci if_pci; | ||
340 | extern struct efi efi; | ||
341 | |||
342 | pcdp = efi.hcdp; | ||
343 | if (! pcdp) | ||
344 | return; /* no hcdp/pcdp table */ | ||
345 | |||
346 | if (pcdp->rev < 3) | ||
347 | return; /* only support PCDP (rev >= 3) */ | ||
348 | |||
349 | for (bp = (u8 *)&pcdp->uart[pcdp->num_type0]; | ||
350 | bp < (u8 *)pcdp + pcdp->length; | ||
351 | bp += device.length) { | ||
352 | memcpy(&device, bp, sizeof(device)); | ||
353 | if (! (device.primary & PCDP_PRIMARY_CONSOLE)) | ||
354 | continue; /* not primary console */ | ||
355 | |||
356 | if (device.type != PCDP_CONSOLE_VGA) | ||
357 | continue; /* not VGA descriptor */ | ||
358 | |||
359 | memcpy(&if_pci, bp+sizeof(device), sizeof(if_pci)); | ||
360 | if (if_pci.type != PCDP_IF_PCI) | ||
361 | continue; /* not PCI interconnect */ | ||
362 | |||
363 | if (if_pci.translation & PCDP_PCI_TRANS_IOPORT) | ||
364 | vga_console_iobase = | ||
365 | if_pci.ioport_tra | __IA64_UNCACHED_OFFSET; | ||
366 | |||
367 | if (if_pci.translation & PCDP_PCI_TRANS_MMIO) | ||
368 | vga_console_membase = | ||
369 | if_pci.mmio_tra | __IA64_UNCACHED_OFFSET; | ||
370 | |||
371 | break; /* once we find the primary, we're done */ | ||
372 | } | ||
373 | } | ||
374 | |||
245 | /** | 375 | /** |
246 | * sn_setup - SN platform setup routine | 376 | * sn_setup - SN platform setup routine |
247 | * @cmdline_p: kernel command line | 377 | * @cmdline_p: kernel command line |
@@ -263,16 +393,35 @@ void __init sn_setup(char **cmdline_p) | |||
263 | 393 | ||
264 | #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) | 394 | #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) |
265 | /* | 395 | /* |
266 | * If there was a primary vga adapter identified through the | 396 | * Handle SN vga console. |
267 | * EFI PCDP table, make it the preferred console. Otherwise | 397 | * |
268 | * zero out conswitchp. | 398 | * SN systems do not have enough ACPI table information |
399 | * being passed from prom to identify VGA adapters and the legacy | ||
400 | * addresses to access them. Until that is done, SN systems rely | ||
401 | * on the PCDP table to identify the primary VGA console if one | ||
402 | * exists. | ||
403 | * | ||
404 | * However, kernel PCDP support is optional, and even if it is built | ||
405 | * into the kernel, it will not be used if the boot cmdline contains | ||
406 | * console= directives. | ||
407 | * | ||
408 | * So, to work around this mess, we duplicate some of the PCDP code | ||
409 | * here so that the primary VGA console (as defined by PCDP) will | ||
410 | * work on SN systems even if a different console (e.g. serial) is | ||
411 | * selected on the boot line (or CONFIG_EFI_PCDP is off). | ||
269 | */ | 412 | */ |
270 | 413 | ||
414 | if (! vga_console_membase) | ||
415 | sn_scan_pcdp(); | ||
416 | |||
271 | if (vga_console_membase) { | 417 | if (vga_console_membase) { |
272 | /* usable vga ... make tty0 the preferred default console */ | 418 | /* usable vga ... make tty0 the preferred default console */ |
273 | add_preferred_console("tty", 0, NULL); | 419 | if (!strstr(*cmdline_p, "console=")) |
420 | add_preferred_console("tty", 0, NULL); | ||
274 | } else { | 421 | } else { |
275 | printk(KERN_DEBUG "SGI: Disabling VGA console\n"); | 422 | printk(KERN_DEBUG "SGI: Disabling VGA console\n"); |
423 | if (!strstr(*cmdline_p, "console=")) | ||
424 | add_preferred_console("ttySG", 0, NULL); | ||
276 | #ifdef CONFIG_DUMMY_CONSOLE | 425 | #ifdef CONFIG_DUMMY_CONSOLE |
277 | conswitchp = &dummy_con; | 426 | conswitchp = &dummy_con; |
278 | #else | 427 | #else |