Index: arch/parisc/kernel/entry.S =================================================================== RCS file: /home/cvs/parisc/linux-2.3/arch/parisc/kernel/entry.S,v retrieving revision 1.32 diff -u -p -r1.32 entry.S --- entry.S 2000/08/30 22:28:35 1.32 +++ entry.S 2000/09/02 04:20:06 @@ -655,12 +655,18 @@ dtlb_miss: depi 1,12,1,prot extru,= pte,_PAGE_USER_BIT,1,r0 depi 7,11,3,prot /* Set for user space (1 rsvd for read) */ + extru,= pte,_PAGE_GATEWAY_BIT,1,r0 + depi 0,11,2,prot /* If Gateway, Set PL2 to 0 */ /* Get rid of prot bits and convert to page addr for idtlba */ depi 0,31,12,pte extru pte,24,25,pte + + /* The following may get patched with idtlb_insert_pa20 */ + .export idtlb_insert0,code +idtlb_insert0: mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ mtsp spc,%sr1 @@ -671,6 +677,8 @@ dtlb_miss: rfir nop + .export idtlb_insert0_end,code +idtlb_insert0_end: itlb_miss: @@ -712,6 +720,8 @@ itlb_miss_common: copy spc,prot /* init prot with faulting space */ dep pte,8,7,prot + extru,= pte,_PAGE_NO_CACHE_BIT,1,r0 + depi 1,12,1,prot extru,= pte,_PAGE_USER_BIT,1,r0 depi 7,11,3,prot /* Set for user space (1 rsvd for read) */ extru,= pte,_PAGE_GATEWAY_BIT,1,r0 @@ -722,6 +732,9 @@ itlb_miss_common: depi 0,31,12,pte extru pte,24,25,pte + /* The following may get patched with idtlb_insert_pa20 */ + .export iitlb_insert,code +iitlb_insert: mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ mtsp spc,%sr1 @@ -732,6 +745,8 @@ itlb_miss_common: rfir nop + .export iitlb_insert_end,code +iitlb_insert_end: itlb_miss_kernel: b itlb_miss_common @@ -773,12 +788,18 @@ dbit_trap: depi 1,12,1,prot extru,= pte,_PAGE_USER_BIT,1,r0 depi 7,11,3,prot /* Set for user space (1 rsvd for read) */ + extru,= pte,_PAGE_GATEWAY_BIT,1,r0 + depi 0,11,2,prot /* If Gateway, Set PL2 to 0 */ /* Get rid of prot bits and convert to page addr for idtlba */ depi 0,31,12,pte extru pte,24,25,pte + + /* The following may get patched with idtlb_insert_pa20 */ + .export idtlb_insert1,code +idtlb_insert1: mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ mtsp spc,%sr1 @@ -789,7 +810,37 @@ dbit_trap: rfir nop + .export idtlb_insert1_end,code +idtlb_insert1_end: + + .level 2.0 + .text + .export idtlb_insert_pa20,code +idtlb_insert_pa20: + depd %r17,31,32,%r17 + depdi 0,46,15,%r17 + idtlbt %r16,%r17 + rfir + nop + nop + nop + .export idtlb_insert_pa20_end,code +idtlb_insert_pa20_end: + + .export iitlb_insert_pa20,code +iitlb_insert_pa20: + depd %r17,31,32,%r17 + depdi 0,46,15,%r17 + iitlbt %r16,%r17 + rfir + nop + nop + nop + .export iitlb_insert_pa20_end,code +iitlb_insert_pa20_end: + .level 1.1 + .text .import handle_interruption,code kernel_bad_space: Index: arch/parisc/kernel/traps.c =================================================================== RCS file: /home/cvs/parisc/linux-2.3/arch/parisc/kernel/traps.c,v retrieving revision 1.18 diff -u -p -r1.18 traps.c --- traps.c 2000/08/28 20:16:11 1.18 +++ traps.c 2000/09/02 04:20:06 @@ -29,6 +29,7 @@ #include #include +#include static inline void console_verbose(void) { @@ -350,8 +351,7 @@ extern void fault_vector(void); int __init check_ivt(char * iva) { - int i; - u32 check = 0, *p; + u32 *p; if(strcmp(iva, "cows can fly")) return -1; @@ -375,7 +375,55 @@ int __init check_ivt(char * iva) return 0; } + +extern void iitlb_insert(), idtlb_insert0(), idtlb_insert1(); +extern void iitlb_insert_end(), idtlb_insert0_end(), idtlb_insert1_end(); +extern void iitlb_insert_pa20(), idtlb_insert_pa20(); +extern void iitlb_insert_pa20_end(), idtlb_insert_pa20_end(); + +static inline void +flush_kernel_icache_range(unsigned long start, unsigned long size) +{ + register unsigned long end = start + size; + register unsigned long i; + + for (i = start; i <= end; i += L1_CACHE_BYTES) { + asm volatile("fic 0(%%sr0, %0)" : : "r" (i)); + } +} + +void +trap_patch_tlb_inserts() +{ + int ilen = iitlb_insert_pa20_end-iitlb_insert_pa20; + int dlen = idtlb_insert_pa20_end-idtlb_insert_pa20; + if(ilen != (iitlb_insert_end-iitlb_insert)) { + panic("trap_patch_tlb_inserts: iitlb_insert_pa20 bad size"); + } + if(dlen != (idtlb_insert0_end-idtlb_insert0)) { + panic("trap_patch_tlb_inserts: idtlb_insert_pa20 bad size"); + } + if(dlen != (idtlb_insert0_end-idtlb_insert0)) { + panic("trap_patch_tlb_inserts: idtlb_insert_pa20 bad size"); + } + + memcpy (iitlb_insert, iitlb_insert_pa20, ilen); + memcpy (idtlb_insert0, idtlb_insert_pa20, dlen); + memcpy (idtlb_insert1, idtlb_insert_pa20, dlen); + + flush_kernel_dcache_range((unsigned long)iitlb_insert, ilen); + flush_kernel_dcache_range((unsigned long)idtlb_insert0, dlen); + flush_kernel_dcache_range((unsigned long)idtlb_insert1, dlen); + + flush_kernel_icache_range((unsigned long)iitlb_insert, ilen); + flush_kernel_icache_range((unsigned long)idtlb_insert0, dlen); + flush_kernel_icache_range((unsigned long)idtlb_insert1, dlen); + + asm volatile("sync"); + +} + void __init trap_init(void) { volatile long eiem; @@ -385,6 +433,9 @@ void __init trap_init(void) if(check_ivt((void *)fault_vector)) panic("IVT invalid"); + if(boot_cpu_data.cpu_type >= pcxu) { + trap_patch_tlb_inserts(); + } mtctl(__pa(&fault_vector), 14); mtctl(0, 30);