Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

parisc: fix partly 16/64k PAGE_SIZE boot

This patch fixes partly PAGE_SIZEs of 16K or 64K by adjusting the
assembler PTE lookup code and the assembler TEMPALIAS code. Furthermore
some data alignments for PAGE_SIZE have been limited to 4K (or less) to
not waste too much memory with greater page sizes. As a side note, the
palo loader can (currently) only handle up to 10 ELF segments which is
fixed with tighter aligning as well.

My testings indicated that the ldci command in the sba iommu coding
needed adjustment by the PAGE_SHIFT value and that the I/O PDIR Page
size was only set to 4K for my machine (C3000).

All this fixes partly the boot, but there are still quite some caching
problems left. Examples are e.g. the symbios logic driver which is
failing:

sym0: <896> rev 0x7 at pci 0000:00:0f.0 irq 69
sym0: PA-RISC Firmware, ID 7, Fast-40, SE, parity checking
CACHE TEST FAILED: DMA error (dstat=0x81).sym0: CACHE INCORRECTLY CONFIGURED.

and the tulip network driver which doesn't seem to work correctly
either:

Sending BOOTP requests .net eth0: Setting full-duplex based on MII#1
link partner capability of 05e1
..... timed out!

Beside those kernel fixes glibc will need fixes too to be able to handle
>4K page sizes.

Signed-off-by: Helge Deller <deller@gmx.de>

