powerpc/powernv: Initialise nest mmu
POWER9 contains an off core mmu called the nest mmu (NMMU). This is used by other hardware units on the chip to translate virtual addresses into real addresses. The unit attempting an address translation provides the majority of the context required for the translation request except for the base address of the partition table (ie. the PTCR) which needs to be programmed into the NMMU. This patch adds a call to OPAL to set the PTCR for the nest mmu in opal_init(). Signed-off-by: Alistair Popple <alistair@popple.id.au> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
2a8628d416
commit
1d0761d255
|
@ -167,7 +167,8 @@
|
|||
#define OPAL_INT_EOI 124
|
||||
#define OPAL_INT_SET_MFRR 125
|
||||
#define OPAL_PCI_TCE_KILL 126
|
||||
#define OPAL_LAST 126
|
||||
#define OPAL_NMMU_SET_PTCR 127
|
||||
#define OPAL_LAST 127
|
||||
|
||||
/* Device tree flags */
|
||||
|
||||
|
|
|
@ -232,6 +232,7 @@ int64_t opal_pci_tce_kill(uint64_t phb_id, uint32_t kill_type,
|
|||
int64_t opal_rm_pci_tce_kill(uint64_t phb_id, uint32_t kill_type,
|
||||
uint32_t pe_num, uint32_t tce_size,
|
||||
uint64_t dma_addr, uint32_t npages);
|
||||
int64_t opal_nmmu_set_ptcr(uint64_t chip_id, uint64_t ptcr);
|
||||
|
||||
/* Internal functions */
|
||||
extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright 2017 IBM Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_POWERNV_H
|
||||
#define _ASM_POWERNV_H
|
||||
|
||||
#ifdef CONFIG_PPC_POWERNV
|
||||
extern void powernv_set_nmmu_ptcr(unsigned long ptcr);
|
||||
#else
|
||||
static inline void powernv_set_nmmu_ptcr(unsigned long ptcr) { }
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_POWERNV_H */
|
|
@ -18,6 +18,7 @@
|
|||
#include <asm/machdep.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/powernv.h>
|
||||
|
||||
#include <trace/events/thp.h>
|
||||
|
||||
|
@ -438,6 +439,7 @@ void radix__mmu_cleanup_all(void)
|
|||
lpcr = mfspr(SPRN_LPCR);
|
||||
mtspr(SPRN_LPCR, lpcr & ~LPCR_UPRT);
|
||||
mtspr(SPRN_PTCR, 0);
|
||||
powernv_set_nmmu_ptcr(0);
|
||||
radix__flush_tlb_all();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include <asm/sections.h>
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/powernv.h>
|
||||
|
||||
#include "mmu_decl.h"
|
||||
|
||||
|
@ -436,6 +437,7 @@ void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift)
|
|||
void __init mmu_partition_table_init(void)
|
||||
{
|
||||
unsigned long patb_size = 1UL << PATB_SIZE_SHIFT;
|
||||
unsigned long ptcr;
|
||||
|
||||
BUILD_BUG_ON_MSG((PATB_SIZE_SHIFT > 36), "Partition table size too large.");
|
||||
partition_tb = __va(memblock_alloc_base(patb_size, patb_size,
|
||||
|
@ -448,7 +450,9 @@ void __init mmu_partition_table_init(void)
|
|||
* update partition table control register,
|
||||
* 64 K size.
|
||||
*/
|
||||
mtspr(SPRN_PTCR, __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
|
||||
ptcr = __pa(partition_tb) | (PATB_SIZE_SHIFT - 12);
|
||||
mtspr(SPRN_PTCR, ptcr);
|
||||
powernv_set_nmmu_ptcr(ptcr);
|
||||
}
|
||||
|
||||
void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
|
||||
|
|
|
@ -311,4 +311,5 @@ OPAL_CALL_REAL(opal_rm_int_eoi, OPAL_INT_EOI);
|
|||
OPAL_CALL(opal_int_set_mfrr, OPAL_INT_SET_MFRR);
|
||||
OPAL_CALL_REAL(opal_rm_int_set_mfrr, OPAL_INT_SET_MFRR);
|
||||
OPAL_CALL(opal_pci_tce_kill, OPAL_PCI_TCE_KILL);
|
||||
OPAL_CALL(opal_nmmu_set_ptcr, OPAL_NMMU_SET_PTCR);
|
||||
OPAL_CALL_REAL(opal_rm_pci_tce_kill, OPAL_PCI_TCE_KILL);
|
||||
|
|
|
@ -875,6 +875,17 @@ int opal_error_code(int rc)
|
|||
}
|
||||
}
|
||||
|
||||
void powernv_set_nmmu_ptcr(unsigned long ptcr)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (firmware_has_feature(FW_FEATURE_OPAL)) {
|
||||
rc = opal_nmmu_set_ptcr(-1UL, ptcr);
|
||||
if (rc != OPAL_SUCCESS && rc != OPAL_UNSUPPORTED)
|
||||
pr_warn("%s: Unable to set nest mmu ptcr\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(opal_poll_events);
|
||||
EXPORT_SYMBOL_GPL(opal_rtc_read);
|
||||
EXPORT_SYMBOL_GPL(opal_rtc_write);
|
||||
|
|
Loading…
Reference in New Issue