|
32 | 32 | #include <asm/sections.h> |
33 | 33 | #include <asm/msgbuf.h> |
34 | 34 | #include <asm/sparsemem.h> |
| 35 | +#include <asm/asm-offsets.h> |
35 | 36 |
|
36 | 37 | extern int data_start; |
37 | 38 | extern void parisc_kernel_start(void); /* Kernel entry point in head.S */ |
@@ -720,6 +721,77 @@ void __init paging_init(void) |
720 | 721 | parisc_bootmem_free(); |
721 | 722 | } |
722 | 723 |
|
| 724 | +static void alloc_btlb(unsigned long start, unsigned long end, int *slot, |
| 725 | + unsigned long entry_info) |
| 726 | +{ |
| 727 | + const int slot_max = btlb_info.fixed_range_info.num_comb; |
| 728 | + int min_num_pages = btlb_info.min_size; |
| 729 | + unsigned long size; |
| 730 | + |
| 731 | + /* map at minimum 4 pages */ |
| 732 | + if (min_num_pages < 4) |
| 733 | + min_num_pages = 4; |
| 734 | + |
| 735 | + size = HUGEPAGE_SIZE; |
| 736 | + while (start < end && *slot < slot_max && size >= PAGE_SIZE) { |
| 737 | + /* starting address must have same alignment as size! */ |
| 738 | + /* if correctly aligned and fits in double size, increase */ |
| 739 | + if (((start & (2 * size - 1)) == 0) && |
| 740 | + (end - start) >= (2 * size)) { |
| 741 | + size <<= 1; |
| 742 | + continue; |
| 743 | + } |
| 744 | + /* if current size alignment is too big, try smaller size */ |
| 745 | + if ((start & (size - 1)) != 0) { |
| 746 | + size >>= 1; |
| 747 | + continue; |
| 748 | + } |
| 749 | + if ((end - start) >= size) { |
| 750 | + if ((size >> PAGE_SHIFT) >= min_num_pages) |
| 751 | + pdc_btlb_insert(start >> PAGE_SHIFT, __pa(start) >> PAGE_SHIFT, |
| 752 | + size >> PAGE_SHIFT, entry_info, *slot); |
| 753 | + (*slot)++; |
| 754 | + start += size; |
| 755 | + continue; |
| 756 | + } |
| 757 | + size /= 2; |
| 758 | + continue; |
| 759 | + } |
| 760 | +} |
| 761 | + |
| 762 | +void btlb_init_per_cpu(void) |
| 763 | +{ |
| 764 | + unsigned long s, t, e; |
| 765 | + int slot; |
| 766 | + |
| 767 | + /* BTLBs are not available on 64-bit CPUs */ |
| 768 | + if (IS_ENABLED(CONFIG_PA20)) |
| 769 | + return; |
| 770 | + else if (pdc_btlb_info(&btlb_info) < 0) { |
| 771 | + memset(&btlb_info, 0, sizeof btlb_info); |
| 772 | + } |
| 773 | + |
| 774 | + /* insert BLTLBs for code and data segments */ |
| 775 | + s = (uintptr_t) dereference_function_descriptor(&_stext); |
| 776 | + e = (uintptr_t) dereference_function_descriptor(&_etext); |
| 777 | + t = (uintptr_t) dereference_function_descriptor(&_sdata); |
| 778 | + BUG_ON(t != e); |
| 779 | + |
| 780 | + /* code segments */ |
| 781 | + slot = 0; |
| 782 | + alloc_btlb(s, e, &slot, 0x13800000); |
| 783 | + |
| 784 | + /* sanity check */ |
| 785 | + t = (uintptr_t) dereference_function_descriptor(&_edata); |
| 786 | + e = (uintptr_t) dereference_function_descriptor(&__bss_start); |
| 787 | + BUG_ON(t != e); |
| 788 | + |
| 789 | + /* data segments */ |
| 790 | + s = (uintptr_t) dereference_function_descriptor(&_sdata); |
| 791 | + e = (uintptr_t) dereference_function_descriptor(&__bss_stop); |
| 792 | + alloc_btlb(s, e, &slot, 0x11800000); |
| 793 | +} |
| 794 | + |
723 | 795 | #ifdef CONFIG_PA20 |
724 | 796 |
|
725 | 797 | /* |
|
0 commit comments