diff options
author | Grant Grundler <grundler@parisc-linux.org> | 2005-10-21 22:40:07 -0400 |
---|---|---|
committer | Kyle McMartin <kyle@parisc-linux.org> | 2005-10-21 22:40:07 -0400 |
commit | 896a375623c3643a3f189353e7d4828c48a7fdf8 (patch) | |
tree | bb79535f843110f9b2b199890157fcabb0504b43 /include | |
parent | b2c1fe81df7471de9f7e2918877ac04ec9cde35f (diff) |
[PARISC] Make sure use of RFI conforms to PA 2.0 and 1.1 arch docs
2.6.12-rc4-pa3 : first pass at making sure use of RFI conforms to
PA 2.0 arch pages F-4 and F-5, PA 1.1 Arch page 3-19 and 3-20.
The discussion revolves around all the rules for clearing PSW Q-bit.
The hard part is meeting all the rules for "relied upon translation".
.align directive is used to guarantee the critical sequence ends more than
8 instructions (32 bytes) from the end of page.
Signed-off-by: Grant Grundler <grundler@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-parisc/assembly.h | 25 | ||||
-rw-r--r-- | include/asm-parisc/psw.h | 51 | ||||
-rw-r--r-- | include/asm-parisc/tlbflush.h | 9 |
3 files changed, 54 insertions, 31 deletions
diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h index 30b023411fef..b24a99e3ef9c 100644 --- a/include/asm-parisc/assembly.h +++ b/include/asm-parisc/assembly.h | |||
@@ -450,5 +450,30 @@ | |||
450 | REST_CR (%cr22, PT_PSW (\regs)) | 450 | REST_CR (%cr22, PT_PSW (\regs)) |
451 | .endm | 451 | .endm |
452 | 452 | ||
453 | |||
454 | /* First step to create a "relied upon translation" | ||
455 | * See PA 2.0 Arch. page F-4 and F-5. | ||
456 | * | ||
457 | * The ssm was originally necessary due to a "PCxT bug". | ||
458 | * But someone decided it needed to be added to the architecture | ||
459 | * and this "feature" went into rev3 of PA-RISC 1.1 Arch Manual. | ||
460 | * It's been carried forward into PA 2.0 Arch as well. :^( | ||
461 | * | ||
462 | * "ssm 0,%r0" is a NOP with side effects (prefetch barrier). | ||
463 | * rsm/ssm prevents the ifetch unit from speculatively fetching | ||
464 | * instructions past this line in the code stream. | ||
465 | * PA 2.0 processor will single step all insn in the same QUAD (4 insn). | ||
466 | */ | ||
467 | .macro pcxt_ssm_bug | ||
468 | rsm PSW_SM_I,%r0 | ||
469 | nop /* 1 */ | ||
470 | nop /* 2 */ | ||
471 | nop /* 3 */ | ||
472 | nop /* 4 */ | ||
473 | nop /* 5 */ | ||
474 | nop /* 6 */ | ||
475 | nop /* 7 */ | ||
476 | .endm | ||
477 | |||
453 | #endif /* __ASSEMBLY__ */ | 478 | #endif /* __ASSEMBLY__ */ |
454 | #endif | 479 | #endif |
diff --git a/include/asm-parisc/psw.h b/include/asm-parisc/psw.h index 51323029f377..4334d6ca2add 100644 --- a/include/asm-parisc/psw.h +++ b/include/asm-parisc/psw.h | |||
@@ -1,4 +1,7 @@ | |||
1 | #ifndef _PARISC_PSW_H | 1 | #ifndef _PARISC_PSW_H |
2 | |||
3 | #include <linux/config.h> | ||
4 | |||
2 | #define PSW_I 0x00000001 | 5 | #define PSW_I 0x00000001 |
3 | #define PSW_D 0x00000002 | 6 | #define PSW_D 0x00000002 |
4 | #define PSW_P 0x00000004 | 7 | #define PSW_P 0x00000004 |
@@ -9,6 +12,16 @@ | |||
9 | #define PSW_G 0x00000040 /* PA1.x only */ | 12 | #define PSW_G 0x00000040 /* PA1.x only */ |
10 | #define PSW_O 0x00000080 /* PA2.0 only */ | 13 | #define PSW_O 0x00000080 /* PA2.0 only */ |
11 | 14 | ||
15 | /* ssm/rsm instructions number PSW_W and PSW_E differently */ | ||
16 | #define PSW_SM_I PSW_I /* Enable External Interrupts */ | ||
17 | #define PSW_SM_D PSW_D | ||
18 | #define PSW_SM_P PSW_P | ||
19 | #define PSW_SM_Q PSW_Q /* Enable Interrupt State Collection */ | ||
20 | #define PSW_SM_R PSW_R /* Enable Recover Counter Trap */ | ||
21 | #define PSW_SM_W 0x200 /* PA2.0 only : Enable Wide Mode */ | ||
22 | |||
23 | #define PSW_SM_QUIET PSW_SM_R+PSW_SM_Q+PSW_SM_P+PSW_SM_D+PSW_SM_I | ||
24 | |||
12 | #define PSW_CB 0x0000ff00 | 25 | #define PSW_CB 0x0000ff00 |
13 | 26 | ||
14 | #define PSW_M 0x00010000 | 27 | #define PSW_M 0x00010000 |
@@ -30,33 +43,21 @@ | |||
30 | #define PSW_Z 0x40000000 /* PA1.x only */ | 43 | #define PSW_Z 0x40000000 /* PA1.x only */ |
31 | #define PSW_Y 0x80000000 /* PA1.x only */ | 44 | #define PSW_Y 0x80000000 /* PA1.x only */ |
32 | 45 | ||
33 | #ifdef __LP64__ | 46 | #ifdef CONFIG_64BIT |
34 | #define PSW_HI_CB 0x000000ff /* PA2.0 only */ | 47 | # define PSW_HI_CB 0x000000ff /* PA2.0 only */ |
35 | #endif | 48 | #endif |
36 | 49 | ||
37 | /* PSW bits to be used with ssm/rsm */ | 50 | #ifdef CONFIG_64BIT |
38 | #define PSW_SM_I 0x1 | 51 | # define USER_PSW_HI_MASK PSW_HI_CB |
39 | #define PSW_SM_D 0x2 | 52 | # define WIDE_PSW PSW_W |
40 | #define PSW_SM_P 0x4 | 53 | #else |
41 | #define PSW_SM_Q 0x8 | 54 | # define WIDE_PSW 0 |
42 | #define PSW_SM_R 0x10 | ||
43 | #define PSW_SM_F 0x20 | ||
44 | #define PSW_SM_G 0x40 | ||
45 | #define PSW_SM_O 0x80 | ||
46 | #define PSW_SM_E 0x100 | ||
47 | #define PSW_SM_W 0x200 | ||
48 | |||
49 | #ifdef __LP64__ | ||
50 | # define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I) | ||
51 | # define KERNEL_PSW (PSW_W | PSW_C | PSW_Q | PSW_P | PSW_D) | ||
52 | # define REAL_MODE_PSW (PSW_W | PSW_Q) | ||
53 | # define USER_PSW_MASK (PSW_W | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB) | ||
54 | # define USER_PSW_HI_MASK (PSW_HI_CB) | ||
55 | #else | ||
56 | # define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I) | ||
57 | # define KERNEL_PSW (PSW_C | PSW_Q | PSW_P | PSW_D) | ||
58 | # define REAL_MODE_PSW (PSW_Q) | ||
59 | # define USER_PSW_MASK (PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB) | ||
60 | #endif | 55 | #endif |
61 | 56 | ||
57 | /* Used when setting up for rfi */ | ||
58 | #define KERNEL_PSW (WIDE_PSW | PSW_C | PSW_Q | PSW_P | PSW_D) | ||
59 | #define REAL_MODE_PSW (WIDE_PSW | PSW_Q) | ||
60 | #define USER_PSW_MASK (WIDE_PSW | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB) | ||
61 | #define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I) | ||
62 | |||
62 | #endif | 63 | #endif |
diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h index eb27b78930e8..efbb2d8625b1 100644 --- a/include/asm-parisc/tlbflush.h +++ b/include/asm-parisc/tlbflush.h | |||
@@ -64,29 +64,26 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, | |||
64 | { | 64 | { |
65 | unsigned long npages; | 65 | unsigned long npages; |
66 | 66 | ||
67 | |||
68 | npages = ((end - (start & PAGE_MASK)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | 67 | npages = ((end - (start & PAGE_MASK)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT; |
69 | if (npages >= 512) /* XXX arbitrary, should be tuned */ | 68 | if (npages >= 512) /* 2MB of space: arbitrary, should be tuned */ |
70 | flush_tlb_all(); | 69 | flush_tlb_all(); |
71 | else { | 70 | else { |
72 | 71 | ||
73 | mtsp(vma->vm_mm->context,1); | 72 | mtsp(vma->vm_mm->context,1); |
73 | purge_tlb_start(); | ||
74 | if (split_tlb) { | 74 | if (split_tlb) { |
75 | purge_tlb_start(); | ||
76 | while (npages--) { | 75 | while (npages--) { |
77 | pdtlb(start); | 76 | pdtlb(start); |
78 | pitlb(start); | 77 | pitlb(start); |
79 | start += PAGE_SIZE; | 78 | start += PAGE_SIZE; |
80 | } | 79 | } |
81 | purge_tlb_end(); | ||
82 | } else { | 80 | } else { |
83 | purge_tlb_start(); | ||
84 | while (npages--) { | 81 | while (npages--) { |
85 | pdtlb(start); | 82 | pdtlb(start); |
86 | start += PAGE_SIZE; | 83 | start += PAGE_SIZE; |
87 | } | 84 | } |
88 | purge_tlb_end(); | ||
89 | } | 85 | } |
86 | purge_tlb_end(); | ||
90 | } | 87 | } |
91 | } | 88 | } |
92 | 89 | ||