[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3 3/3] xen/ppc: Implement initial Radix MMU support
On 10.08.2023 00:48, Shawn Anastasio wrote: > --- /dev/null > +++ b/xen/arch/ppc/include/asm/page.h > @@ -0,0 +1,181 @@ > +#ifndef _ASM_PPC_PAGE_H > +#define _ASM_PPC_PAGE_H > + > +#include <xen/types.h> > + > +#include <asm/bitops.h> > +#include <asm/byteorder.h> > + > +#define PDE_VALID PPC_BIT(0) > +#define PDE_NLB_MASK 0xfffffffffffffUL > +#define PDE_NLB_SHIFT 5UL > +#define PDE_NLS_MASK 0x1f > + > +#define PTE_VALID PPC_BIT(0) > +#define PTE_LEAF PPC_BIT(1) > +#define PTE_REFERENCE PPC_BIT(55) > +#define PTE_CHANGE PPC_BIT(56) > + > +/* PTE Attributes */ > +#define PTE_ATT_SAO PPC_BIT(59) /* Strong Access Ordering */ > +#define PTE_ATT_NON_IDEMPOTENT PPC_BIT(58) > +#define PTE_ATT_TOLERANT (PPC_BIT(58) | PPC_BIT(59)) > + > +/* PTE Encoded Access Authority*/ > +#define PTE_EAA_PRIVILEGED PPC_BIT(60) > +#define PTE_EAA_READ PPC_BIT(61) > +#define PTE_EAA_WRITE PPC_BIT(62) > +#define PTE_EAA_EXECUTE PPC_BIT(63) > + > +/* Field shifts/masks */ > +#define PTE_RPN_MASK 0x1fffffffffffUL > +#define PTE_RPN_SHIFT 12UL I still don't understand why you need two constants here. Even more so that now all their uses are as (PTE_RPN_MASK << PTE_RPN_SHIFT). With (only) #define PTE_RPN_MASK 0x1fffffffffff000UL instead, as indicated before, you would then (should the need arise) have this usable with MASK_EXTR() / MASK_INSR(). The again you likely know much better than me what further uses are going to appear. > --- /dev/null > +++ b/xen/arch/ppc/include/asm/regs.h > @@ -0,0 +1,138 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +/* > + * 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. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. There's still an SPDX header and a full license here. > --- /dev/null > +++ b/xen/arch/ppc/mm-radix.c > @@ -0,0 +1,265 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +#include <xen/init.h> > +#include <xen/kernel.h> > +#include <xen/types.h> > +#include <xen/lib.h> > + > +#include <asm/bitops.h> > +#include <asm/byteorder.h> > +#include <asm/early_printk.h> > +#include <asm/mm.h> > +#include <asm/page.h> > +#include <asm/processor.h> > +#include <asm/regs.h> > +#include <asm/msr.h> > + > +void enable_mmu(void); > + > +#define INITIAL_LVL1_PD_COUNT 1 > +#define INITIAL_LVL2_LVL3_PD_COUNT 2 > +#define INITIAL_LVL4_PT_COUNT 256 > + > +static size_t initial_lvl1_pd_pool_used; > +static struct lvl1_pd initial_lvl1_pd_pool[INITIAL_LVL1_PD_COUNT]; > + > +static size_t initial_lvl2_lvl3_pd_pool_used; > +static struct lvl2_pd initial_lvl2_lvl3_pd_pool[INITIAL_LVL2_LVL3_PD_COUNT]; > + > +static size_t initial_lvl4_pt_pool_used; > +static struct lvl4_pt initial_lvl4_pt_pool[INITIAL_LVL4_PT_COUNT]; The initial_lvl..._pool_used variables can likely all be __initdata? > +static void __init setup_initial_mapping(struct lvl1_pd *lvl1, > + vaddr_t map_start, > + vaddr_t map_end, > + paddr_t phys_base) > +{ > + uint64_t page_addr; > + > + if ( map_start & ~PAGE_MASK ) > + { > + early_printk("Xen _start be aligned to 64k (PAGE_SIZE) boundary\n"); > + die(); > + } > + > + if ( phys_base & ~PAGE_MASK ) > + { > + early_printk("Xen should be loaded at 64k (PAGE_SIZE) boundary\n"); > + die(); > + } > + > + for ( page_addr = map_start; page_addr < map_end; page_addr += PAGE_SIZE > ) > + { > + struct lvl2_pd *lvl2; > + struct lvl3_pd *lvl3; > + struct lvl4_pt *lvl4; > + pde_t *pde; > + pte_t *pte; > + > + /* Allocate LVL 2 PD if necessary */ > + pde = pt_entry(lvl1, page_addr); > + if ( !pde_is_valid(*pde) ) > + { > + lvl2 = lvl2_pd_pool_alloc(); > + *pde = paddr_to_pde(__pa(lvl2), PDE_VALID, > + XEN_PT_ENTRIES_LOG2_LVL_2); > + } > + else > + lvl2 = (struct lvl2_pd *)__va(pde_to_paddr(*pde)); I don't think the cast here (and similar ones below) is needed. > +static void __init setup_partition_table(struct lvl1_pd *root) > +{ > + unsigned long ptcr; > + > + /* Configure entry for LPID 0 to enable Radix and point to root PD */ > + uint64_t patb0 = RTS_FIELD | __pa(root) | XEN_PT_ENTRIES_LOG2_LVL_1 | > + PATB0_HR; > + uint64_t patb1 = __pa(initial_prtb) | (PRTB_SIZE_LOG2 - 12) | PATB1_GR; > + initial_patb[0].patb0 = cpu_to_be64(patb0); > + initial_patb[0].patb1 = cpu_to_be64(patb1); Nit: Blank line please between declaration(s) and statement(s). > + ptcr = __pa(initial_patb) | (PATB_SIZE_LOG2 - 12); > + mtspr(SPRN_PTCR, ptcr); > +} > + > +static void __init setup_process_table(struct lvl1_pd *root) > +{ > + /* Configure entry for PID 0 to point to root PD */ > + uint64_t prtb0 = RTS_FIELD | __pa(root) | XEN_PT_ENTRIES_LOG2_LVL_1; > + initial_prtb[0].prtb0 = cpu_to_be64(prtb0); Same here then. Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |