diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2005-09-23 00:47:58 -0400 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2005-09-23 00:47:58 -0400 |
commit | 4c55130b2aa93370f1bf52d2304394e91cf8ee39 (patch) | |
tree | 522c7f510775f221c4e8046bc238a618db4768df /arch/ppc64/kernel | |
parent | ba293fff085fde5b9f1b5a57c8abb1a8098d0c59 (diff) |
ppc64 iSeries: Update create_pte_mapping to replace iSeries_bolt_kernel()
early_setup() calls htab_initialize() which is similar, but not identical
to iSeries_bolt_kernel().
On iSeries the Hypervisor has already inserted some ptes for us, and we
simply have to detect that and bolt them. iSeries_hpte_bolt_or_insert()
implements that logic.
For the case of a non-existing pte we just call iSeries_hpte_insert(). This
appears to work, although it's not entirely equivalent to the old code in
iSeries_make_pte() which panicked if we got a secondary slot. Not sure if
that's important.
Finally we call iSeries_hpte_bolt_or_insert() from create_pte_mapping(),
which is called from htab_initialize() for each lmb region.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Diffstat (limited to 'arch/ppc64/kernel')
-rw-r--r-- | arch/ppc64/kernel/iSeries_htab.c | 19 | ||||
-rw-r--r-- | arch/ppc64/kernel/iSeries_setup.c | 60 |
2 files changed, 19 insertions, 60 deletions
diff --git a/arch/ppc64/kernel/iSeries_htab.c b/arch/ppc64/kernel/iSeries_htab.c index 2192055a90a0..9a2be3abf349 100644 --- a/arch/ppc64/kernel/iSeries_htab.c +++ b/arch/ppc64/kernel/iSeries_htab.c | |||
@@ -84,6 +84,25 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va, | |||
84 | return (secondary << 3) | (slot & 7); | 84 | return (secondary << 3) | (slot & 7); |
85 | } | 85 | } |
86 | 86 | ||
87 | long iSeries_hpte_bolt_or_insert(unsigned long hpte_group, | ||
88 | unsigned long va, unsigned long prpn, unsigned long vflags, | ||
89 | unsigned long rflags) | ||
90 | { | ||
91 | long slot; | ||
92 | hpte_t lhpte; | ||
93 | |||
94 | slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT); | ||
95 | |||
96 | if (lhpte.v & HPTE_V_VALID) { | ||
97 | /* Bolt the existing HPTE */ | ||
98 | HvCallHpt_setSwBits(slot, 0x10, 0); | ||
99 | HvCallHpt_setPp(slot, PP_RWXX); | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | return iSeries_hpte_insert(hpte_group, va, prpn, vflags, rflags); | ||
104 | } | ||
105 | |||
87 | static unsigned long iSeries_hpte_getword0(unsigned long slot) | 106 | static unsigned long iSeries_hpte_getword0(unsigned long slot) |
88 | { | 107 | { |
89 | hpte_t hpte; | 108 | hpte_t hpte; |
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 75d8db4eaac6..49d0f9999682 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c | |||
@@ -75,7 +75,6 @@ extern void ppcdbg_initialize(void); | |||
75 | 75 | ||
76 | static void build_iSeries_Memory_Map(void); | 76 | static void build_iSeries_Memory_Map(void); |
77 | static void setup_iSeries_cache_sizes(void); | 77 | static void setup_iSeries_cache_sizes(void); |
78 | static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr); | ||
79 | static int iseries_shared_idle(void); | 78 | static int iseries_shared_idle(void); |
80 | static int iseries_dedicated_idle(void); | 79 | static int iseries_dedicated_idle(void); |
81 | #ifdef CONFIG_PCI | 80 | #ifdef CONFIG_PCI |
@@ -383,9 +382,6 @@ static void __init iSeries_init_early(void) | |||
383 | } | 382 | } |
384 | } | 383 | } |
385 | 384 | ||
386 | /* Bolt kernel mappings for all of memory (or just a bit if we've got a limit) */ | ||
387 | iSeries_bolt_kernel(0, systemcfg->physicalMemorySize); | ||
388 | |||
389 | lmb_init(); | 385 | lmb_init(); |
390 | lmb_add(0, systemcfg->physicalMemorySize); | 386 | lmb_add(0, systemcfg->physicalMemorySize); |
391 | lmb_analyze(); | 387 | lmb_analyze(); |
@@ -637,62 +633,6 @@ static void __init setup_iSeries_cache_sizes(void) | |||
637 | } | 633 | } |
638 | 634 | ||
639 | /* | 635 | /* |
640 | * Create a pte. Used during initialization only. | ||
641 | */ | ||
642 | static void iSeries_make_pte(unsigned long va, unsigned long pa, | ||
643 | int mode) | ||
644 | { | ||
645 | hpte_t local_hpte, rhpte; | ||
646 | unsigned long hash, vpn; | ||
647 | long slot; | ||
648 | |||
649 | vpn = va >> PAGE_SHIFT; | ||
650 | hash = hpt_hash(vpn, 0); | ||
651 | |||
652 | local_hpte.r = pa | mode; | ||
653 | local_hpte.v = ((va >> 23) << HPTE_V_AVPN_SHIFT) | ||
654 | | HPTE_V_BOLTED | HPTE_V_VALID; | ||
655 | |||
656 | slot = HvCallHpt_findValid(&rhpte, vpn); | ||
657 | if (slot < 0) { | ||
658 | /* Must find space in primary group */ | ||
659 | panic("hash_page: hpte already exists\n"); | ||
660 | } | ||
661 | HvCallHpt_addValidate(slot, 0, &local_hpte); | ||
662 | } | ||
663 | |||
664 | /* | ||
665 | * Bolt the kernel addr space into the HPT | ||
666 | */ | ||
667 | static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr) | ||
668 | { | ||
669 | unsigned long pa; | ||
670 | unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX; | ||
671 | hpte_t hpte; | ||
672 | |||
673 | for (pa = saddr; pa < eaddr ;pa += PAGE_SIZE) { | ||
674 | unsigned long ea = (unsigned long)__va(pa); | ||
675 | unsigned long vsid = get_kernel_vsid(ea); | ||
676 | unsigned long va = (vsid << 28) | (pa & 0xfffffff); | ||
677 | unsigned long vpn = va >> PAGE_SHIFT; | ||
678 | unsigned long slot = HvCallHpt_findValid(&hpte, vpn); | ||
679 | |||
680 | /* Make non-kernel text non-executable */ | ||
681 | if (!in_kernel_text(ea)) | ||
682 | mode_rw |= HW_NO_EXEC; | ||
683 | |||
684 | if (hpte.v & HPTE_V_VALID) { | ||
685 | /* HPTE exists, so just bolt it */ | ||
686 | HvCallHpt_setSwBits(slot, 0x10, 0); | ||
687 | /* And make sure the pp bits are correct */ | ||
688 | HvCallHpt_setPp(slot, PP_RWXX); | ||
689 | } else | ||
690 | /* No HPTE exists, so create a new bolted one */ | ||
691 | iSeries_make_pte(va, phys_to_abs(pa), mode_rw); | ||
692 | } | ||
693 | } | ||
694 | |||
695 | /* | ||
696 | * Document me. | 636 | * Document me. |
697 | */ | 637 | */ |
698 | static void __init iSeries_setup_arch(void) | 638 | static void __init iSeries_setup_arch(void) |