+52 -25
+9 -1
arch/parisc/kernel/entry.S
··· 400 400 #if PT_NLEVELS == 3 401 401 extru \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index 402 402 #else 403 + # if defined(CONFIG_64BIT) 404 + extrd,u \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index 405 + #else 406 + # if PAGE_SIZE > 4096 407 + extru \va,31-ASM_PGDIR_SHIFT,32-ASM_PGDIR_SHIFT,\index 408 + # else 403 409 extru \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index 410 + # endif 411 + # endif 404 412 #endif 405 413 dep %r0,31,PAGE_SHIFT,\pmd /* clear offset */ 406 414 copy %r0,\pte ··· 623 615 624 616 .text 625 617 626 - .align PAGE_SIZE 618 + .align 4096 627 619 628 620 ENTRY(fault_vector_20) 629 621 /* First vector is invalid (0) */
+2 -2
arch/parisc/kernel/hpmc.S
··· 55 55 * IODC requires 7K byte stack. That leaves 1K byte for os_hpmc. 56 56 */ 57 57 58 - .align PAGE_SIZE 58 + .align 4096 59 59 hpmc_stack: 60 60 .block 16384 61 61 62 62 #define HPMC_IODC_BUF_SIZE 0x8000 63 63 64 - .align PAGE_SIZE 64 + .align 4096 65 65 hpmc_iodc_buf: 66 66 .block HPMC_IODC_BUF_SIZE 67 67
+19 -14
arch/parisc/kernel/pacache.S
··· 563 563 * %r23 physical page (shifted for tlb insert) of "from" translation 564 564 */ 565 565 566 + /* Drop prot bits and convert to page addr for iitlbt and idtlbt */ 567 + #define PAGE_ADD_SHIFT (PAGE_SHIFT-12) 568 + .macro convert_phys_for_tlb_insert20 phys 569 + extrd,u \phys, 56-PAGE_ADD_SHIFT, 32-PAGE_ADD_SHIFT, \phys 570 + #if _PAGE_SIZE_ENCODING_DEFAULT 571 + depdi _PAGE_SIZE_ENCODING_DEFAULT, 63, (63-58), \phys 572 + #endif 573 + .endm 574 + 566 575 /* 567 576 * We can't do this since copy_user_page is used to bring in 568 577 * file data that might have instructions. Since the data would ··· 598 589 sub %r25, %r1, %r23 599 590 600 591 ldil L%(TMPALIAS_MAP_START), %r28 601 - /* FIXME for different page sizes != 4k */ 602 592 #ifdef CONFIG_64BIT 603 593 #if (TMPALIAS_MAP_START >= 0x80000000) 604 594 depdi 0, 31,32, %r28 /* clear any sign extension */ 605 595 #endif 606 - extrd,u %r26,56,32, %r26 /* convert phys addr to tlb insert format */ 607 - extrd,u %r23,56,32, %r23 /* convert phys addr to tlb insert format */ 596 + convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */ 597 + convert_phys_for_tlb_insert20 %r23 /* convert phys addr to tlb insert format */ 608 598 depd %r24,63,22, %r28 /* Form aliased virtual address 'to' */ 609 - depdi 0, 63,12, %r28 /* Clear any offset bits */ 599 + depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */ 610 600 copy %r28, %r29 611 601 depdi 1, 41,1, %r29 /* Form aliased virtual address 'from' */ 612 602 #else ··· 755 747 #ifdef CONFIG_64BIT 756 748 #if (TMPALIAS_MAP_START >= 0x80000000) 757 749 depdi 0, 31,32, %r28 /* clear any sign extension */ 758 - /* FIXME: page size dependend */ 759 750 #endif 760 - extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ 751 + convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */ 761 752 depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ 762 - depdi 0, 63,12, %r28 /* Clear any offset bits */ 753 + depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */ 763 754 #else 764 755 extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ 765 756 depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ ··· 839 832 #ifdef CONFIG_64BIT 840 833 #if (TMPALIAS_MAP_START >= 0x80000000) 841 834 depdi 0, 31,32, %r28 /* clear any sign extension */ 842 - /* FIXME: page size dependend */ 843 835 #endif 844 - extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ 836 + convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */ 845 837 depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ 846 - depdi 0, 63,12, %r28 /* Clear any offset bits */ 838 + depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */ 847 839 #else 848 840 extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ 849 841 depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ ··· 915 909 #ifdef CONFIG_64BIT 916 910 #if (TMPALIAS_MAP_START >= 0x80000000) 917 911 depdi 0, 31,32, %r28 /* clear any sign extension */ 918 - /* FIXME: page size dependend */ 919 912 #endif 920 - extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ 913 + convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */ 921 914 depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ 922 - depdi 0, 63,12, %r28 /* Clear any offset bits */ 915 + depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */ 923 916 #else 924 917 extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ 925 918 depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ ··· 964 959 fic,m %r1(%sr4,%r28) 965 960 fic,m %r1(%sr4,%r28) 966 961 fic,m %r1(%sr4,%r28) 967 - cmpb,COND(<<) %r28, %r25,1b 962 + cmpb,COND(<<) %r28, %r25,1b 968 963 fic,m %r1(%sr4,%r28) 969 964 970 965 sync
+2
arch/parisc/kernel/setup.c
··· 129 129 printk(KERN_INFO "The 32-bit Kernel has started...\n"); 130 130 #endif 131 131 132 + printk(KERN_INFO "Default page size is %dKB.\n", (int)(PAGE_SIZE / 1024)); 133 + 132 134 pdc_console_init(); 133 135 134 136 #ifdef CONFIG_64BIT
+5 -4
arch/parisc/kernel/syscall.S
··· 15 15 #include <asm/thread_info.h> 16 16 #include <asm/assembly.h> 17 17 #include <asm/processor.h> 18 + #include <asm/cache.h> 18 19 19 20 #include <linux/linkage.h> 20 21 ··· 644 643 645 644 .section .rodata,"a" 646 645 647 - .align PAGE_SIZE 646 + .align 8 648 647 /* Light-weight-syscall table */ 649 648 /* Start of lws table. */ 650 649 ENTRY(lws_table) ··· 653 652 END(lws_table) 654 653 /* End of lws table */ 655 654 656 - .align PAGE_SIZE 655 + .align 8 657 656 ENTRY(sys_call_table) 658 657 #include "syscall_table.S" 659 658 END(sys_call_table) 660 659 661 660 #ifdef CONFIG_64BIT 662 - .align PAGE_SIZE 661 + .align 8 663 662 ENTRY(sys_call_table64) 664 663 #define SYSCALL_TABLE_64BIT 665 664 #include "syscall_table.S" ··· 675 674 with ldcw. 676 675 */ 677 676 .section .data 678 - .align PAGE_SIZE 677 + .align L1_CACHE_BYTES 679 678 ENTRY(lws_lock_start) 680 679 /* lws locks */ 681 680 .rept 16
+15 -4
drivers/parisc/sba_iommu.c
··· 575 575 576 576 mtsp(sid,1); 577 577 asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba)); 578 - pa |= (ci >> 12) & 0xff; /* move CI (8 bits) into lowest byte */ 578 + pa |= (ci >> PAGE_SHIFT) & 0xff; /* move CI (8 bits) into lowest byte */ 579 579 580 580 pa |= SBA_PDIR_VALID_BIT; /* set "valid" bit */ 581 581 *pdir_ptr = cpu_to_le64(pa); /* swap and store into I/O Pdir */ ··· 1376 1376 sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) 1377 1377 { 1378 1378 u32 iova_space_size, iova_space_mask; 1379 - unsigned int pdir_size, iov_order; 1379 + unsigned int pdir_size, iov_order, tcnfg; 1380 1380 1381 1381 /* 1382 1382 ** Determine IOVA Space size from memory size. ··· 1468 1468 WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa+IOC_IBASE); 1469 1469 WRITE_REG(ioc->imask, ioc->ioc_hpa+IOC_IMASK); 1470 1470 1471 - /* Set I/O PDIR Page size to 4K */ 1472 - WRITE_REG(0, ioc->ioc_hpa+IOC_TCNFG); 1471 + /* Set I/O PDIR Page size to system page size */ 1472 + switch (PAGE_SHIFT) { 1473 + case 12: tcnfg = 0; break; /* 4K */ 1474 + case 13: tcnfg = 1; break; /* 8K */ 1475 + case 14: tcnfg = 2; break; /* 16K */ 1476 + case 16: tcnfg = 3; break; /* 64K */ 1477 + default: 1478 + panic(__FILE__ "Unsupported system page size %d", 1479 + 1 << PAGE_SHIFT); 1480 + break; 1481 + } 1482 + /* Set I/O PDIR Page size to PAGE_SIZE (4k/16k/...) */ 1483 + WRITE_REG(tcnfg, ioc->ioc_hpa+IOC_TCNFG); 1473 1484 1474 1485 /* 1475 1486 ** Clear I/O TLB of any possible entries.