[PATCH v5 3/3] xen/ppc: mm-radix: Allocate all paging structures at runtime
In the initial mm-radix implementation, the in-memory partition and process tables required to configure the MMU, as well as the page tables themselves were all allocated statically since the boot allocator was not yet available. Now that it is, allocate these structures at runtime and bump the size of the Process Table to its maximum supported value (on POWER9). Signed-off-by: Shawn Anastasio --- Changes in v5: - Add more clarification comments to min/max mfn variable decls. Changes in v4: - use mfn_add in initial_page_alloc() - zero pages returned by initial_page_alloc() xen/arch/ppc/mm-radix.c | 238 ++-- 1 file changed, 130 insertions(+), 108 deletions(-) diff --git a/xen/arch/ppc/mm-radix.c b/xen/arch/ppc/mm-radix.c index 24232f3907..e3bf41675b 100644 --- a/xen/arch/ppc/mm-radix.c +++ b/xen/arch/ppc/mm-radix.c @@ -22,69 +22,112 @@ void enable_mmu(void); #define radix_dprintk(...) #endif -#define INITIAL_LVL1_PD_COUNT 1 -#define INITIAL_LVL2_LVL3_PD_COUNT 2 -#define INITIAL_LVL4_PT_COUNT 256 - -static size_t __initdata initial_lvl1_pd_pool_used; -static struct lvl1_pd initial_lvl1_pd_pool[INITIAL_LVL1_PD_COUNT]; - -static size_t __initdata initial_lvl2_lvl3_pd_pool_used; -static struct lvl2_pd initial_lvl2_lvl3_pd_pool[INITIAL_LVL2_LVL3_PD_COUNT]; - -static size_t __initdata initial_lvl4_pt_pool_used; -static struct lvl4_pt initial_lvl4_pt_pool[INITIAL_LVL4_PT_COUNT]; - -/* Only reserve minimum Partition and Process tables */ #define PATB_SIZE_LOG2 16 /* Only supported partition table size on POWER9 */ #define PATB_SIZE (1UL << PATB_SIZE_LOG2) -#define PRTB_SIZE_LOG2 12 +#define PRTB_SIZE_LOG2 24 /* Maximum process table size on POWER9 */ #define PRTB_SIZE (1UL << PRTB_SIZE_LOG2) -static struct patb_entry -__aligned(PATB_SIZE) initial_patb[PATB_SIZE / sizeof(struct patb_entry)]; +static struct patb_entry *initial_patb; +static struct prtb_entry *initial_prtb; -static struct prtb_entry -__aligned(PRTB_SIZE) initial_prtb[PRTB_SIZE / sizeof(struct prtb_entry)]; +/* + * The highest and lowest mfns returned by initial_page_alloc. In order to + * bootstrap the xen's initial page tables, the mfns allocated to store the + * paging structurs needs to be tracked so that they can be included in the + * mapping. This is most simply accomplished by keeping track of the minimum + * and maximum mfn numbers so that the whole range from min->max can be mapped. + */ +static mfn_t __initdata min_alloc_mfn = {-1}; +static mfn_t __initdata max_alloc_mfn = {0}; -static __init struct lvl1_pd *lvl1_pd_pool_alloc(void) +/* + * A thin wrapper for alloc_boot_pages that keeps track of the maximum and + * minimum mfns that have been allocated. This information is used by + * setup_initial_mapping to include the allocated pages in the initial + * page mapping. + * + * Additionally, allocated pages are zeroed before return. + */ +static mfn_t __init initial_page_alloc(unsigned long nr_pfns, + unsigned long pfn_align) { -if ( initial_lvl1_pd_pool_used >= INITIAL_LVL1_PD_COUNT ) -{ -early_printk("Ran out of space for LVL1 PD!\n"); -die(); -} +mfn_t mfn_first, mfn_last; -return &initial_lvl1_pd_pool[initial_lvl1_pd_pool_used++]; -} +mfn_first = alloc_boot_pages(nr_pfns, pfn_align); +mfn_last = mfn_add(mfn_first, nr_pfns - 1); -static __init struct lvl2_pd *lvl2_pd_pool_alloc(void) -{ -if ( initial_lvl2_lvl3_pd_pool_used >= INITIAL_LVL2_LVL3_PD_COUNT ) -{ -early_printk("Ran out of space for LVL2/3 PD!\n"); -die(); -} +min_alloc_mfn = _mfn(min(mfn_x(min_alloc_mfn), mfn_x(mfn_first))); +max_alloc_mfn = _mfn(max(mfn_x(max_alloc_mfn), mfn_x(mfn_last))); + +memset(__va(mfn_to_maddr(mfn_first)), 0, nr_pfns << PAGE_SHIFT); -return &initial_lvl2_lvl3_pd_pool[initial_lvl2_lvl3_pd_pool_used++]; +return mfn_first; } -static __init struct lvl3_pd *lvl3_pd_pool_alloc(void) +static __init void *initial_pd_pt_alloc(void) { -BUILD_BUG_ON(sizeof(struct lvl3_pd) != sizeof(struct lvl2_pd)); +BUILD_BUG_ON(sizeof(struct lvl1_pd) > PAGE_SIZE); +BUILD_BUG_ON(sizeof(struct lvl2_pd) > PAGE_SIZE); +BUILD_BUG_ON(sizeof(struct lvl3_pd) > PAGE_SIZE); +BUILD_BUG_ON(sizeof(struct lvl4_pt) > PAGE_SIZE); -return (struct lvl3_pd *) lvl2_pd_pool_alloc(); +return __va(mfn_to_maddr(initial_page_alloc(1, 1))); } -static __init struct lvl4_pt *lvl4_pt_pool_alloc(void) +static void map_page_initial(struct lvl1_pd *lvl1, vaddr_t virt, paddr_t phys, + unsigned long flags) { -if ( initial_lvl4_pt_pool_used >= INITIAL_LVL4_PT_COUNT ) +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, virt
[PATCH v5 0/3] Early Boot Allocation on Power
Hello all, This series enables the Xen boot time allocator on Power by parsing the available memory regions from the firmware-provided device tree. Thanks to Oleksii's work on my patches to move ARM's bootfdt code to common, v5 is much smaller. One new patch is included to fix some newly-broken behavior in bootfdt.c regarding handling of DT reserved memory maps. Thanks, Shawn Shawn Anastasio (3): xen/device-tree: Let DT reserve map entries overlap reserved-memory xen/ppc: Enable bootfdt and boot allocator xen/ppc: mm-radix: Allocate all paging structures at runtime xen/arch/ppc/mm-radix.c | 238 -- xen/arch/ppc/setup.c | 20 ++- xen/common/device-tree/bootfdt.c | 37 - xen/common/device-tree/bootinfo.c | 11 +- xen/include/xen/bootfdt.h | 3 +- 5 files changed, 191 insertions(+), 118 deletions(-) -- 2.30.2
[PATCH v5 1/3] xen/device-tree: Let DT reserve map entries overlap reserved-memory
Commit 53dc37829c31 ("xen/arm: Add DT reserve map regions to bootinfo.reserved_mem") changes the way reserve map regions are tracked, and as a result broke bootfdt's ability to handle device trees in which the reserve map and the `reserved-memory` node contain the same entries as each other, as is the case on PPC when booted by skiboot. Fix this behavior by moving the reserve map check to after the DT has been parsed and by explicitly allowing overlap with entries created by `reserved-memory` nodes. Fixes: 53dc37829c31 ("xen/arm: Add DT reserve map regions to bootinfo.reserved_mem") Signed-off-by: Shawn Anastasio --- xen/common/device-tree/bootfdt.c | 28 +++- xen/common/device-tree/bootinfo.c | 11 +-- xen/include/xen/bootfdt.h | 3 ++- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/xen/common/device-tree/bootfdt.c b/xen/common/device-tree/bootfdt.c index 911a630e7d..2a51ee44a3 100644 --- a/xen/common/device-tree/bootfdt.c +++ b/xen/common/device-tree/bootfdt.c @@ -177,7 +177,7 @@ static int __init device_tree_get_meminfo(const void *fdt, int node, { device_tree_get_reg(&cell, address_cells, size_cells, &start, &size); if ( mem == bootinfo_get_reserved_mem() && - check_reserved_regions_overlap(start, size) ) + check_reserved_regions_overlap(start, size, NULL) ) return -EINVAL; /* Some DT may describe empty bank, ignore them */ if ( !size ) @@ -590,14 +590,36 @@ size_t __init boot_fdt_info(const void *fdt, paddr_t paddr) if ( nr_rsvd < 0 ) panic("Parsing FDT memory reserve map failed (%d)\n", nr_rsvd); +ret = device_tree_for_each_node(fdt, 0, early_scan_node, NULL); +if ( ret ) +panic("Early FDT parsing failed (%d)\n", ret); + for ( i = 0; i < nr_rsvd; i++ ) { +const struct membanks *overlap = NULL; struct membank *bank; paddr_t s, sz; if ( fdt_get_mem_rsv_paddr(device_tree_flattened, i, &s, &sz) < 0 ) continue; +if ( check_reserved_regions_overlap(s, sz, &overlap) ) +{ +if ( overlap == bootinfo_get_reserved_mem() ) +{ +/* + * Some valid device trees, such as those generated by OpenPOWER + * skiboot firmware, expose all reserved memory regions in the + * FDT memory reservation block (here) AND in the + * reserved-memory node which has already been parsed. Thus, any + * overlaps in the mem_reserved banks should be ignored. + */ + continue; +} +else +panic("FDT reserve map overlapped with membanks/modules\n"); +} + if ( reserved_mem->nr_banks < reserved_mem->max_banks ) { bank = &reserved_mem->bank[reserved_mem->nr_banks]; @@ -610,10 +632,6 @@ size_t __init boot_fdt_info(const void *fdt, paddr_t paddr) panic("Cannot allocate reserved memory bank\n"); } -ret = device_tree_for_each_node(fdt, 0, early_scan_node, NULL); -if ( ret ) -panic("Early FDT parsing failed (%d)\n", ret); - /* * On Arm64 setup_directmap_mappings() expects to be called with the lowest * bank in memory first. There is no requirement that the DT will provide diff --git a/xen/common/device-tree/bootinfo.c b/xen/common/device-tree/bootinfo.c index f2e6a1145b..c1752bfdc8 100644 --- a/xen/common/device-tree/bootinfo.c +++ b/xen/common/device-tree/bootinfo.c @@ -171,7 +171,8 @@ void __init fw_unreserved_regions(paddr_t s, paddr_t e, * existing reserved memory regions, otherwise false. */ bool __init check_reserved_regions_overlap(paddr_t region_start, - paddr_t region_size) + paddr_t region_size, + const struct membanks **out_overlapping_membanks) { const struct membanks *mem_banks[] = { bootinfo_get_reserved_mem(), @@ -190,8 +191,14 @@ bool __init check_reserved_regions_overlap(paddr_t region_start, * shared memory banks (when static shared memory feature is enabled) */ for ( i = 0; i < ARRAY_SIZE(mem_banks); i++ ) +{ if ( meminfo_overlap_check(mem_banks[i], region_start, region_size) ) +{ +if ( out_overlapping_membanks ) +*out_overlapping_membanks = mem_banks[i]; return true; +} +} /* Check if input region is overlapping with bootmodules */ if ( bootmodules_overlap_check(&bootinfo.modules, @@ -216,7 +223,7 @@ struct bootmodule __init *add_boot_module(bootmodule_kind kind, return NULL; } -if ( check_rese
[PATCH v5 2/3] xen/ppc: Enable bootfdt and boot allocator
Enable usage of bootfdt for populating the boot info struct from the firmware-provided device tree. Also enable the Xen boot page allocator. Additionally, modify bootfdt.c's boot_fdt_info() to tolerate the scenario in which the FDT overlaps a reserved memory region, as is the case on PPC when booted directly from skiboot. Since this means that Xen can now boot without a BOOTMOD_FDT present in bootinfo, clarify this fact in a comment above BOOTMOD_FDT's definition. Signed-off-by: Shawn Anastasio Acked-by: Julien Grall --- Changes in v5: - Drop setup.c's unnecessary `boot_fdt` variable per Julien's suggestion xen/arch/ppc/setup.c | 20 +++- xen/common/device-tree/bootfdt.c | 11 +-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/xen/arch/ppc/setup.c b/xen/arch/ppc/setup.c index 5fb5ab64e3..17bc1aed34 100644 --- a/xen/arch/ppc/setup.c +++ b/xen/arch/ppc/setup.c @@ -1,4 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include +#include #include #include #include @@ -9,6 +11,7 @@ #include #include #include +#include /* Xen stack for bringing up the first CPU. */ unsigned char __initdata cpu0_boot_stack[STACK_SIZE] __aligned(STACK_SIZE); @@ -26,6 +29,8 @@ void __init noreturn start_xen(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { +const struct bootmodule *xen_bootmodule; + if ( r5 ) { /* Unsupported OpenFirmware boot protocol */ @@ -34,11 +39,24 @@ void __init noreturn start_xen(unsigned long r3, unsigned long r4, else { /* kexec boot protocol */ -boot_opal_init((void *)r3); +device_tree_flattened = (void *)r3; +boot_opal_init(device_tree_flattened); } setup_exceptions(); +boot_fdt_info(device_tree_flattened, r3); + +/* + * Xen relocates itself at the ppc64 entrypoint, so we need to manually mark + * the kernel module. + */ +xen_bootmodule = add_boot_module(BOOTMOD_XEN, __pa(_start), + PAGE_ALIGN(__pa(_end)), false); +BUG_ON(!xen_bootmodule); + +populate_boot_allocator(); + setup_initial_pagetables(); init_constructors(); diff --git a/xen/common/device-tree/bootfdt.c b/xen/common/device-tree/bootfdt.c index 2a51ee44a3..5facd683b8 100644 --- a/xen/common/device-tree/bootfdt.c +++ b/xen/common/device-tree/bootfdt.c @@ -584,8 +584,6 @@ size_t __init boot_fdt_info(const void *fdt, paddr_t paddr) if ( ret < 0 ) panic("No valid device tree\n"); -add_boot_module(BOOTMOD_FDT, paddr, fdt_totalsize(fdt), false); - nr_rsvd = fdt_num_mem_rsv(fdt); if ( nr_rsvd < 0 ) panic("Parsing FDT memory reserve map failed (%d)\n", nr_rsvd); @@ -632,6 +630,15 @@ size_t __init boot_fdt_info(const void *fdt, paddr_t paddr) panic("Cannot allocate reserved memory bank\n"); } +/* + * Add module for the FDT itself after the device tree has been parsed. This + * is required on ppc64le where the device tree passed to Xen may have been + * allocated by skiboot, in which case it will exist within a reserved + * region and this call will fail. This is fine, however, since either way + * the allocator will know not to step on the device tree. + */ +(void)add_boot_module(BOOTMOD_FDT, paddr, fdt_totalsize(fdt), false); + /* * On Arm64 setup_directmap_mappings() expects to be called with the lowest * bank in memory first. There is no requirement that the DT will provide -- 2.30.2
Re: [PATCH v4 6/6] xen/ppc: mm-radix: Allocate all paging structures at runtime
Hi Jan, I'm revisiting this series and wanted to follow up on your comments. On 4/24/24 9:46 AM, Jan Beulich wrote: > On 12.04.2024 05:55, Shawn Anastasio wrote: >> +/* >> + * A thin wrapper for alloc_boot_pages that keeps track of the maximum and >> + * minimum mfns that have been allocated. This information is used by >> + * setup_initial_mapping to include the allocated pages in the initial >> + * page mapping. > > Plus everything in between. Together with the further comment below I'm > afraid I still think that the constraints (and the justification for them > being tolerable at least for the time being) aren't made sufficiently > clear (perhaps in another code comment next to the respective two > variables' definitions). > Sure, I'll elaborate a bit further in a new comment above those two variables. >> +/* >> + * Identity map all pages we've allocated for paging structures. This >> act >> + * itself will allocate more pages, so continue until we've mapped from >> + * `max_alloc_mfn` down to `min_alloc_mfn`. This assumes that the heap >> grows >> + * downwards, which matches the behavior of alloc_boot_pages. > > ... as long as you only ever allocate individual pages (which looks > to be the case for such incremental allocations, but that imo doesn't > go without saying). > I'm not sure I'm following you. `initial_page_alloc` as well as its underlying `alloc_boot_pages` can only ever allocate individual pages (or contiguous ranges of pages). If the assumption about growing downwards is not met, the code catches it and panics. > Jan Thanks, Shawn
Re: [PATCH v2 1/5] xen: define ACPI and DT device info sections macros
Hi Oleksii, On 9/17/24 11:15 AM, Oleksii Kurochko wrote: > Introduce conditional macros to define device > information sections based on the configuration of ACPI > or device tree support. These sections are required for > common code of device initialization and getting an information > about a device. > > These macros are expected to be used across different > architectures (Arm, PPC, RISC-V), so they are moved to > the common xen/xen.lds.h, based on their original definition > in Arm. > > Signed-off-by: Oleksii Kurochko > --- > Changes in v2: > - New patch. > --- > xen/include/xen/xen.lds.h | 26 ++ > 1 file changed, 26 insertions(+) > > diff --git a/xen/include/xen/xen.lds.h b/xen/include/xen/xen.lds.h > index a17810bb28..aa7301139d 100644 > --- a/xen/include/xen/xen.lds.h > +++ b/xen/include/xen/xen.lds.h > @@ -114,6 +114,21 @@ > > /* List of constructs other than *_SECTIONS in alphabetical order. */ > > +#define USE_DECL_SECTION(x) DECL_SECTION(x) > + > +#define NOUSE_DECL_SECTION(x) x : > + > +#ifdef CONFIG_ACPI > +#define ACPI_DEV_INFO_SEC(secname, DECL_SECTION_MACROS_NAME) \ > +DECL_SECTION_MACROS_NAME(secname) { \ > + _asdevice = .;\ > + *(secname)\ > + _aedevice = .;\ > +} :text > +#else > +#define ACPI_DEV_INFO_SEC(secname, DECL_SECTION_MACROS_NAME) > +#endif /* CONFIG_ACPI */ This works, but is there a reason you didn't just define the actual entries themselves in the macro, like is done for most of the other macros in this file (including BUFRAMES right below this)? Something like: #define ADEV_INFO \ _asdevice = .;\ *(secname)\ _aedevice = .;\ Parameterizing the section name seems pointless since there are other parts of the code that rely on them, and parameterizing the macro for declaring a section adds unnecessary boilerplate for non-ppc/x86 architectures (the NOUSE_DECL_SECTION no-op). > + > #define BUGFRAMES \ > __start_bug_frames_0 = .; \ > *(.bug_frames.0)\ > @@ -131,6 +146,17 @@ > *(.bug_frames.3)\ > __stop_bug_frames_3 = .; > > +#ifdef CONFIG_HAS_DEVICE_TREE > +#define DT_DEV_INFO_SEC(secname, DECL_SECTION_MACROS_NAME) \ > +DECL_SECTION_MACROS_NAME(secname) { \ > + _sdevice = .; \ > + *(secname)\ > + _edevice = .; \ > +} :text > +#else > +#define DECL_DT_DEV_INFO_SEC(secname, DECL_SECTION_MACROS_NAME) > +#endif /* CONFIG_HAS_DEVICE_TREE */ Ditto. Also, if you go with the approach I mentioned, then you wouldn't need to guard these on CONFIG_HAS_DEVICE_TREE/CONFIG_ACPI since that would be done in the linker scripts themselves. Thanks, Shawn
Re: [PATCH v2 3/5] xen/ppc: add section for device information in linker script
Hi Oleksii, On 9/17/24 11:15 AM, Oleksii Kurochko wrote: > Introduce a new `.dev.info` section in the PPC linker script to > handle device-specific information. This section is required by > common code (common/device.c: device_init(), device_get_class() ). > This section is aligned to `POINTER_ALIGN`, with `_sdevice` and `_edevice` > marking the start and end of the section, respectively. > > Signed-off-by: Oleksii Kurochko > --- > Changes in V2: > - reuse DT_DEV_INFO_SEC introduced earlier in this patch series with using >of DECL_SECTION. > --- > xen/arch/ppc/xen.lds.S | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/xen/arch/ppc/xen.lds.S b/xen/arch/ppc/xen.lds.S > index 38cd857187..6e5582c3e4 100644 > --- a/xen/arch/ppc/xen.lds.S > +++ b/xen/arch/ppc/xen.lds.S > @@ -94,6 +94,9 @@ SECTIONS > CONSTRUCTORS > } :text > > +. = ALIGN(POINTER_ALIGN); /* Devicetree based device info */ > +DT_DEV_INFO_SEC(.dev.info, USE_DECL_SECTION) > + As I mentioned in my comment on patch 1, I think this should be done in the same style as the other xen.lds.h macros, which leaves the actual section declaration here in xen.lds.S and just uses the macro to fill in the definition. Whether or not that route is ultimately taken though, this change is fine from the PPC end of things: Acked-by: Shawn Anastasio Thanks, Shawn
Re: [PATCH 2/2] ppc/shutdown: Implement machine_{halt,restart}()
Hi Andrew, Overall this looks good, I just have one comment. On 7/5/24 1:23 PM, Andrew Cooper wrote: > diff --git a/xen/arch/ppc/shutdown.c b/xen/arch/ppc/shutdown.c > new file mode 100644 > index ..c4b00e57b13a > --- /dev/null > +++ b/xen/arch/ppc/shutdown.c > @@ -0,0 +1,43 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +#include > + > +#include > + > +int64_t opal_cec_power_down(uint64_t request); > +int64_t opal_cec_reboot(void); > +int64_t opal_poll_events(uint64_t *outstanding_event_mask); > + > +void machine_halt(void) > +{ > +int rc; > + Before the opal_cec_{power_down,reboot} calls are made, any interupts reserved for OPAL to handle need to be masked off. Since we don't have any set up at this point, I would just add a TODO comment like: /* TODO: mask any OPAL IRQs before shutting down */ > +do { > +rc = opal_cec_power_down(0); > + > +if ( rc == OPAL_BUSY_EVENT ) > +opal_poll_events(NULL); > + > +} while ( rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT ); > + > +for ( ;; ) > +opal_poll_events(NULL); > +} > + > +void machine_restart(unsigned int delay_millisecs) > +{ > +int rc; > + > +/* TODO: mdelay(delay_millisecs); */ > + Ditto. > +do { > +rc = opal_cec_reboot(); > + > +if ( rc == OPAL_BUSY_EVENT ) > +opal_poll_events(NULL); > + > +} while ( rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT ); > + > +for ( ;; ) > +opal_poll_events(NULL); > +} > + Other than that, looks great. Reviewed-by: Shawn Anastasio Thanks, Shawn
Re: [PATCH for-4.19] ppc/riscv: fix arch_acquire_resource_check()
Hi Roger, On 4/30/24 10:34 AM, Roger Pau Monne wrote: > None of the implementations support set_foreign_p2m_entry() yet, neither they > have a p2m walk in domain_relinquish_resources() in order to remove the > foreign > mappings from the p2m and thus drop the extra refcounts. > > Adjust the arch helpers to return false and introduce a comment that clearly > states it is not only taking extra refcounts that's needed, but also dropping > them on domain teardown. > > Fixes: 4988704e00d8 ('xen/riscv: introduce p2m.h') > Fixes: 4a2f68f90930 ('xen/ppc: Define minimal stub headers required for full > build') > Signed-off-by: Roger Pau Monné > --- This makes sense to me. This stub implementation was definitely an oversight on my part. Acked-by: Shawn Anastasio Thanks, Shawn
Re: [PATCH v2 01/13] ppc/boot: Run constructors on boot
Hi Andrew, On 5/24/24 3:03 PM, Andrew Cooper wrote: > PPC collects constructors, but doesn't run them yet. Do so. > > They'll shortly be used to confirm correct behaviour of the bitops primitives. > > Signed-off-by: Andrew Cooper > --- Looks good to me. Acked-by: Shawn Anastasio Thanks, Shawn
Re: [PATCH 1/2] arch/irq: Make irq_ack_none() mandatory
Hi Andrew, On 5/30/24 1:40 PM, Andrew Cooper wrote: > Any non-stub implementation of these is going to have to do something here. > > irq_end_none() is more complicated and has arch-specific interactions with > irq_ack_none(), so make it optional. > > For PPC, introduce a stub irq_ack_none(). > > For ARM and x86, export the existing {ack,end}_none() helpers, gaining an irq_ > prefix for consisntency with everything else in no_irq_type. > > No functional change. > > Signed-off-by: Andrew Cooper For the PPC parts: Acked-by: Shawn Anastasio a Thanks, Shawn
Re: [PATCH 2/2] arch/irq: Centralise no_irq_type
Hi Andrew, On 5/30/24 1:40 PM, Andrew Cooper wrote: > Having no_irq_type defined per arch, but using common callbacks is a mess, and > particualrly hard to bootstrap a new architecture with. > > Now that the ack()/end() hooks have been exported suitably, move the > definition of no_irq_type into common/irq.c, and into .rodata for good > measure. > > No functional change, but a whole lot less tangled. > > Signed-off-by: Andrew Cooper Acked-by: Shawn Anastasio Thanks, Shawn
Re: [PATCH for-4.19] xen/arch: Centralise __read_mostly and __ro_after_init
On 6/14/24 7:49 AM, Andrew Cooper wrote: > These being in cache.h is inherited from Linux, but is an inappropriate > location to live. > > __read_mostly is an optimisation related to data placement in order to avoid > having shared data in cachelines that are likely to be written to, but it > really is just a section of the linked image separating data by usage > patterns; it has nothing to do with cache sizes or flushing logic. > > Worse, __ro_after_init was only in xen/cache.h because __read_mostly was in > arch/cache.h, and has literally nothing whatsoever to do with caches. > > Move the definitions into xen/sections.h, which in paritcular means that > RISC-V doesn't need to repeat the problematic pattern. Take the opportunity > to provide a short descriptions of what these are used for. > > For now, leave TODO comments next to the other identical definitions. It > turns out that unpicking cache.h is more complicated than it appears because a > number of files use it for transitive dependencies. > > Signed-off-by: Andrew Cooper This seems like a reasonable approach, and removing usage of the old cache.h __read_mostly from the PPC tree should be a relatively simple follow up patch from my end. Acked-by: Shawn Anastasio Thanks, Shawn
Re: XenSummit: Empty per-arch files
On 6/28/23 6:32 AM, Andrew Cooper wrote: > Hello, Hi Andrew, > This wasn't a formal discussion point at XenSummit, but Oleksii pointed > out that it was still a problem, hence this thread. > > As we take on more architectures, it becomes more and more important for > things to be handled in a mostly-common way. With that comes quite a > lot of including , and the arch one being a stub > in simple cases. > > It would be nice to get rid of the stub files; they're irritating to > deal with, both when refactoring and simply for the file bloat they create. This is definitely something that would be great to see from the Power side of things, especially as we're getting to the point where we'd like to start dropping the build overrides in arch.mk and building the rest of xen/common/. As we get to that point, I was wonder if upstream would be fine with submission of patches that add stub files for ppc in the interim, to be removed later when this proposal is finalized and a solution is decided upon. It'd obviously be best to avoid too much duplication of effort, but at the same time we'd like to avoid getting blocked on progressing. > ~Andrew Thanks, Shawn
Re: [PATCH v3 1/3] xen/ppc: Set up a basic C environment
On 7/17/23 10:38 AM, Jan Beulich wrote: > On 06.07.2023 21:04, Shawn Anastasio wrote: >> --- a/xen/arch/ppc/include/asm/config.h >> +++ b/xen/arch/ppc/include/asm/config.h >> @@ -43,7 +43,7 @@ >> >> #define SMP_CACHE_BYTES (1 << 6) >> >> -#define STACK_ORDER 2 >> +#define STACK_ORDER 0 >> #define STACK_SIZE (PAGE_SIZE << STACK_ORDER) > > In which way is this related to the change at hand? Aren't you going to > need to undo this rather sooner than later? I noticed the stack order being too large when I moved the stack declaration to .c per Andrew's recommendation for v2. Since we're using 64k pages, I don't see why the stack would need to be this big. A quick look at ARM shows they have a stack order of 3, which would yield a stack size of just 32k. >> --- a/xen/arch/ppc/ppc64/head.S >> +++ b/xen/arch/ppc/ppc64/head.S >> @@ -1,30 +1,30 @@ >> /* SPDX-License-Identifier: GPL-2.0-or-later */ >> >> +#include >> + >> .section .text.header, "ax", %progbits >> >> ENTRY(start) >> /* >> - * Depending on how we were booted, the CPU could be running in either >> - * Little Endian or Big Endian mode. The following trampoline from Linux >> - * cleverly uses an instruction that encodes to a NOP if the CPU's >> - * endianness matches the assumption of the assembler (LE, in our case) >> - * or a branch to code that performs the endian switch in the other >> case. >> + * NOTE: argument registers (r3-r9) must be preserved until the C >> entrypoint >> */ >> -tdi 0, 0, 0x48/* Reverse endian of b . + 8 */ >> -b . + 44 /* Skip trampoline if endian is good */ >> -.long 0xa600607d /* mfmsr r11 */ >> -.long 0x01006b69 /* xori r11,r11,1 */ >> -.long 0x4039 /* li r10,0 */ >> -.long 0x6401417d /* mtmsrd r10,1 */ >> -.long 0x05009f42 /* bcl 20,31,$+4 */ >> -.long 0xa602487d /* mflr r10 */ >> -.long 0x14004a39 /* addi r10,r10,20*/ >> -.long 0xa6035a7d /* mtsrr0 r10 */ >> -.long 0xa6037b7d /* mtsrr1 r11 */ >> -.long 0x244c /* rfid */ >> - >> -/* Now that the endianness is confirmed, continue */ >> -1: b 1b >> +FIXUP_ENDIAN >> + >> +/* set up the TOC pointer */ >> +LOAD_IMM32(%r2, .TOC.) >> + >> +/* set up the initial stack */ >> +LOAD_IMM32(%r1, cpu0_boot_stack) > > Wouldn't this (and perhaps also .TOC.) better be calculated in a > PC-relative manner? Or is the plan to have Xen linked to an address > below 4Gb? As mentioned previously, I am planning to enable the PIC code model in my next series in order to accommodate booting on the PowerNV firmware type which has a different load address. That patch will change the initial TOC load to a simulated PC-relative one (pre-POWER10 doesn't have proper PC-relative loads/stores) and the rest to TOC-relative. >> +li %r11, 0 >> +stdu %r11, -STACK_FRAME_OVERHEAD(%r1) >> + >> +/* call the C entrypoint */ >> +bl start_xen >> + >> +/* should never return */ >> +trap >> >> .size start, . - start >> .type start, %function >> + >> +.section .init.data, "aw", @progbits > > What's this good for when no data follows? Good catch. With the stack no longer declared in head.S this is unnecessary. Will remove in v3. >> --- /dev/null >> +++ b/xen/arch/ppc/setup.c >> @@ -0,0 +1,19 @@ >> +/* SPDX-License-Identifier: GPL-2.0-or-later */ >> +#include >> + >> +/* Xen stack for bringing up the first CPU. */ >> +unsigned char __initdata cpu0_boot_stack[STACK_SIZE] __aligned(STACK_SIZE); > > This yields the entire array as zero-initialized. At which point I > don't see a need for the store in head.S. Okay, fair enough. Given that the array is zero-initialized the stdu could be replaced with an `addi %r1, %r1, -STACK_FRAME_OVERHEAD`, and the load of zero to %r11 could be deferred to the second patch in this series where it's used in the .bss clearing loop. That said I don't really see the harm with keeping the standard idiomatic `stdu` for the initial stack frame setup. Other than performance, which isn't a concern here in early setup code. >> +/* Macro to adjust thread priority for hardware multithreading */ >> +#define HMT_very_low() asm volatile (" or %r31, %r31, %r31 ") > > Nit: Style. Wants to be > > #define HMT_very_low() asm volatile ( "or %r31, %r31, %r31" ) Will fix in v3. > Jan Thanks, Shawn
Re: [PATCH v3 2/3] xen/ppc: Implement early serial printk on pseries
On 7/17/23 11:17 AM, Jan Beulich wrote: > On 06.07.2023 21:04, Shawn Anastasio wrote: >> --- a/xen/arch/ppc/Makefile >> +++ b/xen/arch/ppc/Makefile >> @@ -1,5 +1,7 @@ >> obj-$(CONFIG_PPC64) += ppc64/ >> >> +obj-y += boot-of.init.o >> +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o > > While in this case I could accept the name as is to be the same as Arm's, > as said before it would be nice if new files could avoid underscores (and > use dashes instead) unless strictly required by something. > > Also, with boot-of.c using early_printk.c, shouldn't the latter also > build into early_printk.init.o? Yes, good point. I'll change it to early_printk.init.o. >> --- /dev/null >> +++ b/xen/arch/ppc/boot-of.c >> @@ -0,0 +1,100 @@ >> +/* SPDX-License-Identifier: GPL-2.0-or-later */ >> +/* >> + * Copyright IBM Corp. 2005, 2006, 2007 > > Judging from the years the file was taken from somewhere. Is the license > there permitting "2.0 or later"? (For files [partly] taken from somewhere, > a clarification as to the originals' licenses would be helpful to have in > the description, or maybe in the post-commit-message area.) The original license of the file that this was derived from (xen/arch/powerpc/boot_of.c from Xen 3.2) is GPL v2.0 or later. In any case where I'm deriving code from existing files, I'm always using the original license of the derived code. Should I still clarify this in the header comment? >> + * Copyright Raptor Engineering, LLC >> + * >> + * Authors: Jimi Xenidis >> + * Hollis Blanchard >> + * Shawn Anastasio >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#define ADDR(x) (uint32_t)(unsigned long)(x) > > Besides needing to be wrapped in parentheses, this likely needs a comment: > It is hard to see how in 64-bit code uint32_t can suffice as an address. > Unless (see the question on patch 1) you intend to link/run Xen at an > address firmly below 4Gb, now and going forward. Calls to the Open Firmware client interface necessitate that the CPU be running with both the MMU off and in 32-bit mode (MSR_SF unset). Obviously these two criteria will not always be true for Xen itself, but we can guarantee that Xen's physical address lies below 4GB. In fact, the mere act of being booted by Open Firmware should guarantee that this is the case. This also came up earlier, but the Open Firmware interface will only need to be used during early boot. Once the MMU is up it shouldn't be necessary to use it, but if it does end up being required this could be changed to use __pa() or equivalent (plus the uint32_t cast). I'll definitely add a comment explaining the situation, as well as the extra parenthesis. >> +/* OF entrypoint*/ >> +static unsigned long __initdata of_vec; >> + >> +/* OF device handles*/ >> +static int __initdata bof_chosen; >> +static int __initdata of_out; >> + >> +static int __init of_call(const char *service, uint32_t nargs, uint32_t >> nrets, >> + int32_t rets[], ...) > > Nit: Indentation. Will fix. >> +{ >> +int rc; >> +va_list args; >> +int i; > > unsigned int? I might as well change it to uint32_t to be in line with nargs. > >> +struct of_service s = { 0 }; >> + >> +s.ofs_service = cpu_to_be32(ADDR(service)); >> +s.ofs_nargs = cpu_to_be32(nargs); >> +s.ofs_nrets = cpu_to_be32(nrets); >> + >> +/* copy all the params into the args array */ > > Nit: Style (comments want to start with a capital letter). Again below. Will fix. >> +va_start(args, rets); >> + >> +for ( i = 0; i < nargs; i++ ) >> +s.ofs_args[i] = cpu_to_be32(va_arg(args, uint32_t)); >> + >> +va_end(args); >> + >> +rc = enter_of(&s, of_vec); >> + >> +/* copy all return values to the output rets array */ >> +for ( i = 0; i < nrets; i++ ) >> +rets[i] = be32_to_cpu(s.ofs_args[i + nargs]); >> + >> +return rc; >> +} >> + >> +static int __init of_finddevice(const char *devspec) >> +{ >> +int rets[1] = { OF_FAILURE }; > > Hmm, of_call() uses int32_t. Again below several times. Good catch. I'll switch all of these to int32_t for consistency. > >> +of_call("finddevice", 1, 1, rets, devspec); > > This could do with using ARRAY_SIZE(rets). Same again below. Sure, will do this. > Also don't you need to wrap devspec in ADDR()? Similar issues > then
Re: [PATCH v3 2/3] xen/ppc: Implement early serial printk on pseries
Quick followup, On 7/17/23 1:32 PM, Shawn Anastasio wrote: > On 7/17/23 11:17 AM, Jan Beulich wrote: >> This could do with using ARRAY_SIZE(rets). Same again below. > > Sure, will do this. ARRAY_SIZE is defined in which can't yet be included due to missing headers. I could copy its definition into this file along with a TODO comment to fix it once the include works. If I were to go down that route, I'd also probably not include the __must_be_array assertion and related machinery that the version has, since it'd require a large portion of to be copy/pasted.
Re: [PATCH v3 1/8] common: move a few macros out of xen/lib.h
On 7/10/23 3:51 AM, Jan Beulich wrote: > Introduce xen/macros.h for this purpose. For now xen/lib.h simply > includes xen/macro.h, until consumers can be suitable cleaned up. > > Signed-off-by: Jan Beulich > --- > v3: New. > > --- a/xen/include/xen/lib.h > +++ b/xen/include/xen/lib.h > @@ -1,26 +1,7 @@ > #ifndef __LIB_H__ > #define __LIB_H__ > > -#define ROUNDUP(x, a) (((x) + (a) - 1) & ~((a) - 1)) > - > -#define IS_ALIGNED(val, align) (!((val) & ((align) - 1))) > - > -#define DIV_ROUND(n, d) (((n) + (d) / 2) / (d)) > -#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) > - > -#define MASK_EXTR(v, m) (((v) & (m)) / ((m) & -(m))) > -#define MASK_INSR(v, m) (((v) * ((m) & -(m))) & (m)) > - > -#define count_args_(dot, a1, a2, a3, a4, a5, a6, a7, a8, x, ...) x > -#define count_args(args...) \ > -count_args_(., ## args, 8, 7, 6, 5, 4, 3, 2, 1, 0) > - > -/* Indirect macros required for expanded argument pasting. */ > -#define PASTE_(a, b) a ## b > -#define PASTE(a, b) PASTE_(a, b) > - > -#define __STR(...) #__VA_ARGS__ > -#define STR(...) __STR(__VA_ARGS__) > +#include > > #ifndef __ASSEMBLY__ > > --- /dev/null > +++ b/xen/include/xen/macros.h > @@ -0,0 +1,34 @@ Should there be an SPDX header here? > +#ifndef __MACROS_H__ > +#define __MACROS_H__ > + > +#define ROUNDUP(x, a) (((x) + (a) - 1) & ~((a) - 1)) > + > +#define IS_ALIGNED(val, align) (!((val) & ((align) - 1))) > + > +#define DIV_ROUND(n, d) (((n) + (d) / 2) / (d)) > +#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) > + > +#define MASK_EXTR(v, m) (((v) & (m)) / ((m) & -(m))) > +#define MASK_INSR(v, m) (((v) * ((m) & -(m))) & (m)) > + > +#define count_args_(dot, a1, a2, a3, a4, a5, a6, a7, a8, x, ...) x > +#define count_args(args...) \ > +count_args_(., ## args, 8, 7, 6, 5, 4, 3, 2, 1, 0) > + > +/* Indirect macros required for expanded argument pasting. */ > +#define PASTE_(a, b) a ## b > +#define PASTE(a, b) PASTE_(a, b) > + > +#define __STR(...) #__VA_ARGS__ > +#define STR(...) __STR(__VA_ARGS__) > + > +#endif /* __MACROS_H__ */ > + > +/* > + * Local variables: > + * mode: C > + * c-file-style: "BSD" > + * c-basic-offset: 4 > + * indent-tabs-mode: nil > + * End: > + */ Reviewed-by: Shawn Anastasio
[PATCH v4 0/4] Early serial on Power
Hello all, This series adds support for early serial printing on Power, as well as a simple CI smoke test modeled after the riscv one. The first patch is responsible for setting up a basic C environment with an initial stack while the second sets up an Open Firmware serial console and primitive early_printk infrastructure. This will currently only run on QEMU pseries VMs, since the firmware interface on bare metal differs significantly. Support for bare metal will be added in a future series along with support for the position-independent code model. Based on v3 of Jan's "common: move a few macros out of xen/lib.h" (https://lists.xen.org/archives/html/xen-devel/2023-07/msg00582.html) Thanks, Shawn -- Changes in v4: - Add macros.h patch for ARRAY_SIZE - Based on v3 of Jan's "common: move a few macros out of xen/lib.h" - (head.S) Remove unnecessary '.section .init.data' - (head.S) Fixup spacing, remove unnecessary parens - (setup.c, processor.h) Fix style of HMT_very_low macro - (early_printk.c) Build early_printk.c as .init.o - (early_printk.c) Mark putchar_func as __initdata - (boot-of.c) Clarify original license in top comment - (boot-of.c) Add parens around ADDR macro definition - (boot-of.c) Add missing ADDR() for pointer arguments - (boot-of.c) Add comment explaining ADDR macro - (boot-of.c) Fix style (indentation, comment capitalization) - (boot-of.c) Fix type inconsistency in boot-of.c - (boot-of.c) Use ARRAY_SIZE instead of hard-coding nrets - (boot-of.c) Change bof_chosen variable to function-scope - (processor.h) Remove duplicate include - (processor.h) Remove unnecessary include - (processor.h) Move HMT_very_low macro to !defined(ASSEMBLY) block - (processor.h) Fixup struct cpu_user_regs comment style Changes in v3: - Set up r2 TOC pointer in start - Change indirect call to start_xen to a direct one - Use 32-bit constant loads for stack pointer, etc. in start - Our load address is < 4GB so this works fine - In a future series we'll get -fPIC working and change all of these immediate address loads to TOC-relative ones. - Move .bss initialization to patch 2 - Move cpu0_boot_stack declaration to setup.c - Bump stack size down to one page (64k), previous was way overkill. - Remove unnecessary STACK_FRAME_OVERHEAD component from of-call.S stack frame size calculation - Add assertion that `struct cpu_user_regs` is stack-aligned - Move magic `or 31,31,31` to appropriately-named macro - Fix formatting of loop in setup.c - Add newline in arch/ppc/Makefile to preserve alphabetical ordering per group - Rebase on staging, including the final version of 'xen/types: Rework stdint vs __{u,s}$N types' Changes in v2: - Split main patch into two - one for basic C environment setup and one for serial - Mark OpenFirmware functions and early_printk functions as __init and change boot-of.o to boot-of.init.o in Makefile - Change include to and drop skeleton headers that are no longer necessary for build as a result - Add loop to clear .bss before jumping to C environment that was accidentally excluded from the first series - Move common asm macros from processor.h to asm-defns.h - Change note in head.S about preserved registers to a multi-line comment so it's more noticeable - Drop reg-defs.h and use '%'-prefixed register names in assembly - This is necessary since -mregnames, which allows standard non-prefixed register names without manual macro definitions, is not supported by LLVM's assembler. - Drop inline asm swab routines in favor of __builtin_bswap family - Fix up types.h in accordance with (as of now, unmerged) 'xen/types: Rework stdint vs __{u,s}$N types' - Remove unnecessary braces for single-line statements - Remove unnecessary license text when SPDX header is present - Fix alphabetical ordering of object declarations in Makefile - Drop 'extern' from enter_of prototype, ensure prototypes have argument names Shawn Anastasio (4): common: Move a few more standalone macros from xen/lib.h to xen/macros.h xen/ppc: Set up a basic C environment xen/ppc: Implement early serial printk on pseries automation: Add smoke test for ppc64le automation/gitlab-ci/test.yaml | 20 automation/scripts/qemu-smoke-ppc64le.sh | 27 + xen/arch/ppc/Kconfig.debug | 5 + xen/arch/ppc/Makefile| 4 + xen/arch/ppc/boot-of.c | 113 +++ xen/arch/ppc/configs/ppc64_defconfig | 1 + xen/arch/ppc/early_printk.c | 28 + xen/arch/ppc/include/asm/asm-defns.h | 57 ++ xen/arch/ppc/include/asm/boot.h | 23 xen/arch/ppc/include/asm/byteorder.h | 12 ++ xen/arch/ppc/include/asm/config.h| 5 +-
[PATCH v4 4/4] automation: Add smoke test for ppc64le
Add an initial smoke test that boots xen on a ppc64/pseries machine and checks for a magic string. Based on the riscv smoke test. Eventually the powernv9 (POWER9 bare metal) machine type will want to be tested as well, but for now we only boot on pseries. Signed-off-by: Shawn Anastasio Reviewed-by: Stefano Stabellini --- automation/gitlab-ci/test.yaml | 20 ++ automation/scripts/qemu-smoke-ppc64le.sh | 27 2 files changed, 47 insertions(+) create mode 100755 automation/scripts/qemu-smoke-ppc64le.sh diff --git a/automation/gitlab-ci/test.yaml b/automation/gitlab-ci/test.yaml index d5cb238b0a..45e8ddb7a3 100644 --- a/automation/gitlab-ci/test.yaml +++ b/automation/gitlab-ci/test.yaml @@ -71,6 +71,19 @@ tags: - x86_64 +.qemu-ppc64le: + extends: .test-jobs-common + variables: +CONTAINER: debian:bullseye-ppc64le +LOGFILE: qemu-smoke-ppc64le.log + artifacts: +paths: + - smoke.serial + - '*.log' +when: always + tags: +- x86_64 + .xilinx-arm64: extends: .test-jobs-common variables: @@ -444,3 +457,10 @@ qemu-smoke-riscv64-gcc: - ./automation/scripts/qemu-smoke-riscv64.sh 2>&1 | tee ${LOGFILE} needs: - archlinux-current-gcc-riscv64-debug + +qemu-smoke-ppc64le-pseries-gcc: + extends: .qemu-ppc64le + script: +- ./automation/scripts/qemu-smoke-ppc64le.sh pseries-5.2 2>&1 | tee ${LOGFILE} + needs: +- debian-bullseye-gcc-ppc64le-debug diff --git a/automation/scripts/qemu-smoke-ppc64le.sh b/automation/scripts/qemu-smoke-ppc64le.sh new file mode 100755 index 00..eb55221221 --- /dev/null +++ b/automation/scripts/qemu-smoke-ppc64le.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +set -ex + +# machine type from first arg passed directly to qemu -M +machine=$1 + +# Run the test +rm -f smoke.serial +set +e + +touch smoke.serial + +timeout -k 1 20 \ +qemu-system-ppc64 \ +-M $machine \ +-m 2g \ +-smp 1 \ +-vga none \ +-monitor none \ +-nographic \ +-serial file:smoke.serial \ +-kernel binaries/xen + +set -e +(grep -q "Hello, ppc64le!" smoke.serial) || exit 1 +exit 0 -- 2.30.2
[PATCH v4 1/4] common: Move a few more standalone macros from xen/lib.h to xen/macros.h
Move a few more macros which have no dependencies on other headers from xen/lib.h to xen/macros.h. Notably, this includes BUILD_BUG_ON* and ARRAY_SIZE. --- xen/include/xen/lib.h| 28 xen/include/xen/macros.h | 32 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h index dae2a1f085..359cfdc784 100644 --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -21,24 +21,6 @@ unlikely(ret_warn_on_); \ }) -/* All clang versions supported by Xen have _Static_assert. */ -#if defined(__clang__) || \ -(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) -/* Force a compilation error if condition is true */ -#define BUILD_BUG_ON(cond) ({ _Static_assert(!(cond), "!(" #cond ")"); }) - -/* Force a compilation error if condition is true, but also produce a - result (of value 0 and type size_t), so the expression can be used - e.g. in a structure initializer (or where-ever else comma expressions - aren't permitted). */ -#define BUILD_BUG_ON_ZERO(cond) \ -(sizeof(struct { char c; _Static_assert(!(cond), "!(" #cond ")"); }) & 0) -#else -#define BUILD_BUG_ON_ZERO(cond) \ -(sizeof(struct { unsigned u : !(cond); }) & 0) -#define BUILD_BUG_ON(cond) ((void)BUILD_BUG_ON_ZERO(cond)) -#endif - #ifndef NDEBUG #define ASSERT(p) \ do { if ( unlikely(!(p)) ) assert_failed(#p); } while (0) @@ -48,16 +30,6 @@ #define ASSERT_UNREACHABLE() do { } while (0) #endif -#define ABS(_x) ({ \ -typeof(_x) __x = (_x); \ -(__x < 0) ? -__x : __x; \ -}) - -#define SWAP(_a, _b) \ - do { typeof(_a) _t = (_a); (_a) = (_b); (_b) = _t; } while ( 0 ) - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]) + __must_be_array(x)) - #define __ACCESS_ONCE(x) ({ \ (void)(typeof(x))0; /* Scalar typecheck. */ \ (volatile typeof(x) *)&(x); }) diff --git a/xen/include/xen/macros.h b/xen/include/xen/macros.h index 7b92d34504..e2832b0e8a 100644 --- a/xen/include/xen/macros.h +++ b/xen/include/xen/macros.h @@ -22,6 +22,38 @@ #define __STR(...) #__VA_ARGS__ #define STR(...) __STR(__VA_ARGS__) +#ifndef __ASSEMBLY__ + +/* All clang versions supported by Xen have _Static_assert. */ +#if defined(__clang__) || \ +(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +/* Force a compilation error if condition is true */ +#define BUILD_BUG_ON(cond) ({ _Static_assert(!(cond), "!(" #cond ")"); }) + +/* Force a compilation error if condition is true, but also produce a + result (of value 0 and type size_t), so the expression can be used + e.g. in a structure initializer (or where-ever else comma expressions + aren't permitted). */ +#define BUILD_BUG_ON_ZERO(cond) \ +(sizeof(struct { char c; _Static_assert(!(cond), "!(" #cond ")"); }) & 0) +#else +#define BUILD_BUG_ON_ZERO(cond) \ +(sizeof(struct { unsigned u : !(cond); }) & 0) +#define BUILD_BUG_ON(cond) ((void)BUILD_BUG_ON_ZERO(cond)) +#endif + +#define ABS(_x) ({ \ +typeof(_x) __x = (_x); \ +(__x < 0) ? -__x : __x; \ +}) + +#define SWAP(_a, _b) \ + do { typeof(_a) _t = (_a); (_a) = (_b); (_b) = _t; } while ( 0 ) + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]) + __must_be_array(x)) + +#endif /* __ASSEMBLY__ */ + #endif /* __MACROS_H__ */ /* -- 2.30.2
[PATCH v4 3/4] xen/ppc: Implement early serial printk on pseries
On typical Power VMs (e.g. QEMU's -M pseries), a variety of services including an early serial console are provided by Open Firmware. Implement the required interfaces to call into Open Firmware and write to the serial console. Since Open Firmware runs in 32-bit Big Endian mode and Xen runs in 64-bit Little Endian mode, a thunk is required to save/restore any potentially-clobbered registers as well as to perform the required endianness switch. Thankfully, linux already has such a routine, which was imported into ppc64/of-call.S. Support for bare metal (PowerNV) will be implemented in a future patch. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/Kconfig.debug | 5 + xen/arch/ppc/Makefile | 2 + xen/arch/ppc/boot-of.c | 113 +++ xen/arch/ppc/configs/ppc64_defconfig| 1 + xen/arch/ppc/early_printk.c | 28 + xen/arch/ppc/include/asm/asm-defns.h| 17 +++ xen/arch/ppc/include/asm/boot.h | 23 xen/arch/ppc/include/asm/byteorder.h| 12 +++ xen/arch/ppc/include/asm/config.h | 3 + xen/arch/ppc/include/asm/early_printk.h | 15 +++ xen/arch/ppc/include/asm/msr.h | 51 + xen/arch/ppc/include/asm/processor.h| 138 xen/arch/ppc/include/asm/types.h| 21 xen/arch/ppc/ppc64/Makefile | 1 + xen/arch/ppc/ppc64/asm-offsets.c| 59 ++ xen/arch/ppc/ppc64/head.S | 9 ++ xen/arch/ppc/ppc64/of-call.S| 83 ++ xen/arch/ppc/setup.c| 19 +++- 18 files changed, 597 insertions(+), 3 deletions(-) create mode 100644 xen/arch/ppc/boot-of.c create mode 100644 xen/arch/ppc/early_printk.c create mode 100644 xen/arch/ppc/include/asm/boot.h create mode 100644 xen/arch/ppc/include/asm/byteorder.h create mode 100644 xen/arch/ppc/include/asm/early_printk.h create mode 100644 xen/arch/ppc/include/asm/msr.h create mode 100644 xen/arch/ppc/include/asm/processor.h create mode 100644 xen/arch/ppc/include/asm/types.h create mode 100644 xen/arch/ppc/ppc64/of-call.S diff --git a/xen/arch/ppc/Kconfig.debug b/xen/arch/ppc/Kconfig.debug index e69de29bb2..608c9ff832 100644 --- a/xen/arch/ppc/Kconfig.debug +++ b/xen/arch/ppc/Kconfig.debug @@ -0,0 +1,5 @@ +config EARLY_PRINTK +bool "Enable early printk" +default DEBUG +help + Enables early printk debug messages diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile index 530fba2121..098a4dd0a9 100644 --- a/xen/arch/ppc/Makefile +++ b/xen/arch/ppc/Makefile @@ -1,5 +1,7 @@ obj-$(CONFIG_PPC64) += ppc64/ +obj-y += boot-of.init.o +obj-$(CONFIG_EARLY_PRINTK) += early_printk.init.o obj-y += setup.o $(TARGET): $(TARGET)-syms diff --git a/xen/arch/ppc/boot-of.c b/xen/arch/ppc/boot-of.c new file mode 100644 index 00..a06546871e --- /dev/null +++ b/xen/arch/ppc/boot-of.c @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * This file was derived from Xen 3.2's xen/arch/powerpc/boot_of.c, + * originally licensed under GPL version 2 or later. + * + * Copyright IBM Corp. 2005, 2006, 2007 + * Copyright Raptor Engineering, LLC + * + * Authors: Jimi Xenidis + * Hollis Blanchard + * Shawn Anastasio + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * The Open Firmware client interface is called in 32-bit mode with the MMU off, + * so any addresses passed to it must be physical addresses under 4GB. + * + * Since the client interface is only used during early boot before the MMU is on + * and Xen itself was loaded by Open Firmware (and therefore resides below 4GB), + * we can achieve the desired result with a simple cast to uint32_t. + */ +#define ADDR(x) ((uint32_t)(unsigned long)(x)) + +/* OF entrypoint*/ +static unsigned long __initdata of_vec; + +static int __initdata of_out; + +static int __init of_call(const char *service, uint32_t nargs, uint32_t nrets, + int32_t rets[], ...) +{ +int rc; +va_list args; +unsigned int i; +struct of_service s = { 0 }; + +s.ofs_service = cpu_to_be32(ADDR(service)); +s.ofs_nargs = cpu_to_be32(nargs); +s.ofs_nrets = cpu_to_be32(nrets); + +/* Copy all the params into the args array */ +va_start(args, rets); + +for ( i = 0; i < nargs; i++ ) +s.ofs_args[i] = cpu_to_be32(va_arg(args, uint32_t)); + +va_end(args); + +rc = enter_of(&s, of_vec); + +/* Copy all return values to the output rets array */ +for ( i = 0; i < nrets; i++ ) +rets[i] = be32_to_cpu(s.ofs_args[i + nargs]); + +return rc; +} + +static int __init of_finddevice(const char *devspec) +{ +int32_t rets[1] = { OF_FAILURE }; + +of_call("finddevice", 1, ARRAY_SIZE(rets), rets, ADDR(devspec)); +return rets[0]; +} + +static int __init of_getprop(int ph, const char *name, void *buf,
[PATCH v4 2/4] xen/ppc: Set up a basic C environment
Update ppc64/head.S to set up an initial boot stack, zero the .bss section, and jump to C. Also refactor the endian fixup trampoline into its own macro, since it will need to be used in multiple places, including every time we make a call into firmware (see next commit). Signed-off-by: Shawn Anastasio --- xen/arch/ppc/Makefile| 2 ++ xen/arch/ppc/include/asm/asm-defns.h | 40 xen/arch/ppc/include/asm/config.h| 2 +- xen/arch/ppc/ppc64/head.S| 38 +- xen/arch/ppc/setup.c | 19 + 5 files changed, 80 insertions(+), 21 deletions(-) create mode 100644 xen/arch/ppc/include/asm/asm-defns.h create mode 100644 xen/arch/ppc/setup.c diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile index 98220648af..530fba2121 100644 --- a/xen/arch/ppc/Makefile +++ b/xen/arch/ppc/Makefile @@ -1,5 +1,7 @@ obj-$(CONFIG_PPC64) += ppc64/ +obj-y += setup.o + $(TARGET): $(TARGET)-syms cp -f $< $@ diff --git a/xen/arch/ppc/include/asm/asm-defns.h b/xen/arch/ppc/include/asm/asm-defns.h new file mode 100644 index 00..6ea35f6edb --- /dev/null +++ b/xen/arch/ppc/include/asm/asm-defns.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _ASM_PPC_ASM_DEFNS_H +#define _ASM_PPC_ASM_DEFNS_H + +/* + * Load a 64-bit immediate value into the specified GPR. + */ +#define LOAD_IMM64(reg, val) \ +lis reg, (val) @highest; \ +ori reg, reg, (val) @higher; \ +rldicr reg, reg, 32, 31; \ +oris reg, reg, (val) @h; \ +ori reg, reg, (val) @l; + +#define LOAD_IMM32(reg, val) \ +lis reg, (val) @h; \ +ori reg, reg, (val) @l; \ + +/* + * Depending on how we were booted, the CPU could be running in either + * Little Endian or Big Endian mode. The following trampoline from Linux + * cleverly uses an instruction that encodes to a NOP if the CPU's + * endianness matches the assumption of the assembler (LE, in our case) + * or a branch to code that performs the endian switch in the other case. + */ +#define FIXUP_ENDIAN \ +tdi 0, 0, 0x48; /* Reverse endian of b . + 8 */ \ +b . + 44; /* Skip trampoline if endian is good */ \ +.long 0xa600607d; /* mfmsr r11 */ \ +.long 0x01006b69; /* xori r11,r11,1 */ \ +.long 0x4039; /* li r10,0 */ \ +.long 0x6401417d; /* mtmsrd r10,1 */ \ +.long 0x05009f42; /* bcl 20,31,$+4 */ \ +.long 0xa602487d; /* mflr r10 */ \ +.long 0x14004a39; /* addi r10,r10,20*/ \ +.long 0xa6035a7d; /* mtsrr0 r10 */ \ +.long 0xa6037b7d; /* mtsrr1 r11 */ \ +.long 0x244c /* rfid */ + +#endif /* _ASM_PPC_ASM_DEFNS_H */ diff --git a/xen/arch/ppc/include/asm/config.h b/xen/arch/ppc/include/asm/config.h index b9a6814f00..01ca5d0803 100644 --- a/xen/arch/ppc/include/asm/config.h +++ b/xen/arch/ppc/include/asm/config.h @@ -43,7 +43,7 @@ #define SMP_CACHE_BYTES (1 << 6) -#define STACK_ORDER 2 +#define STACK_ORDER 0 #define STACK_SIZE (PAGE_SIZE << STACK_ORDER) /* 288 bytes below the stack pointer must be preserved by interrupt handlers */ diff --git a/xen/arch/ppc/ppc64/head.S b/xen/arch/ppc/ppc64/head.S index 2fcefb40d8..17f4a3e19c 100644 --- a/xen/arch/ppc/ppc64/head.S +++ b/xen/arch/ppc/ppc64/head.S @@ -1,30 +1,28 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include + .section .text.header, "ax", %progbits ENTRY(start) /* - * Depending on how we were booted, the CPU could be running in either - * Little Endian or Big Endian mode. The following trampoline from Linux - * cleverly uses an instruction that encodes to a NOP if the CPU's - * endianness matches the assumption of the assembler (LE, in our case) - * or a branch to code that performs the endian switch in the other case. + * NOTE: argument registers (r3-r9) must be preserved until the C entrypoint */ -tdi 0, 0, 0x48/* Reverse endian of b . + 8 */ -b . + 44 /* Skip trampoline if endian is good */ -.long 0xa600607d /* mfmsr r11
Re: [PATCH v4 3/4] xen/ppc: Implement early serial printk on pseries
On 7/19/23 9:05 AM, Jan Beulich wrote: > Before you/we grow more assembly code, may I re-raise a request regarding > readability: I think it would be nice if operands started at a fixed column, > unless the insn mnemonic is unusually long. Where exactly to draw the line > is up to each archtecture; on x86 we use 8 positions from the start of the > mnemonic. There is quite a large variance in mnemonic length on ppc -- many common mnemonics only use 2 characters (e.g. ld, mr) while other common ones use 6+ (e.g. rldicr, the mtspr family, etc.). Enforcing a column size that's too short would make the longer mnemonics look misaligned and out of place, but using a longer column length (like 8) that can accommodate most common mnemonics adds too much space between short mnemonics and their arguments. That said if you still feel strongly about this then I am not strongly opposed to adding an 8-space column alignment. > Jan Thanks, Shawn
Re: [PATCH v4 3/4] xen/ppc: Implement early serial printk on pseries
On 7/19/23 9:05 AM, Jan Beulich wrote: > On 18.07.2023 22:20, Shawn Anastasio wrote: >> +void __init boot_of_init(unsigned long vec) >> +{ >> +int bof_chosen; >> + >> +of_vec = vec; >> + >> +/* Get a handle to the default console */ >> +bof_chosen = of_finddevice("/chosen"); >> +of_getprop(bof_chosen, "stdout", &of_out, sizeof(of_out)); >> +of_out = be32_to_cpu(of_out); > > Can any of these fail, and hence lead to ... These calls are allowed to fail, but their return value in those cases is well-defined (an invalid handle), so... > >> +early_printk_init(of_putchar); > > ... this better not getting invoked? this being invoked is fine even in those cases. It will just result in the invalid handle being passed to of_write and the firmware will refuse to service the writes. >> --- a/xen/arch/ppc/ppc64/asm-offsets.c >> +++ b/xen/arch/ppc/ppc64/asm-offsets.c >> @@ -0,0 +1,59 @@ >> +/* >> + * Generate definitions needed by assembly language modules. >> + * This code generates raw asm output which is post-processed >> + * to extract and format the required data. >> + */ >> + >> +#include >> + >> +#define DEFINE(_sym, _val) \ >> +asm volatile ("\n.ascii\"==>#define " #_sym " %0 /* " #_val " */<==\"" \ >> + : : "i" (_val) ) > > Nit: There's a blank missing after the opening paren, which will then want > the 2nd line to be indented by one more character. (Instead, as a matter of > your taste, you may omit the blank between the two colons.) Will fix. >> +#define BLANK()\ >> +asm volatile ( "\n.ascii\"==><==\"" : : ) >> +#define OFFSET(_sym, _str, _mem) \ >> +DEFINE(_sym, offsetof(_str, _mem)); >> + >> +/* base-2 logarithm */ >> +#define __L2(_x) (((_x) & 0x0002) ? 1 : 0) >> +#define __L4(_x) (((_x) & 0x000c) ? ( 2 + __L2( (_x)>> 2)) : __L2( _x)) >> +#define __L8(_x) (((_x) & 0x00f0) ? ( 4 + __L4( (_x)>> 4)) : __L4( _x)) >> +#define __L16(_x) (((_x) & 0xff00) ? ( 8 + __L8( (_x)>> 8)) : __L8( _x)) >> +#define LOG_2(_x) (((_x) & 0x) ? (16 + __L16((_x)>>16)) : __L16(_x)) >> + >> +void __dummy__(void) >> +{ >> +DEFINE(GPR_WIDTH, sizeof(unsigned long)); >> +DEFINE(FPR_WIDTH, sizeof(double)); >> + >> +OFFSET(UREGS_gprs, struct cpu_user_regs, gprs); >> +OFFSET(UREGS_r0, struct cpu_user_regs, gprs[0]); >> +OFFSET(UREGS_r1, struct cpu_user_regs, gprs[1]); >> +OFFSET(UREGS_r13, struct cpu_user_regs, gprs[13]); >> +OFFSET(UREGS_srr0, struct cpu_user_regs, srr0); >> +OFFSET(UREGS_srr1, struct cpu_user_regs, srr1); >> +OFFSET(UREGS_pc, struct cpu_user_regs, pc); >> +OFFSET(UREGS_msr, struct cpu_user_regs, msr); >> +OFFSET(UREGS_lr, struct cpu_user_regs, lr); >> +OFFSET(UREGS_ctr, struct cpu_user_regs, ctr); >> +OFFSET(UREGS_xer, struct cpu_user_regs, xer); >> +OFFSET(UREGS_hid4, struct cpu_user_regs, hid4); >> +OFFSET(UREGS_dar, struct cpu_user_regs, dar); >> +OFFSET(UREGS_dsisr, struct cpu_user_regs, dsisr); >> +OFFSET(UREGS_cr, struct cpu_user_regs, cr); >> +OFFSET(UREGS_fpscr, struct cpu_user_regs, fpscr); >> +DEFINE(UREGS_sizeof, sizeof(struct cpu_user_regs)); >> +} >> + >> +/* TODO: Replace with BUILD_BUG_ON + IS_ALIGNED once we can use >> */ >> +_Static_assert(sizeof(struct cpu_user_regs) % STACK_ALIGN == 0, >> + "struct cpu_user_regs not stack aligned!"); > > But patch 1 makes BUILD_BUG_ON() available now. Good point, will fix. >> --- /dev/null >> +++ b/xen/arch/ppc/ppc64/of-call.S >> @@ -0,0 +1,83 @@ >> +/* SPDX-License-Identifier: GPL-2.0-or-later */ >> +/* >> + * Adapted from Linux's arch/powerpc/kernel/entry_64.S, with the >> + * following copyright notice: >> + * >> + * PowerPC version >> + *Copyright (C) 1995-1996 Gary Thomas (g...@linuxppc.org) >> + * Rewritten by Cort Dougan (c...@cs.nmt.edu) for PReP >> + *Copyright (C) 1996 Cort Dougan >> + * Adapted for Power Macintosh by Paul Mackerras. >> + * Low-level exception handlers and MMU support >> + * rewritten by Paul Mackerras. >> + *Copyright (C) 1996 Paul Mackerras. >> + * MPC8xx modifications Copyright (C) 1997 Dan Malek (dma
[PATCH v5 1/4] common: Move a few more standalone macros from xen/lib.h to xen/macros.h
Move a few more macros which have no dependencies on other headers from xen/lib.h to xen/macros.h. Notably, this includes BUILD_BUG_ON* and ARRAY_SIZE. Signed-off-by: Shawn Anastasio Reviewed-by: Jan Beulich --- xen/include/xen/lib.h| 28 xen/include/xen/macros.h | 34 ++ 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h index dae2a1f085..359cfdc784 100644 --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -21,24 +21,6 @@ unlikely(ret_warn_on_); \ }) -/* All clang versions supported by Xen have _Static_assert. */ -#if defined(__clang__) || \ -(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) -/* Force a compilation error if condition is true */ -#define BUILD_BUG_ON(cond) ({ _Static_assert(!(cond), "!(" #cond ")"); }) - -/* Force a compilation error if condition is true, but also produce a - result (of value 0 and type size_t), so the expression can be used - e.g. in a structure initializer (or where-ever else comma expressions - aren't permitted). */ -#define BUILD_BUG_ON_ZERO(cond) \ -(sizeof(struct { char c; _Static_assert(!(cond), "!(" #cond ")"); }) & 0) -#else -#define BUILD_BUG_ON_ZERO(cond) \ -(sizeof(struct { unsigned u : !(cond); }) & 0) -#define BUILD_BUG_ON(cond) ((void)BUILD_BUG_ON_ZERO(cond)) -#endif - #ifndef NDEBUG #define ASSERT(p) \ do { if ( unlikely(!(p)) ) assert_failed(#p); } while (0) @@ -48,16 +30,6 @@ #define ASSERT_UNREACHABLE() do { } while (0) #endif -#define ABS(_x) ({ \ -typeof(_x) __x = (_x); \ -(__x < 0) ? -__x : __x; \ -}) - -#define SWAP(_a, _b) \ - do { typeof(_a) _t = (_a); (_a) = (_b); (_b) = _t; } while ( 0 ) - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]) + __must_be_array(x)) - #define __ACCESS_ONCE(x) ({ \ (void)(typeof(x))0; /* Scalar typecheck. */ \ (volatile typeof(x) *)&(x); }) diff --git a/xen/include/xen/macros.h b/xen/include/xen/macros.h index 7b92d34504..d0caae7db2 100644 --- a/xen/include/xen/macros.h +++ b/xen/include/xen/macros.h @@ -22,6 +22,40 @@ #define __STR(...) #__VA_ARGS__ #define STR(...) __STR(__VA_ARGS__) +#ifndef __ASSEMBLY__ + +/* All clang versions supported by Xen have _Static_assert. */ +#if defined(__clang__) || \ +(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +/* Force a compilation error if condition is true */ +#define BUILD_BUG_ON(cond) ({ _Static_assert(!(cond), "!(" #cond ")"); }) + +/* + * Force a compilation error if condition is true, but also produce a + * result (of value 0 and type size_t), so the expression can be used + * e.g. in a structure initializer (or where-ever else comma expressions + * aren't permitted). + */ +#define BUILD_BUG_ON_ZERO(cond) \ +(sizeof(struct { char c; _Static_assert(!(cond), "!(" #cond ")"); }) & 0) +#else +#define BUILD_BUG_ON_ZERO(cond) \ +(sizeof(struct { unsigned u : !(cond); }) & 0) +#define BUILD_BUG_ON(cond) ((void)BUILD_BUG_ON_ZERO(cond)) +#endif + +#define ABS(x) ({ \ +typeof(x) x_ = (x);\ +(x_ < 0) ? -x_ : x_; \ +}) + +#define SWAP(a, b) \ + do { typeof(a) t_ = (a); (a) = (b); (b) = t_; } while ( 0 ) + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]) + __must_be_array(x)) + +#endif /* __ASSEMBLY__ */ + #endif /* __MACROS_H__ */ /* -- 2.30.2
[PATCH v5 4/4] automation: Add smoke test for ppc64le
Add an initial smoke test that boots xen on a ppc64/pseries machine and checks for a magic string. Based on the riscv smoke test. Eventually the powernv9 (POWER9 bare metal) machine type will want to be tested as well, but for now we only boot on pseries. Signed-off-by: Shawn Anastasio Reviewed-by: Stefano Stabellini --- automation/gitlab-ci/test.yaml | 20 ++ automation/scripts/qemu-smoke-ppc64le.sh | 27 2 files changed, 47 insertions(+) create mode 100755 automation/scripts/qemu-smoke-ppc64le.sh diff --git a/automation/gitlab-ci/test.yaml b/automation/gitlab-ci/test.yaml index d5cb238b0a..45e8ddb7a3 100644 --- a/automation/gitlab-ci/test.yaml +++ b/automation/gitlab-ci/test.yaml @@ -71,6 +71,19 @@ tags: - x86_64 +.qemu-ppc64le: + extends: .test-jobs-common + variables: +CONTAINER: debian:bullseye-ppc64le +LOGFILE: qemu-smoke-ppc64le.log + artifacts: +paths: + - smoke.serial + - '*.log' +when: always + tags: +- x86_64 + .xilinx-arm64: extends: .test-jobs-common variables: @@ -444,3 +457,10 @@ qemu-smoke-riscv64-gcc: - ./automation/scripts/qemu-smoke-riscv64.sh 2>&1 | tee ${LOGFILE} needs: - archlinux-current-gcc-riscv64-debug + +qemu-smoke-ppc64le-pseries-gcc: + extends: .qemu-ppc64le + script: +- ./automation/scripts/qemu-smoke-ppc64le.sh pseries-5.2 2>&1 | tee ${LOGFILE} + needs: +- debian-bullseye-gcc-ppc64le-debug diff --git a/automation/scripts/qemu-smoke-ppc64le.sh b/automation/scripts/qemu-smoke-ppc64le.sh new file mode 100755 index 00..eb55221221 --- /dev/null +++ b/automation/scripts/qemu-smoke-ppc64le.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +set -ex + +# machine type from first arg passed directly to qemu -M +machine=$1 + +# Run the test +rm -f smoke.serial +set +e + +touch smoke.serial + +timeout -k 1 20 \ +qemu-system-ppc64 \ +-M $machine \ +-m 2g \ +-smp 1 \ +-vga none \ +-monitor none \ +-nographic \ +-serial file:smoke.serial \ +-kernel binaries/xen + +set -e +(grep -q "Hello, ppc64le!" smoke.serial) || exit 1 +exit 0 -- 2.30.2
[PATCH v5 2/4] xen/ppc: Set up a basic C environment
Update ppc64/head.S to set up an initial boot stack, zero the .bss section, and jump to C. The required setup is done using 32-bit immediate address loads for now, but they will be changed to TOC-relative loads once the position-independent code model is enabled. Additionally, move the cpu0_boot_stack declaration to setup.c and change STACK_ORDER from 2 to 0. For now, ppc64 is using 64k pages and thus the larger STACK_ORDER is unnecessary. Finally, refactor the endian fixup trampoline into its own macro, since it will need to be used in multiple places, including every time we make a call into firmware. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/Makefile| 2 ++ xen/arch/ppc/include/asm/asm-defns.h | 40 xen/arch/ppc/include/asm/config.h| 2 +- xen/arch/ppc/ppc64/head.S| 38 +- xen/arch/ppc/setup.c | 19 + 5 files changed, 80 insertions(+), 21 deletions(-) create mode 100644 xen/arch/ppc/include/asm/asm-defns.h create mode 100644 xen/arch/ppc/setup.c diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile index 98220648af..530fba2121 100644 --- a/xen/arch/ppc/Makefile +++ b/xen/arch/ppc/Makefile @@ -1,5 +1,7 @@ obj-$(CONFIG_PPC64) += ppc64/ +obj-y += setup.o + $(TARGET): $(TARGET)-syms cp -f $< $@ diff --git a/xen/arch/ppc/include/asm/asm-defns.h b/xen/arch/ppc/include/asm/asm-defns.h new file mode 100644 index 00..6ea35f6edb --- /dev/null +++ b/xen/arch/ppc/include/asm/asm-defns.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _ASM_PPC_ASM_DEFNS_H +#define _ASM_PPC_ASM_DEFNS_H + +/* + * Load a 64-bit immediate value into the specified GPR. + */ +#define LOAD_IMM64(reg, val) \ +lis reg, (val) @highest; \ +ori reg, reg, (val) @higher; \ +rldicr reg, reg, 32, 31; \ +oris reg, reg, (val) @h; \ +ori reg, reg, (val) @l; + +#define LOAD_IMM32(reg, val) \ +lis reg, (val) @h; \ +ori reg, reg, (val) @l; \ + +/* + * Depending on how we were booted, the CPU could be running in either + * Little Endian or Big Endian mode. The following trampoline from Linux + * cleverly uses an instruction that encodes to a NOP if the CPU's + * endianness matches the assumption of the assembler (LE, in our case) + * or a branch to code that performs the endian switch in the other case. + */ +#define FIXUP_ENDIAN \ +tdi 0, 0, 0x48; /* Reverse endian of b . + 8 */ \ +b . + 44; /* Skip trampoline if endian is good */ \ +.long 0xa600607d; /* mfmsr r11 */ \ +.long 0x01006b69; /* xori r11,r11,1 */ \ +.long 0x4039; /* li r10,0 */ \ +.long 0x6401417d; /* mtmsrd r10,1 */ \ +.long 0x05009f42; /* bcl 20,31,$+4 */ \ +.long 0xa602487d; /* mflr r10 */ \ +.long 0x14004a39; /* addi r10,r10,20*/ \ +.long 0xa6035a7d; /* mtsrr0 r10 */ \ +.long 0xa6037b7d; /* mtsrr1 r11 */ \ +.long 0x244c /* rfid */ + +#endif /* _ASM_PPC_ASM_DEFNS_H */ diff --git a/xen/arch/ppc/include/asm/config.h b/xen/arch/ppc/include/asm/config.h index b9a6814f00..01ca5d0803 100644 --- a/xen/arch/ppc/include/asm/config.h +++ b/xen/arch/ppc/include/asm/config.h @@ -43,7 +43,7 @@ #define SMP_CACHE_BYTES (1 << 6) -#define STACK_ORDER 2 +#define STACK_ORDER 0 #define STACK_SIZE (PAGE_SIZE << STACK_ORDER) /* 288 bytes below the stack pointer must be preserved by interrupt handlers */ diff --git a/xen/arch/ppc/ppc64/head.S b/xen/arch/ppc/ppc64/head.S index 2fcefb40d8..49b3066396 100644 --- a/xen/arch/ppc/ppc64/head.S +++ b/xen/arch/ppc/ppc64/head.S @@ -1,30 +1,28 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include + .section .text.header, "ax", %progbits ENTRY(start) /* - * Depending on how we were booted, the CPU could be running in either - * Little Endian or Big Endian mode. The following trampoline from Linux - * cleverly uses an instruction that encodes to a NOP if the CPU's - * endianness matches the assumption of the assembler (LE, in our case) - * or
[PATCH v5 0/4] Early serial on Power
Hello all, This series adds support for early serial printing on Power, as well as a simple CI smoke test modeled after the riscv one. The first patch is responsible for setting up a basic C environment with an initial stack while the second sets up an Open Firmware serial console and primitive early_printk infrastructure. This will currently only run on QEMU pseries VMs, since the firmware interface on bare metal differs significantly. Support for bare metal will be added in a future series along with support for the position-independent code model. Thanks, Shawn -- Changes in v5: - (xen/macros.h) Add signoff - (xen/macros.h) Fix up comment formatting and macro parameter names - (*.S) Use 8-space column alignment for assembly - (of-call.S) Add missing space after comma - (asm-offsets.c) Fix DEFINE() macro formatting - (asm-offsets.c) Replace _Static_assert with BUILD_BUG_ON Changes in v4: - Add macros.h patch for ARRAY_SIZE - Based on v3 of Jan's "common: move a few macros out of xen/lib.h" - (head.S) Remove unnecessary '.section .init.data' - (head.S) Fixup spacing, remove unnecessary parens - (setup.c, processor.h) Fix style of HMT_very_low macro - (early_printk.c) Build early_printk.c as .init.o - (early_printk.c) Mark putchar_func as __initdata - (boot-of.c) Clarify original license in top comment - (boot-of.c) Add parens around ADDR macro definition - (boot-of.c) Add missing ADDR() for pointer arguments - (boot-of.c) Add comment explaining ADDR macro - (boot-of.c) Fix style (indentation, comment capitalization) - (boot-of.c) Fix type inconsistency in boot-of.c - (boot-of.c) Use ARRAY_SIZE instead of hard-coding nrets - (boot-of.c) Change bof_chosen variable to function-scope - (processor.h) Remove duplicate include - (processor.h) Remove unnecessary include - (processor.h) Move HMT_very_low macro to !defined(ASSEMBLY) block - (processor.h) Fixup struct cpu_user_regs comment style Changes in v3: - Set up r2 TOC pointer in start - Change indirect call to start_xen to a direct one - Use 32-bit constant loads for stack pointer, etc. in start - Our load address is < 4GB so this works fine - In a future series we'll get -fPIC working and change all of these immediate address loads to TOC-relative ones. - Move .bss initialization to patch 2 - Move cpu0_boot_stack declaration to setup.c - Bump stack size down to one page (64k), previous was way overkill. - Remove unnecessary STACK_FRAME_OVERHEAD component from of-call.S stack frame size calculation - Add assertion that `struct cpu_user_regs` is stack-aligned - Move magic `or 31,31,31` to appropriately-named macro - Fix formatting of loop in setup.c - Add newline in arch/ppc/Makefile to preserve alphabetical ordering per group - Rebase on staging, including the final version of 'xen/types: Rework stdint vs __{u,s}$N types' Changes in v2: - Split main patch into two - one for basic C environment setup and one for serial - Mark OpenFirmware functions and early_printk functions as __init and change boot-of.o to boot-of.init.o in Makefile - Change include to and drop skeleton headers that are no longer necessary for build as a result - Add loop to clear .bss before jumping to C environment that was accidentally excluded from the first series - Move common asm macros from processor.h to asm-defns.h - Change note in head.S about preserved registers to a multi-line comment so it's more noticeable - Drop reg-defs.h and use '%'-prefixed register names in assembly - This is necessary since -mregnames, which allows standard non-prefixed register names without manual macro definitions, is not supported by LLVM's assembler. - Drop inline asm swab routines in favor of __builtin_bswap family - Fix up types.h in accordance with (as of now, unmerged) 'xen/types: Rework stdint vs __{u,s}$N types' - Remove unnecessary braces for single-line statements - Remove unnecessary license text when SPDX header is present - Fix alphabetical ordering of object declarations in Makefile - Drop 'extern' from enter_of prototype, ensure prototypes have argument names Shawn Anastasio (4): common: Move a few more standalone macros from xen/lib.h to xen/macros.h xen/ppc: Set up a basic C environment xen/ppc: Implement early serial printk on pseries automation: Add smoke test for ppc64le automation/gitlab-ci/test.yaml | 20 automation/scripts/qemu-smoke-ppc64le.sh | 27 + xen/arch/ppc/Kconfig.debug | 5 + xen/arch/ppc/Makefile| 4 + xen/arch/ppc/boot-of.c | 113 +++ xen/arch/ppc/configs/ppc64_defconfig | 1 + xen/arch/ppc/early_printk.c | 28 + xen/arch/ppc/include/asm/asm-defns.h | 57 ++
[PATCH v5 3/4] xen/ppc: Implement early serial printk on pseries
On typical Power VMs (e.g. QEMU's -M pseries), a variety of services including an early serial console are provided by Open Firmware. Implement the required interfaces to call into Open Firmware and write to the serial console. Since Open Firmware runs in 32-bit Big Endian mode and Xen runs in 64-bit Little Endian mode, a thunk is required to save/restore any potentially-clobbered registers as well as to perform the required endianness switch. Thankfully, linux already has such a routine, which was imported into ppc64/of-call.S. Support for bare metal (PowerNV) will be implemented in a future patch. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/Kconfig.debug | 5 + xen/arch/ppc/Makefile | 2 + xen/arch/ppc/boot-of.c | 113 +++ xen/arch/ppc/configs/ppc64_defconfig| 1 + xen/arch/ppc/early_printk.c | 28 + xen/arch/ppc/include/asm/asm-defns.h| 17 +++ xen/arch/ppc/include/asm/boot.h | 23 xen/arch/ppc/include/asm/byteorder.h| 12 +++ xen/arch/ppc/include/asm/config.h | 3 + xen/arch/ppc/include/asm/early_printk.h | 15 +++ xen/arch/ppc/include/asm/msr.h | 51 + xen/arch/ppc/include/asm/processor.h| 138 xen/arch/ppc/include/asm/types.h| 21 xen/arch/ppc/ppc64/Makefile | 1 + xen/arch/ppc/ppc64/asm-offsets.c| 58 ++ xen/arch/ppc/ppc64/head.S | 9 ++ xen/arch/ppc/ppc64/of-call.S| 83 ++ xen/arch/ppc/setup.c| 19 +++- 18 files changed, 596 insertions(+), 3 deletions(-) create mode 100644 xen/arch/ppc/boot-of.c create mode 100644 xen/arch/ppc/early_printk.c create mode 100644 xen/arch/ppc/include/asm/boot.h create mode 100644 xen/arch/ppc/include/asm/byteorder.h create mode 100644 xen/arch/ppc/include/asm/early_printk.h create mode 100644 xen/arch/ppc/include/asm/msr.h create mode 100644 xen/arch/ppc/include/asm/processor.h create mode 100644 xen/arch/ppc/include/asm/types.h create mode 100644 xen/arch/ppc/ppc64/of-call.S diff --git a/xen/arch/ppc/Kconfig.debug b/xen/arch/ppc/Kconfig.debug index e69de29bb2..608c9ff832 100644 --- a/xen/arch/ppc/Kconfig.debug +++ b/xen/arch/ppc/Kconfig.debug @@ -0,0 +1,5 @@ +config EARLY_PRINTK +bool "Enable early printk" +default DEBUG +help + Enables early printk debug messages diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile index 530fba2121..098a4dd0a9 100644 --- a/xen/arch/ppc/Makefile +++ b/xen/arch/ppc/Makefile @@ -1,5 +1,7 @@ obj-$(CONFIG_PPC64) += ppc64/ +obj-y += boot-of.init.o +obj-$(CONFIG_EARLY_PRINTK) += early_printk.init.o obj-y += setup.o $(TARGET): $(TARGET)-syms diff --git a/xen/arch/ppc/boot-of.c b/xen/arch/ppc/boot-of.c new file mode 100644 index 00..a06546871e --- /dev/null +++ b/xen/arch/ppc/boot-of.c @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * This file was derived from Xen 3.2's xen/arch/powerpc/boot_of.c, + * originally licensed under GPL version 2 or later. + * + * Copyright IBM Corp. 2005, 2006, 2007 + * Copyright Raptor Engineering, LLC + * + * Authors: Jimi Xenidis + * Hollis Blanchard + * Shawn Anastasio + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * The Open Firmware client interface is called in 32-bit mode with the MMU off, + * so any addresses passed to it must be physical addresses under 4GB. + * + * Since the client interface is only used during early boot before the MMU is on + * and Xen itself was loaded by Open Firmware (and therefore resides below 4GB), + * we can achieve the desired result with a simple cast to uint32_t. + */ +#define ADDR(x) ((uint32_t)(unsigned long)(x)) + +/* OF entrypoint*/ +static unsigned long __initdata of_vec; + +static int __initdata of_out; + +static int __init of_call(const char *service, uint32_t nargs, uint32_t nrets, + int32_t rets[], ...) +{ +int rc; +va_list args; +unsigned int i; +struct of_service s = { 0 }; + +s.ofs_service = cpu_to_be32(ADDR(service)); +s.ofs_nargs = cpu_to_be32(nargs); +s.ofs_nrets = cpu_to_be32(nrets); + +/* Copy all the params into the args array */ +va_start(args, rets); + +for ( i = 0; i < nargs; i++ ) +s.ofs_args[i] = cpu_to_be32(va_arg(args, uint32_t)); + +va_end(args); + +rc = enter_of(&s, of_vec); + +/* Copy all return values to the output rets array */ +for ( i = 0; i < nrets; i++ ) +rets[i] = be32_to_cpu(s.ofs_args[i + nargs]); + +return rc; +} + +static int __init of_finddevice(const char *devspec) +{ +int32_t rets[1] = { OF_FAILURE }; + +of_call("finddevice", 1, ARRAY_SIZE(rets), rets, ADDR(devspec)); +return rets[0]; +} + +static int __init of_getprop(int ph, const char *name, void *buf,
Re: [PATCH v5 3/4] xen/ppc: Implement early serial printk on pseries
On 7/24/23 7:40 AM, Jan Beulich wrote: > On 21.07.2023 19:02, Shawn Anastasio wrote: >> On typical Power VMs (e.g. QEMU's -M pseries), a variety of services >> including an early serial console are provided by Open Firmware. >> Implement the required interfaces to call into Open Firmware and write >> to the serial console. >> >> Since Open Firmware runs in 32-bit Big Endian mode and Xen runs in >> 64-bit Little Endian mode, a thunk is required to save/restore >> any potentially-clobbered registers as well as to perform the >> required endianness switch. Thankfully, linux already has such >> a routine, which was imported into ppc64/of-call.S. >> >> Support for bare metal (PowerNV) will be implemented in a future >> patch. >> >> Signed-off-by: Shawn Anastasio > > While I've committed the earlier two patches, I had to back out this > one. In my environment (gcc13) the build fails due an unresolved > reference to memset() out of boot-of.c (supposedly from of_call()). Does removing the `{ 0 }` initializer to `struct of_service s` on line 43 resolve this? > Jan Thanks, Shawn
Re: [PATCH v5 3/4] xen/ppc: Implement early serial printk on pseries
On 7/26/23 10:32 AM, Jan Beulich wrote: > On 24.07.2023 17:06, Shawn Anastasio wrote: >> On 7/24/23 7:40 AM, Jan Beulich wrote: >>> On 21.07.2023 19:02, Shawn Anastasio wrote: >>>> On typical Power VMs (e.g. QEMU's -M pseries), a variety of services >>>> including an early serial console are provided by Open Firmware. >>>> Implement the required interfaces to call into Open Firmware and write >>>> to the serial console. >>>> >>>> Since Open Firmware runs in 32-bit Big Endian mode and Xen runs in >>>> 64-bit Little Endian mode, a thunk is required to save/restore >>>> any potentially-clobbered registers as well as to perform the >>>> required endianness switch. Thankfully, linux already has such >>>> a routine, which was imported into ppc64/of-call.S. >>>> >>>> Support for bare metal (PowerNV) will be implemented in a future >>>> patch. >>>> >>>> Signed-off-by: Shawn Anastasio >>> >>> While I've committed the earlier two patches, I had to back out this >>> one. In my environment (gcc13) the build fails due an unresolved >>> reference to memset() out of boot-of.c (supposedly from of_call()). >> >> Does removing the `{ 0 }` initializer to `struct of_service s` on line >> 43 resolve this? > > Yes, that's what's causing the call (and removing, whether or not correct, > helps). Thanks for confirming. Removing it should be fine since the code manually initializes all of the other fields of the struct. The only behavioral difference is that the members of `ofs_args` at indices >= nargs would be left uninitialized. This shouldn't be an issue though since we're guarding reads of the array on `nargs` and `nrets` and thus only read explicitly initialized values (and of course, firmware would do the same). Naturally we can't avoid memset calls forever. I have lib/ building locally, but if we could get this series in without having to make those changes here that'd be great. > Jan Thanks, Shawn
Re: [PATCH v5 3/4] xen/ppc: Implement early serial printk on pseries
On 7/26/23 10:45 AM, Jan Beulich wrote: > On 26.07.2023 17:42, Shawn Anastasio wrote: >> On 7/26/23 10:32 AM, Jan Beulich wrote: >>> On 24.07.2023 17:06, Shawn Anastasio wrote: >>>> On 7/24/23 7:40 AM, Jan Beulich wrote: >>>>> On 21.07.2023 19:02, Shawn Anastasio wrote: >>>>>> On typical Power VMs (e.g. QEMU's -M pseries), a variety of services >>>>>> including an early serial console are provided by Open Firmware. >>>>>> Implement the required interfaces to call into Open Firmware and write >>>>>> to the serial console. >>>>>> >>>>>> Since Open Firmware runs in 32-bit Big Endian mode and Xen runs in >>>>>> 64-bit Little Endian mode, a thunk is required to save/restore >>>>>> any potentially-clobbered registers as well as to perform the >>>>>> required endianness switch. Thankfully, linux already has such >>>>>> a routine, which was imported into ppc64/of-call.S. >>>>>> >>>>>> Support for bare metal (PowerNV) will be implemented in a future >>>>>> patch. >>>>>> >>>>>> Signed-off-by: Shawn Anastasio >>>>> >>>>> While I've committed the earlier two patches, I had to back out this >>>>> one. In my environment (gcc13) the build fails due an unresolved >>>>> reference to memset() out of boot-of.c (supposedly from of_call()). >>>> >>>> Does removing the `{ 0 }` initializer to `struct of_service s` on line >>>> 43 resolve this? >>> >>> Yes, that's what's causing the call (and removing, whether or not correct, >>> helps). >> >> Thanks for confirming. Removing it should be fine since the code >> manually initializes all of the other fields of the struct. The only >> behavioral difference is that the members of `ofs_args` at indices >= >> nargs would be left uninitialized. This shouldn't be an issue though >> since we're guarding reads of the array on `nargs` and `nrets` and thus >> only read explicitly initialized values (and of course, firmware would >> do the same). >> >> Naturally we can't avoid memset calls forever. I have lib/ building >> locally, but if we could get this series in without having to make those >> changes here that'd be great. > > Are you suggesting I should put in this patch almost as is, with just > that initializer dropped? Yes. I've tested the change locally and it still behaves correctly, so if dropping it removes the memset invocation on your toolchain then I'd say the patch is fine to go with that initializer dropped. I could also submit a v6 with the initializer dropped, if you'd be more comfortable with that. > Jan Thanks, Shawn
[PATCH 4/5] xen/ppc: Parse device tree for OPAL node on PowerNV
Communication with firmware boot services on PowerNV requires parsing the fdt blob passed by the bootloader in order to obtain the firmware entrypoint. Use Xen's libfdt to do this and store the information required for firmware calls, to be implemented in a future patch. The full xen/common build doesn't yet work, but libfdt and its xen/lib dependency can be made to build by defining a few stub headers. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/Kconfig | 1 + xen/arch/ppc/Makefile| 1 + xen/arch/ppc/arch.mk | 4 +-- xen/arch/ppc/include/asm/boot.h | 16 +- xen/arch/ppc/include/asm/bug.h | 18 +++ xen/arch/ppc/include/asm/cache.h | 6 xen/arch/ppc/include/asm/processor.h | 13 +++- xen/arch/ppc/include/asm/string.h| 6 xen/arch/ppc/include/asm/system.h| 6 xen/arch/ppc/opal.c | 48 xen/arch/ppc/setup.c | 9 -- 11 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 xen/arch/ppc/include/asm/bug.h create mode 100644 xen/arch/ppc/include/asm/cache.h create mode 100644 xen/arch/ppc/include/asm/string.h create mode 100644 xen/arch/ppc/include/asm/system.h create mode 100644 xen/arch/ppc/opal.c diff --git a/xen/arch/ppc/Kconfig b/xen/arch/ppc/Kconfig index a2ade2ecf4..b32dce39b8 100644 --- a/xen/arch/ppc/Kconfig +++ b/xen/arch/ppc/Kconfig @@ -1,5 +1,6 @@ config PPC def_bool y + select HAS_DEVICE_TREE config PPC64 def_bool y diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile index 098a4dd0a9..0c0a7884a1 100644 --- a/xen/arch/ppc/Makefile +++ b/xen/arch/ppc/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_PPC64) += ppc64/ obj-y += boot-of.init.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.init.o +obj-y += opal.o obj-y += setup.o $(TARGET): $(TARGET)-syms diff --git a/xen/arch/ppc/arch.mk b/xen/arch/ppc/arch.mk index 0183b9ac6a..9f66f7a57b 100644 --- a/xen/arch/ppc/arch.mk +++ b/xen/arch/ppc/arch.mk @@ -10,5 +10,5 @@ CFLAGS += -mstrict-align -mcmodel=medium -mabi=elfv2 -fPIC -mno-altivec -mno-vsx LDFLAGS += -m elf64lppc # TODO: Drop override when more of the build is working -override ALL_OBJS-y = arch/$(SRCARCH)/built_in.o -override ALL_LIBS-y = +override ALL_OBJS-y = arch/$(SRCARCH)/built_in.o common/libfdt/built_in.o lib/built_in.o +override ALL_LIBS-y = lib/lib.a diff --git a/xen/arch/ppc/include/asm/boot.h b/xen/arch/ppc/include/asm/boot.h index 9b8a7c43c2..296539cd9e 100644 --- a/xen/arch/ppc/include/asm/boot.h +++ b/xen/arch/ppc/include/asm/boot.h @@ -4,7 +4,10 @@ #include -/* a collection of interfaces used during boot. */ +/* + * OpenFirmware boot interfaces + */ + enum { OF_FAILURE = -1, OF_SUCCESS = 0, @@ -20,4 +23,15 @@ struct of_service { int enter_of(struct of_service *args, unsigned long entry); void boot_of_init(unsigned long vec); +/* + * OPAL boot interfaces + */ + +struct opal { +uint64_t base; +uint64_t entry; +}; + +void boot_opal_init(const void *fdt); + #endif /* _ASM_PPC_BOOT_H */ diff --git a/xen/arch/ppc/include/asm/bug.h b/xen/arch/ppc/include/asm/bug.h new file mode 100644 index 00..e5e874b31c --- /dev/null +++ b/xen/arch/ppc/include/asm/bug.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ASM_PPC_BUG_H +#define _ASM_PPC_BUG_H + +#include + +/* + * Power ISA guarantees that an instruction consisting of all zeroes is + * illegal. + */ +#define BUG_OPCODE 0x + +#define BUG_INSTR ".long " __stringify(BUG_OPCODE) + +#define BUG_FN_REG r0 + +#endif /* _ASM_PPC_BUG_H */ diff --git a/xen/arch/ppc/include/asm/cache.h b/xen/arch/ppc/include/asm/cache.h new file mode 100644 index 00..8a0a6b7b17 --- /dev/null +++ b/xen/arch/ppc/include/asm/cache.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ASM_PPC_CACHE_H +#define _ASM_PPC_CACHE_H + +#endif /* _ASM_PPC_CACHE_H */ diff --git a/xen/arch/ppc/include/asm/processor.h b/xen/arch/ppc/include/asm/processor.h index 838d279508..2300640787 100644 --- a/xen/arch/ppc/include/asm/processor.h +++ b/xen/arch/ppc/include/asm/processor.h @@ -133,6 +133,17 @@ struct cpu_user_regs uint32_t entry_vector; }; -#endif +/* + * panic() isn't available at the moment so an infinite loop will be + * used temporarily. + * TODO: change it to panic() + */ +static inline void noreturn die(void) +{ +for ( ; ; ) +HMT_very_low(); +} + +#endif /* __ASSEMBLY__ */ #endif /* _ASM_PPC_PROCESSOR_H */ diff --git a/xen/arch/ppc/include/asm/string.h b/xen/arch/ppc/include/asm/string.h new file mode 100644 index 00..7a420e05e4 --- /dev/null +++ b/xen/arch/ppc/include/asm/string.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ASM_PPC_STRING_H +#define _ASM_PPC_STRING_H + +#endif /* _ASM_PPC_STRING_H */ diff --git a/xen/arch/ppc/include/asm/system.h b
[PATCH 0/5] xen/ppc: Add PowerNV bare metal support
Hello all, This series adds support for booting and using the serial console on bare metal PowerNV/OpenPOWER systems. Up until now, Xen could only be booted on the QEMU pseries model, which was initially targetted for ease of development, but which differs significantly from the bare metal systems where this port is likely to be the most useful. In addition to adding support for the PowerNV boot protocol and firmware interface, changes required to get libfdt from xen/libfdt building are included. This is required to obtain the firmware entrypoint address on PowerNV. Thanks, Shawn Shawn Anastasio (5): xen/lib: Move simple_strtoul from common/vsprintf.c to lib xen/ppc: Switch to medium PIC code model xen/ppc: Add OPAL API definition header file xen/ppc: Parse device tree for OPAL node on PowerNV xen/ppc: Implement early serial console on PowerNV xen/arch/ppc/Kconfig |1 + xen/arch/ppc/Makefile|1 + xen/arch/ppc/arch.mk |6 +- xen/arch/ppc/include/asm/asm-defns.h | 19 + xen/arch/ppc/include/asm/boot.h | 16 +- xen/arch/ppc/include/asm/bug.h | 18 + xen/arch/ppc/include/asm/cache.h |6 + xen/arch/ppc/include/asm/config.h|2 +- xen/arch/ppc/include/asm/opal-api.h | 1190 ++ xen/arch/ppc/include/asm/processor.h | 13 +- xen/arch/ppc/include/asm/string.h|6 + xen/arch/ppc/include/asm/system.h|6 + xen/arch/ppc/opal.c | 73 ++ xen/arch/ppc/ppc64/Makefile |1 + xen/arch/ppc/ppc64/asm-offsets.c |4 + xen/arch/ppc/ppc64/head.S| 13 +- xen/arch/ppc/ppc64/opal-calls.S | 82 ++ xen/arch/ppc/setup.c |9 +- xen/arch/ppc/xen.lds.S | 44 +- xen/common/vsprintf.c| 37 - xen/lib/Makefile |1 + xen/lib/simple_strtoul.c | 40 + 22 files changed, 1511 insertions(+), 77 deletions(-) create mode 100644 xen/arch/ppc/include/asm/bug.h create mode 100644 xen/arch/ppc/include/asm/cache.h create mode 100644 xen/arch/ppc/include/asm/opal-api.h create mode 100644 xen/arch/ppc/include/asm/string.h create mode 100644 xen/arch/ppc/include/asm/system.h create mode 100644 xen/arch/ppc/opal.c create mode 100644 xen/arch/ppc/ppc64/opal-calls.S create mode 100644 xen/lib/simple_strtoul.c -- 2.30.2
[PATCH 5/5] xen/ppc: Implement early serial console on PowerNV
Implement the OPAL firmware calls required to write to the serial console on PowerNV systems. Unlike pseries/Open Firmware, the OPAL firmware interface can be used past early boot and as such the relevant functions are not marked as __init. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/include/asm/asm-defns.h | 12 xen/arch/ppc/opal.c | 27 - xen/arch/ppc/ppc64/Makefile | 1 + xen/arch/ppc/ppc64/asm-offsets.c | 4 ++ xen/arch/ppc/ppc64/opal-calls.S | 82 5 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 xen/arch/ppc/ppc64/opal-calls.S diff --git a/xen/arch/ppc/include/asm/asm-defns.h b/xen/arch/ppc/include/asm/asm-defns.h index 5821f9024d..54d578ea3b 100644 --- a/xen/arch/ppc/include/asm/asm-defns.h +++ b/xen/arch/ppc/include/asm/asm-defns.h @@ -23,6 +23,18 @@ addis reg,%r2,name@toc@ha; \ addi reg,reg,name@toc@l +/* + * Declare a global assembly function with a proper TOC setup prologue + */ +#define _GLOBAL_TOC(name) \ +.balign 4; \ +.type name,@function; \ +.globl name;\ +name: \ +0: addis %r2,%r12,(.TOC.-0b)@ha; \ +addi %r2,%r2,(.TOC.-0b)@l; \ +.localentry name,.-name + /* * Depending on how we were booted, the CPU could be running in either * Little Endian or Big Endian mode. The following trampoline from Linux diff --git a/xen/arch/ppc/opal.c b/xen/arch/ppc/opal.c index 251de8ac23..cc75ccfcbe 100644 --- a/xen/arch/ppc/opal.c +++ b/xen/arch/ppc/opal.c @@ -8,9 +8,28 @@ #include #include -/* Global OPAL struct containing entrypoint and base */ +/* Global OPAL struct containing entrypoint and base used by opal-calls.S */ struct opal opal; +int64_t opal_console_write(int64_t term_number, uint64_t *length, + uint8_t *buffer); +int64_t opal_console_flush(int64_t term_number); +int64_t opal_reinit_cpus(uint64_t flags); + +static void opal_putchar(char c) +{ +uint64_t len; +if (c == '\n') +{ +char buf = '\r'; +len = cpu_to_be64(1); +opal_console_write(0, &len, (uint8_t *) &buf); +} +len = cpu_to_be64(1); +opal_console_write(0, &len, (uint8_t *) &c); +opal_console_flush(0); +} + void __init boot_opal_init(const void *fdt) { int opal_node; @@ -45,4 +64,10 @@ void __init boot_opal_init(const void *fdt) opal.base = be64_to_cpu(*opal_base); opal.entry = be64_to_cpu(*opal_entry); + +early_printk_init(opal_putchar); + +/* Ask OPAL to set HID0 for Little Endian interrupts + Radix TLB support */ +opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_LE | OPAL_REINIT_CPUS_MMU_RADIX + | OPAL_REINIT_CPUS_MMU_HASH); } diff --git a/xen/arch/ppc/ppc64/Makefile b/xen/arch/ppc/ppc64/Makefile index f4956daaa9..b9a91dc15f 100644 --- a/xen/arch/ppc/ppc64/Makefile +++ b/xen/arch/ppc/ppc64/Makefile @@ -1,2 +1,3 @@ obj-y += head.o obj-y += of-call.o +obj-y += opal-calls.o diff --git a/xen/arch/ppc/ppc64/asm-offsets.c b/xen/arch/ppc/ppc64/asm-offsets.c index e1129cb0f4..c15c1bf136 100644 --- a/xen/arch/ppc/ppc64/asm-offsets.c +++ b/xen/arch/ppc/ppc64/asm-offsets.c @@ -6,6 +6,7 @@ #include #include +#include #define DEFINE(_sym, _val) \ asm volatile ( "\n.ascii\"==>#define " #_sym " %0 /* " #_val " */<==\"" \ @@ -46,6 +47,9 @@ void __dummy__(void) OFFSET(UREGS_cr, struct cpu_user_regs, cr); OFFSET(UREGS_fpscr, struct cpu_user_regs, fpscr); DEFINE(UREGS_sizeof, sizeof(struct cpu_user_regs)); + +OFFSET(OPAL_base, struct opal, base); +OFFSET(OPAL_entry, struct opal, entry); } /* diff --git a/xen/arch/ppc/ppc64/opal-calls.S b/xen/arch/ppc/ppc64/opal-calls.S new file mode 100644 index 00..f754308725 --- /dev/null +++ b/xen/arch/ppc/ppc64/opal-calls.S @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Adapted from Linux's arch/powerpc/boot/opal-calls.S + * + * Copyright (c) 2016 IBM Corporation. + * Copyright Raptor Engineering, LLC + */ + +#include +#include +#include +#include + +.text + +#define OPAL_CALL(name, token) \ +.globl name;\ +name: \ +li %r0, token; \ +b opal_call; + + _GLOBAL_TOC(opal_call) +/* Back up LR, CR, r2 in caller's stack frame */ +mflr%r11 +mfcr%r12 +std %r2, 24(%r1) +std %r11, 16(%r1) +stw %
[PATCH 2/5] xen/ppc: Switch to medium PIC code model
Switch Xen to the medium PIC code model on Power. Among other things, this allows us to be load address agnostic and will open the door to booting on bare metal PowerNV systems that don't use OpenFirmware. Also update XEN_VIRT_START to 0xc000, which is equivalent to address 0x0 when the MMU is off. This prevents Open Firmware from loading Xen at an offset from its base load address, so the DECL_SECTION hack in xen.lds.S is no longer required. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/arch.mk | 2 +- xen/arch/ppc/include/asm/asm-defns.h | 7 + xen/arch/ppc/include/asm/config.h| 2 +- xen/arch/ppc/ppc64/head.S| 13 +--- xen/arch/ppc/xen.lds.S | 44 ++-- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/xen/arch/ppc/arch.mk b/xen/arch/ppc/arch.mk index 7eec22c283..0183b9ac6a 100644 --- a/xen/arch/ppc/arch.mk +++ b/xen/arch/ppc/arch.mk @@ -5,7 +5,7 @@ ppc-march-$(CONFIG_POWER_ISA_2_07B) := power8 ppc-march-$(CONFIG_POWER_ISA_3_00) := power9 CFLAGS += -m64 -mlittle-endian -mcpu=$(ppc-march-y) -CFLAGS += -mstrict-align -mcmodel=large -mabi=elfv2 -mno-altivec -mno-vsx +CFLAGS += -mstrict-align -mcmodel=medium -mabi=elfv2 -fPIC -mno-altivec -mno-vsx -msoft-float LDFLAGS += -m elf64lppc diff --git a/xen/arch/ppc/include/asm/asm-defns.h b/xen/arch/ppc/include/asm/asm-defns.h index 35b1c89d4e..5821f9024d 100644 --- a/xen/arch/ppc/include/asm/asm-defns.h +++ b/xen/arch/ppc/include/asm/asm-defns.h @@ -16,6 +16,13 @@ lis reg, (val) @h; \ ori reg, reg, (val) @l; \ +/* + * Load the address of a symbol from the TOC into the specified GPR. + */ +#define LOAD_REG_ADDR(reg,name) \ +addis reg,%r2,name@toc@ha; \ +addi reg,reg,name@toc@l + /* * Depending on how we were booted, the CPU could be running in either * Little Endian or Big Endian mode. The following trampoline from Linux diff --git a/xen/arch/ppc/include/asm/config.h b/xen/arch/ppc/include/asm/config.h index cb27d2781e..d060f0dca7 100644 --- a/xen/arch/ppc/include/asm/config.h +++ b/xen/arch/ppc/include/asm/config.h @@ -39,7 +39,7 @@ name: #endif -#define XEN_VIRT_START _AT(UL, 0x40) +#define XEN_VIRT_START _AT(UL, 0xc000) #define SMP_CACHE_BYTES (1 << 6) diff --git a/xen/arch/ppc/ppc64/head.S b/xen/arch/ppc/ppc64/head.S index 02ff520458..5ac2dad2ee 100644 --- a/xen/arch/ppc/ppc64/head.S +++ b/xen/arch/ppc/ppc64/head.S @@ -1,9 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include +#include .section .text.header, "ax", %progbits + ENTRY(start) /* * NOTE: argument registers (r3-r9) must be preserved until the C entrypoint @@ -11,16 +13,19 @@ ENTRY(start) FIXUP_ENDIAN /* set up the TOC pointer */ -LOAD_IMM32(%r2, .TOC.) +bcl20, 31, .+4 +1: mflr%r12 +addis %r2, %r12, .TOC.-1b@ha +addi%r2, %r2, .TOC.-1b@l /* set up the initial stack */ -LOAD_IMM32(%r1, cpu0_boot_stack) +LOAD_REG_ADDR(%r1, cpu0_boot_stack) li %r11, 0 stdu%r11, -STACK_FRAME_OVERHEAD(%r1) /* clear .bss */ -LOAD_IMM32(%r14, __bss_start) -LOAD_IMM32(%r15, __bss_end) +LOAD_REG_ADDR(%r14, __bss_start) +LOAD_REG_ADDR(%r15, __bss_end) 1: std %r11, 0(%r14) addi%r14, %r14, 8 diff --git a/xen/arch/ppc/xen.lds.S b/xen/arch/ppc/xen.lds.S index c628cc0e5c..2fa81d5a83 100644 --- a/xen/arch/ppc/xen.lds.S +++ b/xen/arch/ppc/xen.lds.S @@ -15,25 +15,12 @@ PHDRS #endif } -/** - * OpenFirmware's base load address is 0x40 (XEN_VIRT_START). - * By defining sections this way, we can keep our virtual address base at 0x40 - * while keeping the physical base at 0x0. - * - * Otherwise, OpenFirmware incorrectly loads .text at 0x40 + 0x40 = 0x80. - * Taken from x86/xen.lds.S - */ -#ifdef CONFIG_LD_IS_GNU -# define DECL_SECTION(x) x : AT(ADDR(#x) - XEN_VIRT_START) -#else -# define DECL_SECTION(x) x : AT(ADDR(x) - XEN_VIRT_START) -#endif - SECTIONS { . = XEN_VIRT_START; +_start = .; -DECL_SECTION(.text) { +.text : { _stext = .;/* Text section */ *(.text.header) @@ -52,7 +39,7 @@ SECTIONS } :text . = ALIGN(PAGE_SIZE); -DECL_SECTION(.rodata) { +.rodata : { _srodata = .; /* Read-only data */ *(.rodata) *(.rodata.*) @@ -67,7 +54,7 @@ SECTIONS #if defined(BUILD_ID) . = ALIGN(4); -DECL_SECTION(.note.gnu.build-id) { +.note.gnu.build-id : { __note_gnu_build_id_start = .; *(.note.gnu.build-id) __note_gnu_build_id_end = .; @@ -76,19 +63,19 @@ SECTIONS _erodata = .;/* End of read-onl
[PATCH 3/5] xen/ppc: Add OPAL API definition header file
OPAL (OpenPower Abstraction Layer) is the interface exposed by firmware on PowerNV (bare metal) systems. Import Linux's header definining the API and related information. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/include/asm/opal-api.h | 1190 +++ 1 file changed, 1190 insertions(+) create mode 100644 xen/arch/ppc/include/asm/opal-api.h diff --git a/xen/arch/ppc/include/asm/opal-api.h b/xen/arch/ppc/include/asm/opal-api.h new file mode 100644 index 00..75100eda83 --- /dev/null +++ b/xen/arch/ppc/include/asm/opal-api.h @@ -0,0 +1,1190 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * OPAL API definitions. + * + * Copyright 2011-2015 IBM Corp. + */ + +#ifndef __OPAL_API_H +#define __OPAL_API_H + +/** OPAL APIs **/ + +/* Return codes */ +#define OPAL_SUCCESS 0 +#define OPAL_PARAMETER -1 +#define OPAL_BUSY -2 +#define OPAL_PARTIAL -3 +#define OPAL_CONSTRAINED -4 +#define OPAL_CLOSED-5 +#define OPAL_HARDWARE -6 +#define OPAL_UNSUPPORTED -7 +#define OPAL_PERMISSION-8 +#define OPAL_NO_MEM-9 +#define OPAL_RESOURCE -10 +#define OPAL_INTERNAL_ERROR-11 +#define OPAL_BUSY_EVENT-12 +#define OPAL_HARDWARE_FROZEN -13 +#define OPAL_WRONG_STATE -14 +#define OPAL_ASYNC_COMPLETION -15 +#define OPAL_EMPTY -16 +#define OPAL_I2C_TIMEOUT -17 +#define OPAL_I2C_INVALID_CMD -18 +#define OPAL_I2C_LBUS_PARITY -19 +#define OPAL_I2C_BKEND_OVERRUN -20 +#define OPAL_I2C_BKEND_ACCESS -21 +#define OPAL_I2C_ARBT_LOST -22 +#define OPAL_I2C_NACK_RCVD -23 +#define OPAL_I2C_STOP_ERR -24 +#define OPAL_XIVE_PROVISIONING -31 +#define OPAL_XIVE_FREE_ACTIVE -32 +#define OPAL_TIMEOUT -33 + +/* API Tokens (in r0) */ +#define OPAL_INVALID_CALL -1 +#define OPAL_TEST 0 +#define OPAL_CONSOLE_WRITE 1 +#define OPAL_CONSOLE_READ 2 +#define OPAL_RTC_READ 3 +#define OPAL_RTC_WRITE 4 +#define OPAL_CEC_POWER_DOWN5 +#define OPAL_CEC_REBOOT6 +#define OPAL_READ_NVRAM7 +#define OPAL_WRITE_NVRAM 8 +#define OPAL_HANDLE_INTERRUPT 9 +#define OPAL_POLL_EVENTS 10 +#define OPAL_PCI_SET_HUB_TCE_MEMORY11 +#define OPAL_PCI_SET_PHB_TCE_MEMORY12 +#define OPAL_PCI_CONFIG_READ_BYTE 13 +#define OPAL_PCI_CONFIG_READ_HALF_WORD 14 +#define OPAL_PCI_CONFIG_READ_WORD 15 +#define OPAL_PCI_CONFIG_WRITE_BYTE 16 +#define OPAL_PCI_CONFIG_WRITE_HALF_WORD17 +#define OPAL_PCI_CONFIG_WRITE_WORD 18 +#define OPAL_SET_XIVE 19 +#define OPAL_GET_XIVE 20 +#define OPAL_GET_COMPLETION_TOKEN_STATUS 21 /* obsolete */ +#define OPAL_REGISTER_OPAL_EXCEPTION_HANDLER 22 +#define OPAL_PCI_EEH_FREEZE_STATUS 23 +#define OPAL_PCI_SHPC 24 +#define OPAL_CONSOLE_WRITE_BUFFER_SPACE25 +#define OPAL_PCI_EEH_FREEZE_CLEAR 26 +#define OPAL_PCI_PHB_MMIO_ENABLE 27 +#define OPAL_PCI_SET_PHB_MEM_WINDOW28 +#define OPAL_PCI_MAP_PE_MMIO_WINDOW29 +#define OPAL_PCI_SET_PHB_TABLE_MEMORY 30 +#define OPAL_PCI_SET_PE31 +#define OPAL_PCI_SET_PELTV 32 +#define OPAL_PCI_SET_MVE 33 +#define OPAL_PCI_SET_MVE_ENABLE34 +#define OPAL_PCI_GET_XIVE_REISSUE 35 +#define OPAL_PCI_SET_XIVE_REISSUE 36 +#define OPAL_PCI_SET_XIVE_PE 37 +#define OPAL_GET_XIVE_SOURCE 38 +#define OPAL_GET_MSI_3239 +#define OPAL_GET_MSI_6440 +#define OPAL_START_CPU 41 +#define OPAL_QUERY_CPU_STATUS 42 +#define OPAL_WRITE_OPPANEL 43 /* unimplemented */ +#define OPAL_PCI_MAP_PE_DMA_WINDOW 44 +#define OPAL_PCI_MAP_PE_DMA_WINDOW_REAL45 +#define OPAL_PCI_RESET 49 +#define OPAL_PCI_GET_HUB_DIAG_DATA 50 +#define OPAL_PCI_GET_PHB_DIAG_DATA 51 +#define OPAL_PCI_FENCE_PHB 52 +#define OPAL_PCI_REINIT53 +#define OPAL_PCI_MASK_PE_ERROR 54 +#define OPAL_SET_SLOT_LED_STATUS 55 +#define OPAL_GET_EPOW_STATUS 56 +#define OPAL_SET_SYSTEM_ATTENTION_LED 57 +#define OPAL_RESERVED1 58 +#define OPAL_RESERVED2 59 +#define OPAL_PCI_NEXT_ERROR60 +#define OPAL_PCI_EEH_FREEZE_ST
[PATCH 1/5] xen/lib: Move simple_strtoul from common/vsprintf.c to lib
Move the simple_strtoul routine which is used throughout the codebase from vsprintf.c to its own file in xen/lib. This allows libfdt to be built on ppc64 even though xen/common doesn't build yet. Signed-off-by: Shawn Anastasio --- xen/common/vsprintf.c| 37 - xen/lib/Makefile | 1 + xen/lib/simple_strtoul.c | 40 3 files changed, 41 insertions(+), 37 deletions(-) create mode 100644 xen/lib/simple_strtoul.c diff --git a/xen/common/vsprintf.c b/xen/common/vsprintf.c index b278961cc3..86330d8082 100644 --- a/xen/common/vsprintf.c +++ b/xen/common/vsprintf.c @@ -24,43 +24,6 @@ #include #include -/** - * simple_strtoul - convert a string to an unsigned long - * @cp: The start of the string - * @endp: A pointer to the end of the parsed string will be placed here - * @base: The number base to use - */ -unsigned long simple_strtoul( -const char *cp, const char **endp, unsigned int base) -{ -unsigned long result = 0,value; - -if (!base) { -base = 10; -if (*cp == '0') { -base = 8; -cp++; -if ((toupper(*cp) == 'X') && isxdigit(cp[1])) { -cp++; -base = 16; -} -} -} else if (base == 16) { -if (cp[0] == '0' && toupper(cp[1]) == 'X') -cp += 2; -} -while (isxdigit(*cp) && - (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { -result = result*base + value; -cp++; -} -if (endp) -*endp = cp; -return result; -} - -EXPORT_SYMBOL(simple_strtoul); - /** * simple_strtol - convert a string to a signed long * @cp: The start of the string diff --git a/xen/lib/Makefile b/xen/lib/Makefile index b311ea739c..bce76f9742 100644 --- a/xen/lib/Makefile +++ b/xen/lib/Makefile @@ -13,6 +13,7 @@ lib-y += memset.o lib-y += muldiv64.o lib-y += parse-size.o lib-y += rbtree.o +lib-y += simple_strtoul.o lib-y += sort.o lib-y += strcasecmp.o lib-y += strchr.o diff --git a/xen/lib/simple_strtoul.c b/xen/lib/simple_strtoul.c new file mode 100644 index 00..e43760ad1d --- /dev/null +++ b/xen/lib/simple_strtoul.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#include + +/** + * simple_strtoul - convert a string to an unsigned long + * @cp: The start of the string + * @endp: A pointer to the end of the parsed string will be placed here + * @base: The number base to use + */ +unsigned long simple_strtoul( +const char *cp, const char **endp, unsigned int base) +{ +unsigned long result = 0,value; + +if (!base) { +base = 10; +if (*cp == '0') { +base = 8; +cp++; +if ((toupper(*cp) == 'X') && isxdigit(cp[1])) { +cp++; +base = 16; +} +} +} else if (base == 16) { +if (cp[0] == '0' && toupper(cp[1]) == 'X') +cp += 2; +} +while (isxdigit(*cp) && + (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { +result = result*base + value; +cp++; +} +if (endp) +*endp = cp; +return result; +} -- 2.30.2
[PATCH 0/3] xen/ppc: Add early Radix MMU support
Hello all, This series adds support for bringing up the Radix MMU with basic identity-mapped page tables. In order to simplify the memory layout, the series changes XEN_VIRT _START to 0xC000___, which has a couple of convenient properties. When the MMU is off, the top 4 address bits are ignored by the hardware, so this is equivalent to physical address 0. When the MMU is enabled, the top 4 address bits are used to select the memory quadrant, and 0xC corresponds to quadrant 3 which is used for kernel memory. Thus, by linking the kernel here and ensuring its physical load address is 0x0, we are able to run at the correct address both before and after the MMU is enabled. Additionally, as the Radix MMU was only added in ISA 3.0 (POWER9), this series also drops support for POWER8 for now, to avoid having a non-working build configuration in-tree. Thanks, Shawn Shawn Anastasio (3): xen/ppc: Bump minimum target ISA to 3.0 (POWER9) xen/ppc: Relocate kernel to physical address 0 on boot xen/ppc: Implement initial Radix MMU support xen/arch/ppc/Kconfig | 7 +- xen/arch/ppc/Makefile| 2 + xen/arch/ppc/arch.mk | 1 - xen/arch/ppc/include/asm/bitops.h| 11 ++ xen/arch/ppc/include/asm/mm.h| 19 ++ xen/arch/ppc/include/asm/page-bits.h | 3 +- xen/arch/ppc/include/asm/page.h | 178 ++ xen/arch/ppc/include/asm/processor.h | 31 xen/arch/ppc/include/asm/regs.h | 138 ++ xen/arch/ppc/include/asm/types.h | 1 + xen/arch/ppc/mm-radix.c | 268 +++ xen/arch/ppc/opal.c | 2 + xen/arch/ppc/ppc64/head.S| 42 + xen/arch/ppc/setup.c | 4 + xen/arch/ppc/tlb-radix.c | 95 ++ 15 files changed, 794 insertions(+), 8 deletions(-) create mode 100644 xen/arch/ppc/include/asm/bitops.h create mode 100644 xen/arch/ppc/include/asm/mm.h create mode 100644 xen/arch/ppc/include/asm/page.h create mode 100644 xen/arch/ppc/include/asm/regs.h create mode 100644 xen/arch/ppc/mm-radix.c create mode 100644 xen/arch/ppc/tlb-radix.c -- 2.30.2
[PATCH 1/3] xen/ppc: Bump minimum target ISA to 3.0 (POWER9)
In preparation for implementing ISA3+ Radix MMU support, drop ISA 2.07B from the supported ISA list to avoid having a non-working configuration in tree. It can be re-added at a later point when Hash MMU support is added. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/Kconfig | 7 +-- xen/arch/ppc/arch.mk | 1 - 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/xen/arch/ppc/Kconfig b/xen/arch/ppc/Kconfig index b32dce39b8..ab116ffb2a 100644 --- a/xen/arch/ppc/Kconfig +++ b/xen/arch/ppc/Kconfig @@ -20,15 +20,10 @@ menu "ISA Selection" choice prompt "Base ISA" - default POWER_ISA_2_07B + default POWER_ISA_3_00 help This selects the base ISA version that Xen will target. -config POWER_ISA_2_07B - bool "Power ISA 2.07B (POWER8)" - help - Target version 2.07B of the Power ISA (POWER8) or later - config POWER_ISA_3_00 bool "Power ISA 3.00 (POWER9)" help diff --git a/xen/arch/ppc/arch.mk b/xen/arch/ppc/arch.mk index 9f66f7a57b..f48ead6580 100644 --- a/xen/arch/ppc/arch.mk +++ b/xen/arch/ppc/arch.mk @@ -1,7 +1,6 @@ # Power-specific definitions -ppc-march-$(CONFIG_POWER_ISA_2_07B) := power8 ppc-march-$(CONFIG_POWER_ISA_3_00) := power9 CFLAGS += -m64 -mlittle-endian -mcpu=$(ppc-march-y) -- 2.30.2
[PATCH 2/3] xen/ppc: Relocate kernel to physical address 0 on boot
Introduce a small assembly loop in `start` to copy the kernel to physical address 0 before continuing. This ensures that the physical address lines up with XEN_VIRT_START (0xc000) and allows us to identity map the kernel when the MMU is set up in the next patch. We are also able to start execution at XEN_VIRT_START after the copy since hardware will ignore the top 4 address bits when operating in Real Mode (MMU off). Signed-off-by: Shawn Anastasio --- xen/arch/ppc/ppc64/head.S | 27 +++ 1 file changed, 27 insertions(+) diff --git a/xen/arch/ppc/ppc64/head.S b/xen/arch/ppc/ppc64/head.S index 5ac2dad2ee..beff8257fa 100644 --- a/xen/arch/ppc/ppc64/head.S +++ b/xen/arch/ppc/ppc64/head.S @@ -18,6 +18,33 @@ ENTRY(start) addis %r2, %r12, .TOC.-1b@ha addi%r2, %r2, .TOC.-1b@l +/* + * Copy Xen to physical address zero and jump to XEN_VIRT_START + * (0xc000). This works because the hardware will ignore the top + * four address bits when the MMU is off. + */ +LOAD_REG_ADDR(%r1, start) +LOAD_IMM64(%r12, XEN_VIRT_START) + +/* If we're at the correct address, skip copy */ +cmpld %r1, %r12 +beq .L_correct_address + +/* Copy bytes until _end */ +LOAD_REG_ADDR(%r11, _end) +addi%r1, %r1, -8 +li %r13, -8 +.L_copy_xen: +ldu %r10, 8(%r1) +stdu%r10, 8(%r13) +cmpld %r1, %r11 +blt .L_copy_xen + +/* Jump to XEN_VIRT_START */ +mtctr %r12 +bctr +.L_correct_address: + /* set up the initial stack */ LOAD_REG_ADDR(%r1, cpu0_boot_stack) li %r11, 0 -- 2.30.2
[PATCH 3/3] xen/ppc: Implement initial Radix MMU support
Add code to construct early identity-mapped page tables as well as the required process and partition tables to enable the MMU. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/Makefile| 2 + xen/arch/ppc/include/asm/bitops.h| 11 ++ xen/arch/ppc/include/asm/mm.h| 19 ++ xen/arch/ppc/include/asm/page-bits.h | 3 +- xen/arch/ppc/include/asm/page.h | 178 ++ xen/arch/ppc/include/asm/processor.h | 31 xen/arch/ppc/include/asm/regs.h | 138 ++ xen/arch/ppc/include/asm/types.h | 1 + xen/arch/ppc/mm-radix.c | 268 +++ xen/arch/ppc/opal.c | 2 + xen/arch/ppc/ppc64/head.S| 15 ++ xen/arch/ppc/setup.c | 4 + xen/arch/ppc/tlb-radix.c | 95 ++ 13 files changed, 766 insertions(+), 1 deletion(-) create mode 100644 xen/arch/ppc/include/asm/bitops.h create mode 100644 xen/arch/ppc/include/asm/mm.h create mode 100644 xen/arch/ppc/include/asm/page.h create mode 100644 xen/arch/ppc/include/asm/regs.h create mode 100644 xen/arch/ppc/mm-radix.c create mode 100644 xen/arch/ppc/tlb-radix.c diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile index 0c0a7884a1..a059ac4c0a 100644 --- a/xen/arch/ppc/Makefile +++ b/xen/arch/ppc/Makefile @@ -2,8 +2,10 @@ obj-$(CONFIG_PPC64) += ppc64/ obj-y += boot-of.init.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.init.o +obj-y += mm-radix.o obj-y += opal.o obj-y += setup.o +obj-y += tlb-radix.o $(TARGET): $(TARGET)-syms cp -f $< $@ diff --git a/xen/arch/ppc/include/asm/bitops.h b/xen/arch/ppc/include/asm/bitops.h new file mode 100644 index 00..a7cd8ec7c5 --- /dev/null +++ b/xen/arch/ppc/include/asm/bitops.h @@ -0,0 +1,11 @@ +#ifndef _ASM_PPC_BITOPS_H +#define _ASM_PPC_BITOPS_H + +#include + +/* PPC bit number conversion */ +#define PPC_BITLSHIFT(be) (BITS_PER_LONG - 1 - (be)) +#define PPC_BIT(bit) (1UL << PPC_BITLSHIFT(bit)) +#define PPC_BITMASK(bs, be)((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) + +#endif /* _ASM_PPC_BITOPS_H */ diff --git a/xen/arch/ppc/include/asm/mm.h b/xen/arch/ppc/include/asm/mm.h new file mode 100644 index 00..36e44a4356 --- /dev/null +++ b/xen/arch/ppc/include/asm/mm.h @@ -0,0 +1,19 @@ +#ifndef _ASM_PPC_MM_H +#define _ASM_PPC_MM_H + +#include +#include + +#define pfn_to_paddr(pfn) ((paddr_t)(pfn) << PAGE_SHIFT) +#define paddr_to_pfn(pa) ((unsigned long)((pa) >> PAGE_SHIFT)) + +#define virt_to_maddr(va) ((paddr_t)((vaddr_t)(va) & PADDR_MASK)) +#define maddr_to_virt(pa) ((void *)((paddr_t)(pa) | XEN_VIRT_START) + +/* Convert between Xen-heap virtual addresses and machine addresses. */ +#define __pa(x) (virt_to_maddr(x)) +#define __va(x) (maddr_to_virt(x)) + +void setup_initial_pagetables(void); + +#endif /* _ASM_PPC_MM_H */ diff --git a/xen/arch/ppc/include/asm/page-bits.h b/xen/arch/ppc/include/asm/page-bits.h index 4c01bf9716..0286177520 100644 --- a/xen/arch/ppc/include/asm/page-bits.h +++ b/xen/arch/ppc/include/asm/page-bits.h @@ -2,6 +2,7 @@ #define __PPC_PAGE_BITS_H__ #define PAGE_SHIFT 16 /* 64 KiB Pages */ -#define PADDR_BITS 48 +#define PADDR_BITS 53 +#define VADDR_BITS 52 #endif /* __PPC_PAGE_BITS_H__ */ diff --git a/xen/arch/ppc/include/asm/page.h b/xen/arch/ppc/include/asm/page.h new file mode 100644 index 00..e58b0a7354 --- /dev/null +++ b/xen/arch/ppc/include/asm/page.h @@ -0,0 +1,178 @@ +#ifndef _ASM_PPC_PAGE_H +#define _ASM_PPC_PAGE_H + +#include + +#include +#include + +#define PDE_VALID PPC_BIT(0) +#define PDE_NLB_MASK 0xfUL +#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_CHANGEPPC_BIT(56) + +/* PTE Attributes */ +#define PTE_ATT_SAOPPC_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_EXECUTEPPC_BIT(63) + +/* Field shifts/masks */ +#define PTE_RPN_MASK 0x1fffUL +#define PTE_RPN_SHIFT 12UL +#define PTE_ATT_MASK 0x3UL +#define PTE_ATT_SHIFT 4UL +#define PTE_EAA_MASK 0xfUL + +#define PTE_XEN_BASE (PTE_VALID | PTE_EAA_PRIVILEGED | PTE_REFERENCE) +#define PTE_XEN_RW (PTE_XEN_BASE | PTE_EAA_READ | PTE_EAA_WRITE | PTE_CHANGE) +#define PTE_XEN_RO (PTE_XEN_BASE | PTE_EAA_READ) +#define PTE_XEN_RX (PTE_XEN_BASE | PTE_EAA_READ | PTE_EAA_EXECUTE) + +/* + * Radix Tree layout for 64KB pages: + * + * [ L1 (ROOT) PAGE DIRECTORY (8192 * sizeof(pde_t)) ] + * | + * | + * v + *[ L2 PAGE DIRE
Re: [PATCH 1/5] xen/lib: Move simple_strtoul from common/vsprintf.c to lib
On 7/31/23 10:52 AM, Jan Beulich wrote: > On 28.07.2023 23:35, Shawn Anastasio wrote: >> Move the simple_strtoul routine which is used throughout the codebase >> from vsprintf.c to its own file in xen/lib. >> >> This allows libfdt to be built on ppc64 even though xen/common doesn't >> build yet. >> >> Signed-off-by: Shawn Anastasio >> --- >> xen/common/vsprintf.c| 37 - >> xen/lib/Makefile | 1 + >> xen/lib/simple_strtoul.c | 40 >> 3 files changed, 41 insertions(+), 37 deletions(-) >> create mode 100644 xen/lib/simple_strtoul.c > > What about its siblings? It'll be irritating to find one here and the > other there. I was debating whether to do this or not and ultimately decided to only make the minimum changes that were required right now. I can go ahead and make the change for its siblings as well. > Also please no underscores in (new) filenames unless there's a reason > for this. In the case here, though, I question the need for "simple" > in the file name in the first place. >From a look at the other files in xen/lib there seemed to be a convention of naming files after the exact function they implement. Would you rather I rename it to just strtoul.c? Or simple-strotoul.c? >> --- /dev/null >> +++ b/xen/lib/simple_strtoul.c >> @@ -0,0 +1,40 @@ >> +/* >> + * Copyright (C) 1991, 1992 Linus Torvalds >> + */ >> + >> +#include >> + >> +/** >> + * simple_strtoul - convert a string to an unsigned long >> + * @cp: The start of the string >> + * @endp: A pointer to the end of the parsed string will be placed here >> + * @base: The number base to use >> + */ >> +unsigned long simple_strtoul( >> +const char *cp, const char **endp, unsigned int base) >> +{ >> +unsigned long result = 0,value; >> + >> +if (!base) { >> +base = 10; >> +if (*cp == '0') { >> +base = 8; >> +cp++; >> +if ((toupper(*cp) == 'X') && isxdigit(cp[1])) { >> +cp++; >> +base = 16; >> +} >> +} >> +} else if (base == 16) { >> +if (cp[0] == '0' && toupper(cp[1]) == 'X') >> +cp += 2; >> +} >> +while (isxdigit(*cp) && >> + (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { >> +result = result*base + value; >> +cp++; >> +} >> +if (endp) >> +*endp = cp; >> +return result; >> +} > > While moving, I think it would be nice if this stopped using neither > Xen nor Linux style. I'm not going to insist, but doing such style > adjustments right here would be quite nice. Especially if I'm going to be moving its siblings, I'd rather just copy the functions verbatim for this patch, if that's acceptable. > Jan Thanks, Shawn
Re: [PATCH 2/5] xen/ppc: Switch to medium PIC code model
On 7/31/23 10:58 AM, Jan Beulich wrote: > On 28.07.2023 23:35, Shawn Anastasio wrote: >> --- a/xen/arch/ppc/ppc64/head.S >> +++ b/xen/arch/ppc/ppc64/head.S >> @@ -1,9 +1,11 @@ >> /* SPDX-License-Identifier: GPL-2.0-or-later */ >> >> #include >> +#include >> >> .section .text.header, "ax", %progbits >> >> + >> ENTRY(start) > > Nit: Stray change? > >> @@ -11,16 +13,19 @@ ENTRY(start) >> FIXUP_ENDIAN >> >> /* set up the TOC pointer */ >> -LOAD_IMM32(%r2, .TOC.) >> +bcl 20, 31, .+4 > > Could you use a label name instead of .+4? Aiui you really mean > >> +1: mflr%r12 > > ... "1f" there? Yes, good point. I'll point out that this form of the `bcl` instruction is specifically defined in the ISA specification as the recommended way to obtain the address of the next instruction, and hardware implementations presumably optimize it. Using a label instead of +4 would of course be fine as long as the label immediately follows the bcl, but if the label was elsewhere then the optimization that the ISA allows for this specific instruction might not be hit. Just something that should be kept in mind in case this code is ever refactored. I'll change it to 1f in v2. > > Jan Thanks, Shawn
Re: [PATCH 3/5] xen/ppc: Add OPAL API definition header file
On 7/31/23 10:59 AM, Jan Beulich wrote: > On 28.07.2023 23:35, Shawn Anastasio wrote: >> OPAL (OpenPower Abstraction Layer) is the interface exposed by firmware >> on PowerNV (bare metal) systems. Import Linux's header definining the >> API and related information. > > To help future updating, mentioning version (or commit) at which this > snapshot was taken would be helpful. Sounds reasonable. I'll reference the Linux commit that this was pulled from in the commit message. > Jan Thanks, Shawn
Re: [PATCH 2/3] xen/ppc: Relocate kernel to physical address 0 on boot
On 7/31/23 10:46 AM, Jan Beulich wrote: > On 29.07.2023 00:21, Shawn Anastasio wrote: >> Introduce a small assembly loop in `start` to copy the kernel to >> physical address 0 before continuing. This ensures that the physical >> address lines up with XEN_VIRT_START (0xc000) and allows us >> to identity map the kernel when the MMU is set up in the next patch. > > So PPC guarantees there's always a reasonable amount of memory at 0, > and that's available for use? Both Linux and FreeBSD rely on this being the case, so it's essentially a de facto standard, though I'm not aware of any specification that guarantees it. >> --- a/xen/arch/ppc/ppc64/head.S >> +++ b/xen/arch/ppc/ppc64/head.S >> @@ -18,6 +18,33 @@ ENTRY(start) >> addis %r2, %r12, .TOC.-1b@ha >> addi%r2, %r2, .TOC.-1b@l >> >> +/* >> + * Copy Xen to physical address zero and jump to XEN_VIRT_START >> + * (0xc000). This works because the hardware will ignore >> the top >> + * four address bits when the MMU is off. >> + */ >> +LOAD_REG_ADDR(%r1, start) > > I think you really mean _start here (which is missing from the linker > script), The PIC patch series fixes the missing _start definition in the linker script. In the cover letter of v2 I'll add a clear note that this series is based on that one. > not start. See also Andrew's recent related RISC-V change. Good point. In practice this worked because the `start` function was the first thing in the first section of the linker script, but of course using _start here is more correct. > >> +LOAD_IMM64(%r12, XEN_VIRT_START) >> + >> +/* If we're at the correct address, skip copy */ >> +cmpld %r1, %r12 >> +beq .L_correct_address > > Can this ever be the case, especially with the MMU-off behavior you > describe in the comment above? Wouldn't you need to ignore the top > four bits in the comparison? It will always be the case after the code jumps to XEN_VIRT_START after the copy takes place. I could have it jump past the copy loop entirely, but then I'd need to duplicate the TOC setup. >> +/* Copy bytes until _end */ >> +LOAD_REG_ADDR(%r11, _end) >> +addi%r1, %r1, -8 >> +li %r13, -8 >> +.L_copy_xen: >> +ldu %r10, 8(%r1) >> +stdu%r10, 8(%r13) >> +cmpld %r1, %r11 >> +blt .L_copy_xen >> + >> +/* Jump to XEN_VIRT_START */ >> +mtctr %r12 >> +bctr >> +.L_correct_address: > > Can the two regions potentially overlap? Looking at the ELF header > it's not clear to me what guarantees there are that this can't > happen. As I understand it, any bootloader that placed the kernel at a low enough address for this to be an issue wouldn't be able to boot Linux or FreeBSD, so in practice it's a safe bet that this won't be the case. > Jan Thanks, Shawn
Re: [PATCH] common: move simple_strto{,u}l{,l}() to lib/
On 8/1/23 5:34 AM, Jan Beulich wrote: > Convert style from a Xen/Linux mix to pure Xen while doing the move. No > other changes, despite having been heavily tempted to do some - at the > very least to make simple_strtoul() and simple_strtoull() the same in > how they deal with non-numeric digits. > > Requested-by: Shawn Anastasio > Signed-off-by: Jan Beulich > --- > Further changes I was considering: > - "value" doesn't need to be unsigned long, and even less so unsigned > long long, > - strtoull.c could simply include strtoul.c, after #define-ing "long" > to "long long" and "simple_strtoul" to "simple_strtoull", > - "else if ( base == 16 )" wants folding with its inner if(). > > --- a/xen/common/vsprintf.c > +++ b/xen/common/vsprintf.c > @@ -24,108 +24,6 @@ > #include > #include > > -/** > - * simple_strtoul - convert a string to an unsigned long > - * @cp: The start of the string > - * @endp: A pointer to the end of the parsed string will be placed here > - * @base: The number base to use > - */ > -unsigned long simple_strtoul( > -const char *cp, const char **endp, unsigned int base) > -{ > -unsigned long result = 0,value; > - > -if (!base) { > -base = 10; > -if (*cp == '0') { > -base = 8; > -cp++; > -if ((toupper(*cp) == 'X') && isxdigit(cp[1])) { > -cp++; > -base = 16; > -} > -} > -} else if (base == 16) { > -if (cp[0] == '0' && toupper(cp[1]) == 'X') > -cp += 2; > -} > -while (isxdigit(*cp) && > - (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { > -result = result*base + value; > -cp++; > -} > -if (endp) > -*endp = cp; > -return result; > -} > - > -EXPORT_SYMBOL(simple_strtoul); > - > -/** > - * simple_strtol - convert a string to a signed long > - * @cp: The start of the string > - * @endp: A pointer to the end of the parsed string will be placed here > - * @base: The number base to use > - */ > -long simple_strtol(const char *cp, const char **endp, unsigned int base) > -{ > -if(*cp=='-') > -return -simple_strtoul(cp+1,endp,base); > -return simple_strtoul(cp,endp,base); > -} > - > -EXPORT_SYMBOL(simple_strtol); > - > -/** > - * simple_strtoull - convert a string to an unsigned long long > - * @cp: The start of the string > - * @endp: A pointer to the end of the parsed string will be placed here > - * @base: The number base to use > - */ > -unsigned long long simple_strtoull( > -const char *cp, const char **endp, unsigned int base) > -{ > -unsigned long long result = 0,value; > - > -if (!base) { > -base = 10; > -if (*cp == '0') { > -base = 8; > -cp++; > -if ((toupper(*cp) == 'X') && isxdigit(cp[1])) { > -cp++; > -base = 16; > -} > -} > -} else if (base == 16) { > -if (cp[0] == '0' && toupper(cp[1]) == 'X') > -cp += 2; > -} > -while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) > - ? > toupper(*cp) : *cp)-'A'+10) < base) { > -result = result*base + value; > -cp++; > -} > -if (endp) > -*endp = cp; > -return result; > -} > - > -EXPORT_SYMBOL(simple_strtoull); > - > -/** > - * simple_strtoll - convert a string to a signed long long > - * @cp: The start of the string > - * @endp: A pointer to the end of the parsed string will be placed here > - * @base: The number base to use > - */ > -long long simple_strtoll(const char *cp,const char **endp,unsigned int base) > -{ > -if(*cp=='-') > -return -simple_strtoull(cp+1,endp,base); > -return simple_strtoull(cp,endp,base); > -} > - > static int skip_atoi(const char **s) > { > int i=0; > --- a/xen/lib/Makefile > +++ b/xen/lib/Makefile > @@ -28,6 +28,10 @@ lib-y += strrchr.o > lib-y += strsep.o > lib-y += strspn.o > lib-y += strstr.o > +lib-y += strtol.o > +lib-y += strtoll.o > +lib-y += strtoul.o > +lib-y += strtoull.o > lib-$(CONFIG_X86) += xxhash32.o > lib-$(CONFIG_X86) += xxhash64.o > > --- /dev/null > +++ b/xen/lib/strtol.c > @@ -0,0 +1,28 @@ > +/* > +
Re: [PATCH 2/5] xen/ppc: Switch to medium PIC code model
On 8/1/23 7:20 AM, Jan Beulich wrote: > On 28.07.2023 23:35, Shawn Anastasio wrote: >> @@ -11,16 +13,19 @@ ENTRY(start) >> FIXUP_ENDIAN >> >> /* set up the TOC pointer */ >> -LOAD_IMM32(%r2, .TOC.) >> +bcl 20, 31, .+4 >> +1: mflr%r12 >> +addis %r2, %r12, .TOC.-1b@ha >> +addi%r2, %r2, .TOC.-1b@l >> >> /* set up the initial stack */ >> -LOAD_IMM32(%r1, cpu0_boot_stack) >> +LOAD_REG_ADDR(%r1, cpu0_boot_stack) > > Question: Would perhaps make sense to use %sp and %rtoc in place of > %r1 and %r2 (not just here of course)? In my opinion, usage of the aliased register names ends up making the code less clear.
Re: [PATCH 4/5] xen/ppc: Parse device tree for OPAL node on PowerNV
On 7/31/23 11:06 AM, Jan Beulich wrote: > On 28.07.2023 23:35, Shawn Anastasio wrote: >> --- a/xen/arch/ppc/arch.mk >> +++ b/xen/arch/ppc/arch.mk >> @@ -10,5 +10,5 @@ CFLAGS += -mstrict-align -mcmodel=medium -mabi=elfv2 -fPIC >> -mno-altivec -mno-vsx >> LDFLAGS += -m elf64lppc >> >> # TODO: Drop override when more of the build is working >> -override ALL_OBJS-y = arch/$(SRCARCH)/built_in.o >> -override ALL_LIBS-y = >> +override ALL_OBJS-y = arch/$(SRCARCH)/built_in.o common/libfdt/built_in.o >> lib/built_in.o >> +override ALL_LIBS-y = lib/lib.a > > Can't you drop the ALL_LIBS-y override right here? Just tested this and it does indeed work. I'll drop the override in v2. > Jan Thanks, Shawn
Re: [PATCH 5/5] xen/ppc: Implement early serial console on PowerNV
On 8/1/23 6:19 AM, Jan Beulich wrote: > On 28.07.2023 23:35, Shawn Anastasio wrote: >> --- a/xen/arch/ppc/include/asm/asm-defns.h >> +++ b/xen/arch/ppc/include/asm/asm-defns.h >> @@ -23,6 +23,18 @@ >> addis reg,%r2,name@toc@ha; >> \ >> addi reg,reg,name@toc@l > > Noticing only now, because of the issue ... > >> +/* >> + * Declare a global assembly function with a proper TOC setup prologue >> + */ >> +#define _GLOBAL_TOC(name) >> \ >> +.balign 4; >> \ >> +.type name,@function; >> \ >> +.globl name; >> \ >> +name: >> \ >> +0: addis %r2,%r12,(.TOC.-0b)@ha; >> \ >> +addi %r2,%r2,(.TOC.-0b)@l; >> \ >> +.localentry name,.-name > > ... being widened - could we gain blanks after the commas? Down here > (to match the code in context) another padding blank after "addi" > would also be nice. Sure, will do in v2. >> --- a/xen/arch/ppc/opal.c >> +++ b/xen/arch/ppc/opal.c >> @@ -8,9 +8,28 @@ >> #include >> #include >> >> -/* Global OPAL struct containing entrypoint and base */ >> +/* Global OPAL struct containing entrypoint and base used by opal-calls.S */ >> struct opal opal; >> >> +int64_t opal_console_write(int64_t term_number, uint64_t *length, >> + uint8_t *buffer); > > Would this perhaps better be void *, eliminating the need for casting > in calls of this function? I made it uint8_t to match the official OPAL API documentation (though I now see I missed a `const`): https://open-power.github.io/skiboot/doc/opal-api/opal-console-read-write-1-2.html#opal-console-write In this case though, the type information of this parameter might not be that important and changing it to void* to avoid the cast is fine with me. >> +int64_t opal_console_flush(int64_t term_number); >> +int64_t opal_reinit_cpus(uint64_t flags); >> + >> +static void opal_putchar(char c) > > Can't this be __init? Unlike OpenFirmware, OPAL calls are expected to be used by the OS during its entire lifecycle, not just during early boot, so the full (non-early) serial console driver would likely want to use these functions as well. > >> +{ >> +uint64_t len; >> +if (c == '\n') > > Nit: Blank line please between declaration(s) and statement(s). (At > least one more instance below.) Will fix. > Also please add the missing blanks in the if(), seeing that otherwise > the file is aiming at being Xen style. Ditto. >> +{ >> +char buf = '\r'; >> +len = cpu_to_be64(1); >> +opal_console_write(0, &len, (uint8_t *) &buf); >> +} >> +len = cpu_to_be64(1); >> +opal_console_write(0, &len, (uint8_t *) &c); >> +opal_console_flush(0); >> +} >> + >> void __init boot_opal_init(const void *fdt) >> { >> int opal_node; >> @@ -45,4 +64,10 @@ void __init boot_opal_init(const void *fdt) >> >> opal.base = be64_to_cpu(*opal_base); >> opal.entry = be64_to_cpu(*opal_entry); >> + >> +early_printk_init(opal_putchar); >> + >> +/* Ask OPAL to set HID0 for Little Endian interrupts + Radix TLB >> support */ >> +opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_LE | OPAL_REINIT_CPUS_MMU_RADIX >> + | OPAL_REINIT_CPUS_MMU_HASH); > > Nit: operators on continued lines go at the end of the earlier line. Will fix. >> --- /dev/null >> +++ b/xen/arch/ppc/ppc64/opal-calls.S >> @@ -0,0 +1,82 @@ >> +/* SPDX-License-Identifier: GPL-2.0-or-later */ >> +/* >> + * Adapted from Linux's arch/powerpc/boot/opal-calls.S >> + * >> + * Copyright (c) 2016 IBM Corporation. >> + * Copyright Raptor Engineering, LLC >> + */ >> + >> +#include >> +#include > > Would it make sense to have asm-defns.h include asm-offsets.h, like > x86 and Arm do? Sure, I'll make this change along with the formatting updates in asm-defns.h >> +#include >> +#include >> + >> +.text > > Is any of this code still needed post-init? Yes, see above. >> +#define OPAL_CALL(name, token) \ >> +.globl name;\ >> +name: \ >> +li %r0, token; \ >> +b opal_call; > > I think the trailing semicolon wants omitting. Will fix. > Jan Thanks, Shawn
[PATCH 0/4] xen/ppc: Add PowerNV bare metal support
Hello all, This series adds support for booting and using the serial console on bare metal PowerNV/OpenPOWER systems. Up until now, Xen could only be booted on the QEMU pseries model, which was initially targetted for ease of development, but which differs significantly from the bare metal systems where this port is likely to be the most useful. In addition to adding support for the PowerNV boot protocol and firmware interface, changes required to get libfdt from xen/libfdt building are included. This is required to obtain the firmware entrypoint address on PowerNV. This series is based on Jan's "common: move simple_strto{,u}l{,l}() to lib/" https://lists.xenproject.org/archives/html/xen-devel/2023-08/msg00095.html Thanks, Shawn -- Changed in v2: - Drop simple_strtoul patch, base on Jan's patch instead - Remove ALL_LIBS-y override - Clean up formatting of opal.c, opal-calls.S, asm-defns.h - Consistently use label in TOC address calculation in head.S Shawn Anastasio (4): xen/ppc: Switch to medium PIC code model xen/ppc: Add OPAL API definition header file xen/ppc: Parse device tree for OPAL node on PowerNV xen/ppc: Implement early serial console on PowerNV xen/arch/ppc/Kconfig |1 + xen/arch/ppc/Makefile|1 + xen/arch/ppc/arch.mk |5 +- xen/arch/ppc/include/asm/asm-defns.h | 21 + xen/arch/ppc/include/asm/boot.h | 16 +- xen/arch/ppc/include/asm/bug.h | 18 + xen/arch/ppc/include/asm/cache.h |6 + xen/arch/ppc/include/asm/config.h|2 +- xen/arch/ppc/include/asm/opal-api.h | 1190 ++ xen/arch/ppc/include/asm/processor.h | 13 +- xen/arch/ppc/include/asm/string.h|6 + xen/arch/ppc/include/asm/system.h|6 + xen/arch/ppc/opal.c | 74 ++ xen/arch/ppc/ppc64/Makefile |1 + xen/arch/ppc/ppc64/asm-offsets.c |4 + xen/arch/ppc/ppc64/head.S| 12 +- xen/arch/ppc/ppc64/opal-calls.S | 81 ++ xen/arch/ppc/setup.c |9 +- xen/arch/ppc/xen.lds.S | 44 +- 19 files changed, 1470 insertions(+), 40 deletions(-) create mode 100644 xen/arch/ppc/include/asm/bug.h create mode 100644 xen/arch/ppc/include/asm/cache.h create mode 100644 xen/arch/ppc/include/asm/opal-api.h create mode 100644 xen/arch/ppc/include/asm/string.h create mode 100644 xen/arch/ppc/include/asm/system.h create mode 100644 xen/arch/ppc/opal.c create mode 100644 xen/arch/ppc/ppc64/opal-calls.S -- 2.30.2
[PATCH 3/4] xen/ppc: Parse device tree for OPAL node on PowerNV
Communication with firmware boot services on PowerNV requires parsing the fdt blob passed by the bootloader in order to obtain the firmware entrypoint. Use Xen's libfdt to do this and store the information required for firmware calls, to be implemented in a future patch. The full xen/common build doesn't yet work, but libfdt and its xen/lib dependency can be made to build by defining a few stub headers. Signed-off-by: Shawn Anastasio --- Changed in v2: - Remove ALL_LIBS-y override xen/arch/ppc/Kconfig | 1 + xen/arch/ppc/Makefile| 1 + xen/arch/ppc/arch.mk | 3 +- xen/arch/ppc/include/asm/boot.h | 16 +- xen/arch/ppc/include/asm/bug.h | 18 +++ xen/arch/ppc/include/asm/cache.h | 6 xen/arch/ppc/include/asm/processor.h | 13 +++- xen/arch/ppc/include/asm/string.h| 6 xen/arch/ppc/include/asm/system.h| 6 xen/arch/ppc/opal.c | 48 xen/arch/ppc/setup.c | 9 -- 11 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 xen/arch/ppc/include/asm/bug.h create mode 100644 xen/arch/ppc/include/asm/cache.h create mode 100644 xen/arch/ppc/include/asm/string.h create mode 100644 xen/arch/ppc/include/asm/system.h create mode 100644 xen/arch/ppc/opal.c diff --git a/xen/arch/ppc/Kconfig b/xen/arch/ppc/Kconfig index a2ade2ecf4..b32dce39b8 100644 --- a/xen/arch/ppc/Kconfig +++ b/xen/arch/ppc/Kconfig @@ -1,5 +1,6 @@ config PPC def_bool y + select HAS_DEVICE_TREE config PPC64 def_bool y diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile index 098a4dd0a9..0c0a7884a1 100644 --- a/xen/arch/ppc/Makefile +++ b/xen/arch/ppc/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_PPC64) += ppc64/ obj-y += boot-of.init.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.init.o +obj-y += opal.o obj-y += setup.o $(TARGET): $(TARGET)-syms diff --git a/xen/arch/ppc/arch.mk b/xen/arch/ppc/arch.mk index 0183b9ac6a..3bf79bac37 100644 --- a/xen/arch/ppc/arch.mk +++ b/xen/arch/ppc/arch.mk @@ -10,5 +10,4 @@ CFLAGS += -mstrict-align -mcmodel=medium -mabi=elfv2 -fPIC -mno-altivec -mno-vsx LDFLAGS += -m elf64lppc # TODO: Drop override when more of the build is working -override ALL_OBJS-y = arch/$(SRCARCH)/built_in.o -override ALL_LIBS-y = +override ALL_OBJS-y = arch/$(SRCARCH)/built_in.o common/libfdt/built_in.o lib/built_in.o diff --git a/xen/arch/ppc/include/asm/boot.h b/xen/arch/ppc/include/asm/boot.h index 9b8a7c43c2..296539cd9e 100644 --- a/xen/arch/ppc/include/asm/boot.h +++ b/xen/arch/ppc/include/asm/boot.h @@ -4,7 +4,10 @@ #include -/* a collection of interfaces used during boot. */ +/* + * OpenFirmware boot interfaces + */ + enum { OF_FAILURE = -1, OF_SUCCESS = 0, @@ -20,4 +23,15 @@ struct of_service { int enter_of(struct of_service *args, unsigned long entry); void boot_of_init(unsigned long vec); +/* + * OPAL boot interfaces + */ + +struct opal { +uint64_t base; +uint64_t entry; +}; + +void boot_opal_init(const void *fdt); + #endif /* _ASM_PPC_BOOT_H */ diff --git a/xen/arch/ppc/include/asm/bug.h b/xen/arch/ppc/include/asm/bug.h new file mode 100644 index 00..e5e874b31c --- /dev/null +++ b/xen/arch/ppc/include/asm/bug.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ASM_PPC_BUG_H +#define _ASM_PPC_BUG_H + +#include + +/* + * Power ISA guarantees that an instruction consisting of all zeroes is + * illegal. + */ +#define BUG_OPCODE 0x + +#define BUG_INSTR ".long " __stringify(BUG_OPCODE) + +#define BUG_FN_REG r0 + +#endif /* _ASM_PPC_BUG_H */ diff --git a/xen/arch/ppc/include/asm/cache.h b/xen/arch/ppc/include/asm/cache.h new file mode 100644 index 00..8a0a6b7b17 --- /dev/null +++ b/xen/arch/ppc/include/asm/cache.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ASM_PPC_CACHE_H +#define _ASM_PPC_CACHE_H + +#endif /* _ASM_PPC_CACHE_H */ diff --git a/xen/arch/ppc/include/asm/processor.h b/xen/arch/ppc/include/asm/processor.h index 838d279508..2300640787 100644 --- a/xen/arch/ppc/include/asm/processor.h +++ b/xen/arch/ppc/include/asm/processor.h @@ -133,6 +133,17 @@ struct cpu_user_regs uint32_t entry_vector; }; -#endif +/* + * panic() isn't available at the moment so an infinite loop will be + * used temporarily. + * TODO: change it to panic() + */ +static inline void noreturn die(void) +{ +for ( ; ; ) +HMT_very_low(); +} + +#endif /* __ASSEMBLY__ */ #endif /* _ASM_PPC_PROCESSOR_H */ diff --git a/xen/arch/ppc/include/asm/string.h b/xen/arch/ppc/include/asm/string.h new file mode 100644 index 00..7a420e05e4 --- /dev/null +++ b/xen/arch/ppc/include/asm/string.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ASM_PPC_STRING_H +#define _ASM_PPC_STRING_H + +#endif /* _ASM_PPC_STRING_H */ diff --git a/xen/arch/ppc/include/asm/system.h b
[PATCH 4/4] xen/ppc: Implement early serial console on PowerNV
Implement the OPAL firmware calls required to write to the serial console on PowerNV systems. Unlike pseries/Open Firmware, the OPAL firmware interface can be used past early boot and as such the relevant functions are not marked as __init. Signed-off-by: Shawn Anastasio --- Changed in v2: - Include asm-offsets in asm-defns.h - Clean up assembly formatting in asm-defns.h - Clean up formatting of opal.c - Clean up stray semicolon in OPAL_CALL macro in opal-calls.S xen/arch/ppc/include/asm/asm-defns.h | 18 ++- xen/arch/ppc/opal.c | 28 +- xen/arch/ppc/ppc64/Makefile | 1 + xen/arch/ppc/ppc64/asm-offsets.c | 4 ++ xen/arch/ppc/ppc64/opal-calls.S | 81 5 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 xen/arch/ppc/ppc64/opal-calls.S diff --git a/xen/arch/ppc/include/asm/asm-defns.h b/xen/arch/ppc/include/asm/asm-defns.h index 5821f9024d..f1c49808bd 100644 --- a/xen/arch/ppc/include/asm/asm-defns.h +++ b/xen/arch/ppc/include/asm/asm-defns.h @@ -2,6 +2,8 @@ #ifndef _ASM_PPC_ASM_DEFNS_H #define _ASM_PPC_ASM_DEFNS_H +#include + /* * Load a 64-bit immediate value into the specified GPR. */ @@ -20,8 +22,20 @@ * Load the address of a symbol from the TOC into the specified GPR. */ #define LOAD_REG_ADDR(reg,name) \ -addis reg,%r2,name@toc@ha; \ -addi reg,reg,name@toc@l +addis reg, %r2, name@toc@ha; \ +addi reg, reg, name@toc@l + +/* + * Declare a global assembly function with a proper TOC setup prologue + */ +#define _GLOBAL_TOC(name) \ +.balign 4; \ +.type name, @function; \ +.globl name;\ +name: \ +0: addis %r2, %r12, (.TOC.-0b)@ha; \ +addi %r2, %r2, (.TOC.-0b)@l; \ +.localentry name, .-name /* * Depending on how we were booted, the CPU could be running in either diff --git a/xen/arch/ppc/opal.c b/xen/arch/ppc/opal.c index 251de8ac23..1183b7d5ef 100644 --- a/xen/arch/ppc/opal.c +++ b/xen/arch/ppc/opal.c @@ -8,9 +8,29 @@ #include #include -/* Global OPAL struct containing entrypoint and base */ +/* Global OPAL struct containing entrypoint and base used by opal-calls.S */ struct opal opal; +int64_t opal_console_write(int64_t term_number, uint64_t *length, + const void *buffer); +int64_t opal_console_flush(int64_t term_number); +int64_t opal_reinit_cpus(uint64_t flags); + +static void opal_putchar(char c) +{ +uint64_t len; + +if ( c == '\n' ) +{ +char buf = '\r'; +len = cpu_to_be64(1); +opal_console_write(0, &len, &buf); +} +len = cpu_to_be64(1); +opal_console_write(0, &len, &c); +opal_console_flush(0); +} + void __init boot_opal_init(const void *fdt) { int opal_node; @@ -45,4 +65,10 @@ void __init boot_opal_init(const void *fdt) opal.base = be64_to_cpu(*opal_base); opal.entry = be64_to_cpu(*opal_entry); + +early_printk_init(opal_putchar); + +/* Ask OPAL to set HID0 for Little Endian interrupts + Radix TLB support */ +opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_LE | OPAL_REINIT_CPUS_MMU_RADIX | + OPAL_REINIT_CPUS_MMU_HASH); } diff --git a/xen/arch/ppc/ppc64/Makefile b/xen/arch/ppc/ppc64/Makefile index f4956daaa9..b9a91dc15f 100644 --- a/xen/arch/ppc/ppc64/Makefile +++ b/xen/arch/ppc/ppc64/Makefile @@ -1,2 +1,3 @@ obj-y += head.o obj-y += of-call.o +obj-y += opal-calls.o diff --git a/xen/arch/ppc/ppc64/asm-offsets.c b/xen/arch/ppc/ppc64/asm-offsets.c index e1129cb0f4..c15c1bf136 100644 --- a/xen/arch/ppc/ppc64/asm-offsets.c +++ b/xen/arch/ppc/ppc64/asm-offsets.c @@ -6,6 +6,7 @@ #include #include +#include #define DEFINE(_sym, _val) \ asm volatile ( "\n.ascii\"==>#define " #_sym " %0 /* " #_val " */<==\"" \ @@ -46,6 +47,9 @@ void __dummy__(void) OFFSET(UREGS_cr, struct cpu_user_regs, cr); OFFSET(UREGS_fpscr, struct cpu_user_regs, fpscr); DEFINE(UREGS_sizeof, sizeof(struct cpu_user_regs)); + +OFFSET(OPAL_base, struct opal, base); +OFFSET(OPAL_entry, struct opal, entry); } /* diff --git a/xen/arch/ppc/ppc64/opal-calls.S b/xen/arch/ppc/ppc64/opal-calls.S new file mode 100644 index 00..cc5de75c8a --- /dev/null +++ b/xen/arch/ppc/ppc64/opal-calls.S @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Adapted from Linux's arch/pow
[PATCH 2/4] xen/ppc: Add OPAL API definition header file
OPAL (OpenPower Abstraction Layer) is the interface exposed by firmware on PowerNV (bare metal) systems. Import Linux's header definining the API and related information. >From Linux commit 5321d1b1afb9a17302c6cec79f0cbf823eb0d3fc Signed-off-by: Shawn Anastasio --- Changed in v2: - Add Linux commit reference to commit message xen/arch/ppc/include/asm/opal-api.h | 1190 +++ 1 file changed, 1190 insertions(+) create mode 100644 xen/arch/ppc/include/asm/opal-api.h diff --git a/xen/arch/ppc/include/asm/opal-api.h b/xen/arch/ppc/include/asm/opal-api.h new file mode 100644 index 00..75100eda83 --- /dev/null +++ b/xen/arch/ppc/include/asm/opal-api.h @@ -0,0 +1,1190 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * OPAL API definitions. + * + * Copyright 2011-2015 IBM Corp. + */ + +#ifndef __OPAL_API_H +#define __OPAL_API_H + +/** OPAL APIs **/ + +/* Return codes */ +#define OPAL_SUCCESS 0 +#define OPAL_PARAMETER -1 +#define OPAL_BUSY -2 +#define OPAL_PARTIAL -3 +#define OPAL_CONSTRAINED -4 +#define OPAL_CLOSED-5 +#define OPAL_HARDWARE -6 +#define OPAL_UNSUPPORTED -7 +#define OPAL_PERMISSION-8 +#define OPAL_NO_MEM-9 +#define OPAL_RESOURCE -10 +#define OPAL_INTERNAL_ERROR-11 +#define OPAL_BUSY_EVENT-12 +#define OPAL_HARDWARE_FROZEN -13 +#define OPAL_WRONG_STATE -14 +#define OPAL_ASYNC_COMPLETION -15 +#define OPAL_EMPTY -16 +#define OPAL_I2C_TIMEOUT -17 +#define OPAL_I2C_INVALID_CMD -18 +#define OPAL_I2C_LBUS_PARITY -19 +#define OPAL_I2C_BKEND_OVERRUN -20 +#define OPAL_I2C_BKEND_ACCESS -21 +#define OPAL_I2C_ARBT_LOST -22 +#define OPAL_I2C_NACK_RCVD -23 +#define OPAL_I2C_STOP_ERR -24 +#define OPAL_XIVE_PROVISIONING -31 +#define OPAL_XIVE_FREE_ACTIVE -32 +#define OPAL_TIMEOUT -33 + +/* API Tokens (in r0) */ +#define OPAL_INVALID_CALL -1 +#define OPAL_TEST 0 +#define OPAL_CONSOLE_WRITE 1 +#define OPAL_CONSOLE_READ 2 +#define OPAL_RTC_READ 3 +#define OPAL_RTC_WRITE 4 +#define OPAL_CEC_POWER_DOWN5 +#define OPAL_CEC_REBOOT6 +#define OPAL_READ_NVRAM7 +#define OPAL_WRITE_NVRAM 8 +#define OPAL_HANDLE_INTERRUPT 9 +#define OPAL_POLL_EVENTS 10 +#define OPAL_PCI_SET_HUB_TCE_MEMORY11 +#define OPAL_PCI_SET_PHB_TCE_MEMORY12 +#define OPAL_PCI_CONFIG_READ_BYTE 13 +#define OPAL_PCI_CONFIG_READ_HALF_WORD 14 +#define OPAL_PCI_CONFIG_READ_WORD 15 +#define OPAL_PCI_CONFIG_WRITE_BYTE 16 +#define OPAL_PCI_CONFIG_WRITE_HALF_WORD17 +#define OPAL_PCI_CONFIG_WRITE_WORD 18 +#define OPAL_SET_XIVE 19 +#define OPAL_GET_XIVE 20 +#define OPAL_GET_COMPLETION_TOKEN_STATUS 21 /* obsolete */ +#define OPAL_REGISTER_OPAL_EXCEPTION_HANDLER 22 +#define OPAL_PCI_EEH_FREEZE_STATUS 23 +#define OPAL_PCI_SHPC 24 +#define OPAL_CONSOLE_WRITE_BUFFER_SPACE25 +#define OPAL_PCI_EEH_FREEZE_CLEAR 26 +#define OPAL_PCI_PHB_MMIO_ENABLE 27 +#define OPAL_PCI_SET_PHB_MEM_WINDOW28 +#define OPAL_PCI_MAP_PE_MMIO_WINDOW29 +#define OPAL_PCI_SET_PHB_TABLE_MEMORY 30 +#define OPAL_PCI_SET_PE31 +#define OPAL_PCI_SET_PELTV 32 +#define OPAL_PCI_SET_MVE 33 +#define OPAL_PCI_SET_MVE_ENABLE34 +#define OPAL_PCI_GET_XIVE_REISSUE 35 +#define OPAL_PCI_SET_XIVE_REISSUE 36 +#define OPAL_PCI_SET_XIVE_PE 37 +#define OPAL_GET_XIVE_SOURCE 38 +#define OPAL_GET_MSI_3239 +#define OPAL_GET_MSI_6440 +#define OPAL_START_CPU 41 +#define OPAL_QUERY_CPU_STATUS 42 +#define OPAL_WRITE_OPPANEL 43 /* unimplemented */ +#define OPAL_PCI_MAP_PE_DMA_WINDOW 44 +#define OPAL_PCI_MAP_PE_DMA_WINDOW_REAL45 +#define OPAL_PCI_RESET 49 +#define OPAL_PCI_GET_HUB_DIAG_DATA 50 +#define OPAL_PCI_GET_PHB_DIAG_DATA 51 +#define OPAL_PCI_FENCE_PHB 52 +#define OPAL_PCI_REINIT53 +#define OPAL_PCI_MASK_PE_ERROR 54 +#define OPAL_SET_SLOT_LED_STATUS 55 +#define OPAL_GET_EPOW_STATUS 56 +#define OPAL_SET_SYSTEM_ATTENTION_LED 57 +#define OPAL_RESERVED1 58
[PATCH 1/4] xen/ppc: Switch to medium PIC code model
Switch Xen to the medium PIC code model on Power. Among other things, this allows us to be load address agnostic and will open the door to booting on bare metal PowerNV systems that don't use OpenFirmware. Also update XEN_VIRT_START to 0xc000, which is equivalent to address 0x0 when the MMU is off. This prevents Open Firmware from loading Xen at an offset from its base load address, so the DECL_SECTION hack in xen.lds.S is no longer required. Signed-off-by: Shawn Anastasio --- Changed in v2: - Remove stray newline - Use label instead of .+4 in TOC setup branch xen/arch/ppc/arch.mk | 2 +- xen/arch/ppc/include/asm/asm-defns.h | 7 + xen/arch/ppc/include/asm/config.h| 2 +- xen/arch/ppc/ppc64/head.S| 12 +--- xen/arch/ppc/xen.lds.S | 44 ++-- 5 files changed, 33 insertions(+), 34 deletions(-) diff --git a/xen/arch/ppc/arch.mk b/xen/arch/ppc/arch.mk index 7eec22c283..0183b9ac6a 100644 --- a/xen/arch/ppc/arch.mk +++ b/xen/arch/ppc/arch.mk @@ -5,7 +5,7 @@ ppc-march-$(CONFIG_POWER_ISA_2_07B) := power8 ppc-march-$(CONFIG_POWER_ISA_3_00) := power9 CFLAGS += -m64 -mlittle-endian -mcpu=$(ppc-march-y) -CFLAGS += -mstrict-align -mcmodel=large -mabi=elfv2 -mno-altivec -mno-vsx +CFLAGS += -mstrict-align -mcmodel=medium -mabi=elfv2 -fPIC -mno-altivec -mno-vsx -msoft-float LDFLAGS += -m elf64lppc diff --git a/xen/arch/ppc/include/asm/asm-defns.h b/xen/arch/ppc/include/asm/asm-defns.h index 35b1c89d4e..5821f9024d 100644 --- a/xen/arch/ppc/include/asm/asm-defns.h +++ b/xen/arch/ppc/include/asm/asm-defns.h @@ -16,6 +16,13 @@ lis reg, (val) @h; \ ori reg, reg, (val) @l; \ +/* + * Load the address of a symbol from the TOC into the specified GPR. + */ +#define LOAD_REG_ADDR(reg,name) \ +addis reg,%r2,name@toc@ha; \ +addi reg,reg,name@toc@l + /* * Depending on how we were booted, the CPU could be running in either * Little Endian or Big Endian mode. The following trampoline from Linux diff --git a/xen/arch/ppc/include/asm/config.h b/xen/arch/ppc/include/asm/config.h index cb27d2781e..d060f0dca7 100644 --- a/xen/arch/ppc/include/asm/config.h +++ b/xen/arch/ppc/include/asm/config.h @@ -39,7 +39,7 @@ name: #endif -#define XEN_VIRT_START _AT(UL, 0x40) +#define XEN_VIRT_START _AT(UL, 0xc000) #define SMP_CACHE_BYTES (1 << 6) diff --git a/xen/arch/ppc/ppc64/head.S b/xen/arch/ppc/ppc64/head.S index 02ff520458..4172f1b8ec 100644 --- a/xen/arch/ppc/ppc64/head.S +++ b/xen/arch/ppc/ppc64/head.S @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include +#include .section .text.header, "ax", %progbits @@ -11,16 +12,19 @@ ENTRY(start) FIXUP_ENDIAN /* set up the TOC pointer */ -LOAD_IMM32(%r2, .TOC.) +bcl20, 31, 1f +1: mflr%r12 +addis %r2, %r12, .TOC.-1b@ha +addi%r2, %r2, .TOC.-1b@l /* set up the initial stack */ -LOAD_IMM32(%r1, cpu0_boot_stack) +LOAD_REG_ADDR(%r1, cpu0_boot_stack) li %r11, 0 stdu%r11, -STACK_FRAME_OVERHEAD(%r1) /* clear .bss */ -LOAD_IMM32(%r14, __bss_start) -LOAD_IMM32(%r15, __bss_end) +LOAD_REG_ADDR(%r14, __bss_start) +LOAD_REG_ADDR(%r15, __bss_end) 1: std %r11, 0(%r14) addi%r14, %r14, 8 diff --git a/xen/arch/ppc/xen.lds.S b/xen/arch/ppc/xen.lds.S index c628cc0e5c..2fa81d5a83 100644 --- a/xen/arch/ppc/xen.lds.S +++ b/xen/arch/ppc/xen.lds.S @@ -15,25 +15,12 @@ PHDRS #endif } -/** - * OpenFirmware's base load address is 0x40 (XEN_VIRT_START). - * By defining sections this way, we can keep our virtual address base at 0x40 - * while keeping the physical base at 0x0. - * - * Otherwise, OpenFirmware incorrectly loads .text at 0x40 + 0x40 = 0x80. - * Taken from x86/xen.lds.S - */ -#ifdef CONFIG_LD_IS_GNU -# define DECL_SECTION(x) x : AT(ADDR(#x) - XEN_VIRT_START) -#else -# define DECL_SECTION(x) x : AT(ADDR(x) - XEN_VIRT_START) -#endif - SECTIONS { . = XEN_VIRT_START; +_start = .; -DECL_SECTION(.text) { +.text : { _stext = .;/* Text section */ *(.text.header) @@ -52,7 +39,7 @@ SECTIONS } :text . = ALIGN(PAGE_SIZE); -DECL_SECTION(.rodata) { +.rodata : { _srodata = .; /* Read-only data */ *(.rodata) *(.rodata.*) @@ -67,7 +54,7 @@ SECTIONS #if defined(BUILD_ID) . = ALIGN(4); -DECL_SECTION(.note.gnu.build-id) { +.note.gnu.build-id : { __note_gnu_build_id_start = .; *(.note.gnu.build-id) __note_gnu_build_id_end = .; @@ -76,19 +63,19 @@ SECTIONS _erodata = .;/* End of read-only data */ . = ALIGN(PAG
Re: [PATCH 0/4] xen/ppc: Add PowerNV bare metal support
On 8/1/23 7:11 PM, Shawn Anastasio wrote: > Hello all, Apologies, the subject should indicate that this is a v2 but I forgot to pass the appropriate argument to git-send-email. Thanks, Shawn
[PATCH 1/9] xen/common: Add missing #includes treewide
A few files treewide depend on defininitions in headers that they don't include. This works when arch headers end up including the required headers by chance, but broke on ppc64 with only minimal/stub arch headers. Signed-off-by: Shawn Anastasio --- xen/common/memory.c | 1 + xen/common/symbols.c | 1 + xen/common/xmalloc_tlsf.c | 1 + xen/include/xen/domain.h | 1 + xen/include/xen/iommu.h | 1 + xen/include/xen/sched.h | 1 + 6 files changed, 6 insertions(+) diff --git a/xen/common/memory.c b/xen/common/memory.c index c206fa4808..1b185b00e4 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/xen/common/symbols.c b/xen/common/symbols.c index 9377f41424..691e617925 100644 --- a/xen/common/symbols.c +++ b/xen/common/symbols.c @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef SYMBOLS_ORIGIN extern const unsigned int symbols_offsets[]; diff --git a/xen/common/xmalloc_tlsf.c b/xen/common/xmalloc_tlsf.c index c603c39bb9..349b31cb4c 100644 --- a/xen/common/xmalloc_tlsf.c +++ b/xen/common/xmalloc_tlsf.c @@ -27,6 +27,7 @@ #include #include #include +#include #define MAX_POOL_NAME_LEN 16 diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h index d35af34841..767127b440 100644 --- a/xen/include/xen/domain.h +++ b/xen/include/xen/domain.h @@ -4,6 +4,7 @@ #include +#include #include #include #include diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h index 405db59971..ef817efec9 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 854f3e32c0..6a96534a45 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include -- 2.30.2
[PATCH 4/9] xen/ppc: Implement bitops.h
Implement bitops.h, based on Linux's implementation as of commit 5321d1b1afb9a17302c6cec79f0cbf823eb0d3fc Signed-off-by: Shawn Anastasio --- xen/arch/ppc/include/asm/bitops.h | 331 +- 1 file changed, 327 insertions(+), 4 deletions(-) diff --git a/xen/arch/ppc/include/asm/bitops.h b/xen/arch/ppc/include/asm/bitops.h index a7cd8ec7c5..286f68cbfe 100644 --- a/xen/arch/ppc/include/asm/bitops.h +++ b/xen/arch/ppc/include/asm/bitops.h @@ -1,11 +1,334 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Adapted from Linux's arch/powerpc/include/asm/bitops.h. + * + * Merged version by David Gibson . + * Based on ppc64 versions by: Dave Engebretsen, Todd Inglett, Don + * Reed, Pat McCarthy, Peter Bergner, Anton Blanchard. They + * originally took it from the ppc32 code. + */ #ifndef _ASM_PPC_BITOPS_H #define _ASM_PPC_BITOPS_H -#include +#define __set_bit(n,p)set_bit(n,p) +#define __clear_bit(n,p) clear_bit(n,p) + +#define BITOP_BITS_PER_WORD 32 +#define BITOP_MASK(nr) (1UL << ((nr) % BITOP_BITS_PER_WORD)) +#define BITOP_WORD(nr) ((nr) / BITOP_BITS_PER_WORD) +#define BITS_PER_BYTE 8 /* PPC bit number conversion */ -#define PPC_BITLSHIFT(be) (BITS_PER_LONG - 1 - (be)) -#define PPC_BIT(bit) (1UL << PPC_BITLSHIFT(bit)) -#define PPC_BITMASK(bs, be)((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) +#define PPC_BITLSHIFT(be)(BITS_PER_LONG - 1 - (be)) +#define PPC_BIT(bit) (1UL << PPC_BITLSHIFT(bit)) +#define PPC_BITMASK(bs, be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) + +/* Macro for generating the ***_bits() functions */ +#define DEFINE_BITOP(fn, op, prefix)\ +static inline void fn(unsigned long mask,\ +volatile unsigned int *_p) \ +{ \ +unsigned long old; \ +unsigned int *p = (unsigned int *)_p;\ +__asm__ __volatile__ ( \ +prefix \ +"1: lwarx %0,0,%3,0\n" \ +#op "%I2 %0,%0,%2\n"\ +"stwcx. %0,0,%3\n" \ +"bne- 1b\n" \ +: "=&r" (old), "+m" (*p)\ +: "rK" (mask), "r" (p) \ +: "cc", "memory"); \ +} + +DEFINE_BITOP(set_bits, or, "") +DEFINE_BITOP(change_bits, xor, "") + +#define DEFINE_CLROP(fn, prefix)\ +static inline void fn(unsigned long mask, volatile unsigned int *_p)\ +{\ +unsigned long old;\ +unsigned int *p = (unsigned int *)_p;\ + \ +asm volatile ( \ + prefix \ + "1: lwarx %0,0,%3,0\n" \ +"andc %0,%0,%2\n" \ +"stwcx. %0,0,%3\n" \ +"bne- 1b\n"\ +: "=&r" (old), "+m" (*p)\ +: "r" (mask), "r" (p) \ +: "cc", "memory"); \ +} + +DEFINE_CLROP(clear_bits, "") + +static inline void set_bit(int nr, volatile void *addr) +{ +set_bits(BITOP_MASK(nr), (volatile unsigned int *)addr + BITOP_WORD(nr)); +} +static inline void clear_bit(int nr, volatile void *addr) +{ +clear_bits(BITOP_MASK(nr), (volatile unsigned int *)addr + BITOP_WORD(nr)); +} + +/** + * test_bit - Determine whether a bit is set + * @nr: bit number to test + * @addr: Address to start counting from + */ +static inline int test_bit(int nr, const volatile void *addr) +{ +const volatile unsigned long *p = (const volatile unsigned long *)addr; +return 1UL & (p[BITOP_WORD(nr)] >> (nr & (BITOP_BITS_PER_WORD-1))); +} + +static inline unsigned long test_and_clear_bits(unsigned long mask, volatile void *_p) +{ +unsigned long old, t; +unsigned int *p = (unsigned int *)_p; + +asm volatile ( + "sync\n" +"1:" "lwarx %0,0,%3,0\n" +"andc%1,%0,%2\n" +"stwcx. %1,0,%3\n" +"bne- 1b\n" + "sync\n" +: "=&r" (old), "=&r" (t) +: "r" (mask), "r" (p) +: "cc", "memory"); + +return (old & mask); +} + +static inline int test_and_clear_bit(unsigned int nr, + volatile void *addr) +{ + return test_and_clear_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr)) != 0; +
[PATCH 3/9] xen/ppc: Implement atomic.h
Implement atomic.h for PPC, based off of the original Xen 3.2 implementation. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/include/asm/atomic.h | 387 ++ xen/arch/ppc/include/asm/memory.h | 34 +++ 2 files changed, 421 insertions(+) create mode 100644 xen/arch/ppc/include/asm/atomic.h create mode 100644 xen/arch/ppc/include/asm/memory.h diff --git a/xen/arch/ppc/include/asm/atomic.h b/xen/arch/ppc/include/asm/atomic.h new file mode 100644 index 00..336dedc476 --- /dev/null +++ b/xen/arch/ppc/include/asm/atomic.h @@ -0,0 +1,387 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * PowerPC64 atomic operations + * + * Copyright (C) 2001 Paul Mackerras , IBM + * Copyright (C) 2001 Anton Blanchard , IBM + * Copyright Raptor Engineering LLC + * + * 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_PPC64_ATOMIC_H_ +#define _ASM_PPC64_ATOMIC_H_ + +#include + +#include +#include + +static inline int atomic_read(const atomic_t *v) +{ +return *(volatile int *)&v->counter; +} + +static inline int _atomic_read(atomic_t v) +{ +return v.counter; +} + +static inline void atomic_set(atomic_t *v, int i) +{ +v->counter = i; +} + +static inline void _atomic_set(atomic_t *v, int i) +{ +v->counter = i; +} + +void __bad_atomic_read(const volatile void *p, void *res); +void __bad_atomic_size(void); + +#define build_atomic_read(name, insn, type) \ +static inline type name(const volatile type *addr) \ +{ \ +type ret; \ +asm volatile ( insn "%U1%X1 %0,%1" : "=r"(ret) : "m<>"(*addr) ); \ +return ret; \ +} + +#define build_atomic_write(name, insn, type) \ +static inline void name(volatile type *addr, type val) \ +{ \ +asm volatile ( insn "%U0%X0 %1,%0" : "=m<>"(*addr) : "r"(val) ); \ +} + +#define build_add_sized(name, ldinsn, stinsn, type) \ +static inline void name(volatile type *addr, type val) \ +{ \ +type t; \ +asm volatile ( "1: " ldinsn " %0,0,%3\n" \ + "add%I2 %0,%0,%2\n" \ + stinsn " %0,0,%3 \n" \ + "bne- 1b\n" \ + : "=&r"(t), "+m"(*addr) \ + : "r"(val), "r"(addr) \ + : "cc" ); \ +} + +build_atomic_read(read_u8_atomic, "lbz", uint8_t) +build_atomic_read(read_u16_atomic, "lhz", uint16_t) +build_atomic_read(read_u32_atomic, "lwz", uint32_t) +build_atomic_read(read_u64_atomic, "ldz", uint64_t) + +build_atomic_write(write_u8_atomic, "stb", uint8_t) +build_atomic_write(write_u16_atomic, "sth", uint16_t) +build_atomic_write(write_u32_atomic, "stw", uint32_t) +build_atomic_write(write_u64_atomic, "std", uint64_t) + +build_add_sized(add_u8_sized, "lbarx", "stbcx.",uint8_t) +build_add_sized(add_u16_sized, "lharx", "sthcx.", uint16_t) +build_add_sized(add_u32_sized, "lwarx", "stwcx.", uint32_t) + +#undef build_atomic_read +#undef build_atomic_write +#undef build_add_sized + +static always_inline void read_atomic_size(const volatile void *p, void *res, + unsigned int size) +{ +ASSERT(IS_ALIGNED((vaddr_t) p, size)); +switch ( size ) +{ +case 1: +*(uint8_t *)res = read_u8_atomic(p); +break; +case 2: +*(uint16_t *)res = read_u16_atomic(p); +break; +case 4: +*(uint32_t *)res = read_u32_atomic(p); +break; +case 8: +*(uint64_t *)res = read_u64_atomic(p); +break; +default: +__bad_atomic_read(p, res); +break; +} +} + +static alw
[PATCH 2/9] xen/ppc: Add public/arch-ppc.h
Signed-off-by: Shawn Anastasio --- xen/include/public/arch-ppc.h | 140 ++ 1 file changed, 140 insertions(+) create mode 100644 xen/include/public/arch-ppc.h diff --git a/xen/include/public/arch-ppc.h b/xen/include/public/arch-ppc.h new file mode 100644 index 00..0eb7ce4208 --- /dev/null +++ b/xen/include/public/arch-ppc.h @@ -0,0 +1,140 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (C) IBM Corp. 2005, 2006 + * Copyright (C) Raptor Engineering, LLC 2023 + * + * Authors: Hollis Blanchard + * Timothy Pearson + */ + +#ifndef __XEN_PUBLIC_ARCH_PPC64_H__ +#define __XEN_PUBLIC_ARCH_PPC64_H__ + +#define int64_aligned_t int64_t __attribute__((aligned(8))) +#define uint64_aligned_t uint64_t __attribute__((aligned(8))) + +#ifndef __ASSEMBLY__ +#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ +typedef union { type *p; unsigned long q; } \ +__guest_handle_ ## name;\ +typedef union { type *p; uint64_aligned_t q; } \ +__guest_handle_64_ ## name + +#define __DEFINE_XEN_GUEST_HANDLE(name, type) \ +___DEFINE_XEN_GUEST_HANDLE(name, type); \ +___DEFINE_XEN_GUEST_HANDLE(const_##name, const type) +#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name) +#define __XEN_GUEST_HANDLE(name)__guest_handle_64_ ## name +#define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name) +#define XEN_GUEST_HANDLE_PARAM(name)__guest_handle_ ## name +#define set_xen_guest_handle_raw(hnd, val) \ +do {\ +__typeof__(&(hnd)) _sxghr_tmp = &(hnd); \ +_sxghr_tmp->q = 0; \ +_sxghr_tmp->p = val;\ +} while ( 0 ) +#define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val) + +#ifdef __XEN_TOOLS__ +#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) +#endif + +typedef uint64_t xen_pfn_t; +#define PRI_xen_pfn PRIx64 +#define PRIu_xen_pfn PRIu64 + +/* + * Maximum number of virtual CPUs in legacy multi-processor guests. + * Only one. All other VCPUS must use VCPUOP_register_vcpu_info. + */ +#define XEN_LEGACY_MAX_VCPUS 1 + +typedef uint64_t xen_ulong_t; +#define PRI_xen_ulong PRIx64 +#endif + +/* + * Pointers and other address fields inside interface structures are padded to + * 64 bits. This means that field alignments aren't different between 32- and + * 64-bit architectures. + */ +/* NB. Multi-level macro ensures __LINE__ is expanded before concatenation. */ +#define __MEMORY_PADDING(_X) +#define _MEMORY_PADDING(_X) __MEMORY_PADDING(_X) +#define MEMORY_PADDING _MEMORY_PADDING(__LINE__) + +/* And the trap vector is... */ +#define TRAP_INSTR "li 0,-1; sc" /* XXX just "sc"? */ + +#ifndef __ASSEMBLY__ + +#define XENCOMM_INLINE_FLAG (1UL << 63) + +typedef uint64_t xen_ulong_t; + +/* User-accessible registers: nost of these need to be saved/restored + * for every nested Xen invocation. */ +struct vcpu_guest_core_regs +{ +uint64_t gprs[32]; +uint64_t lr; +uint64_t ctr; +uint64_t srr0; +uint64_t srr1; +uint64_t pc; +uint64_t msr; +uint64_t fpscr; /* XXX Is this necessary */ +uint64_t xer; +uint64_t hid4; /* debug only */ +uint64_t dar; /* debug only */ +uint32_t dsisr; /* debug only */ +uint32_t cr; +uint32_t __pad; /* good spot for another 32bit reg */ +uint32_t entry_vector; +}; +typedef struct vcpu_guest_core_regs vcpu_guest_core_regs_t; + +typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */ /* XXX timebase */ + +/* ONLY used to communicate with dom0! See also struct exec_domain. */ +struct vcpu_guest_conte
[PATCH 0/9] ppc: Enable full Xen build
Hello all, This patch series performs all of the additions necessary to drop the build overrides for PPC and enable the full Xen build. Except in cases where compatibile implementations already exist (e.g. atomic.h and bitops.h), the newly added definitions are simple, unimplemented stubs that just call BUG(). A few miscellaneous changes were also made to non-ppc code as well, namely a few missing header fixes as well as an ARM-ism in the ns16550 driver. Thanks, Shawn Shawn Anastasio (9): xen/common: Add missing #includes treewide xen/ppc: Add public/arch-ppc.h xen/ppc: Implement atomic.h xen/ppc: Implement bitops.h xen/ppc: Define minimal stub headers required for full build ns16550: Guard accesses to `vuart` field by CONFIG_ARM xen/ppc: Define bug frames table in linker script xen/ppc: Add stub function and symbol definitions xen/ppc: Enable full Xen build xen/arch/ppc/Kconfig | 1 + xen/arch/ppc/Makefile| 17 +- xen/arch/ppc/arch.mk | 3 - xen/arch/ppc/include/asm/altp2m.h| 39 +++ xen/arch/ppc/include/asm/atomic.h| 387 +++ xen/arch/ppc/include/asm/bitops.h| 331 ++- xen/arch/ppc/include/asm/bug.h | 7 + xen/arch/ppc/include/asm/cache.h | 2 + xen/arch/ppc/include/asm/config.h| 9 + xen/arch/ppc/include/asm/cpufeature.h| 9 + xen/arch/ppc/include/asm/current.h | 42 +++ xen/arch/ppc/include/asm/delay.h | 11 + xen/arch/ppc/include/asm/desc.h | 0 xen/arch/ppc/include/asm/device.h| 53 xen/arch/ppc/include/asm/div64.h | 14 + xen/arch/ppc/include/asm/domain.h| 46 +++ xen/arch/ppc/include/asm/event.h | 35 ++ xen/arch/ppc/include/asm/flushtlb.h | 23 ++ xen/arch/ppc/include/asm/grant_table.h | 0 xen/arch/ppc/include/asm/guest_access.h | 54 xen/arch/ppc/include/asm/guest_atomics.h | 14 + xen/arch/ppc/include/asm/hardirq.h | 18 ++ xen/arch/ppc/include/asm/hypercall.h | 0 xen/arch/ppc/include/asm/io.h| 15 + xen/arch/ppc/include/asm/iocap.h | 7 + xen/arch/ppc/include/asm/iommu.h | 7 + xen/arch/ppc/include/asm/irq.h | 32 ++ xen/arch/ppc/include/asm/mem_access.h| 0 xen/arch/ppc/include/asm/memory.h| 34 ++ xen/arch/ppc/include/asm/mm.h| 255 ++- xen/arch/ppc/include/asm/monitor.h | 48 +++ xen/arch/ppc/include/asm/nospec.h| 18 ++ xen/arch/ppc/include/asm/numa.h | 26 ++ xen/arch/ppc/include/asm/p2m.h | 105 ++ xen/arch/ppc/include/asm/page.h | 19 ++ xen/arch/ppc/include/asm/paging.h| 7 + xen/arch/ppc/include/asm/pci.h | 7 + xen/arch/ppc/include/asm/percpu.h| 26 ++ xen/arch/ppc/include/asm/procarea.h | 38 +++ xen/arch/ppc/include/asm/processor.h | 6 + xen/arch/ppc/include/asm/random.h| 9 + xen/arch/ppc/include/asm/regs.h | 2 + xen/arch/ppc/include/asm/setup.h | 6 + xen/arch/ppc/include/asm/smp.h | 18 ++ xen/arch/ppc/include/asm/softirq.h | 8 + xen/arch/ppc/include/asm/spinlock.h | 15 + xen/arch/ppc/include/asm/system.h| 243 +- xen/arch/ppc/include/asm/time.h | 20 ++ xen/arch/ppc/include/asm/vm_event.h | 49 +++ xen/arch/ppc/include/asm/xenoprof.h | 0 xen/arch/ppc/mm-radix.c | 46 ++- xen/arch/ppc/opal.c | 2 - xen/arch/ppc/setup.c | 10 +- xen/arch/ppc/stubs.c | 351 xen/arch/ppc/tlb-radix.c | 2 +- xen/arch/ppc/xen.lds.S | 10 + xen/common/memory.c | 1 + xen/common/symbols.c | 1 + xen/common/xmalloc_tlsf.c| 1 + xen/drivers/char/ns16550.c | 2 + xen/include/public/arch-ppc.h| 140 xen/include/public/hvm/save.h| 2 + xen/include/public/pmu.h | 2 + xen/include/public/xen.h | 2 + xen/include/xen/domain.h | 1 + xen/include/xen/iommu.h | 1 + xen/include/xen/sched.h | 1 + 67 files changed, 2693 insertions(+), 17 deletions(-) create mode 100644 xen/arch/ppc/include/asm/altp2m.h create mode 100644 xen/arch/ppc/include/asm/atomic.h create mode 100644 xen/arch/ppc/include/asm/cpufeature.h create mode 100644 xen/arch/ppc/include/asm/current.h create mode 100644 xen/arch/ppc/include/asm/delay.h create mode 100644 xen/arch/ppc/include/asm/desc.h create mode 100644 xen/arch/ppc/include/asm/device.h create mode 100644 xen/arch/ppc/include/asm/div64.h create mode 100644 xen/arch/ppc/include/asm/domain.h create mode 100644 xen/arch/ppc/include/asm/event.h create mode 100644 xen/arch/ppc
[PATCH 8/9] xen/ppc: Add stub function and symbol definitions
Add stub function and symbol definitions required by common code. If the file that the definition is supposed to be located in doesn't already exist yet, temporarily place its definition in the new stubs.c Signed-off-by: Shawn Anastasio --- xen/arch/ppc/Makefile | 1 + xen/arch/ppc/mm-radix.c | 44 + xen/arch/ppc/setup.c| 10 +- xen/arch/ppc/stubs.c| 351 4 files changed, 404 insertions(+), 2 deletions(-) create mode 100644 xen/arch/ppc/stubs.c diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile index a059ac4c0a..969910b3b6 100644 --- a/xen/arch/ppc/Makefile +++ b/xen/arch/ppc/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.init.o obj-y += mm-radix.o obj-y += opal.o obj-y += setup.o +obj-y += stubs.o obj-y += tlb-radix.o $(TARGET): $(TARGET)-syms diff --git a/xen/arch/ppc/mm-radix.c b/xen/arch/ppc/mm-radix.c index 399898a36d..1ed6897366 100644 --- a/xen/arch/ppc/mm-radix.c +++ b/xen/arch/ppc/mm-radix.c @@ -266,3 +266,47 @@ void __init setup_initial_pagetables(void) /* Turn on the MMU */ enable_mmu(); } + + +/* + * TODO: Implement the functions below + */ +unsigned long total_pages; +unsigned long frametable_base_pdx __read_mostly; + +void put_page(struct page_info *p) +{ +BUG(); +} + +void arch_dump_shared_mem_info(void) +{ +BUG(); +} + +int xenmem_add_to_physmap_one(struct domain *d, + unsigned int space, + union add_to_physmap_extra extra, + unsigned long idx, + gfn_t gfn) +{ +BUG(); +} + +int destroy_xen_mappings(unsigned long s, unsigned long e) +{ +BUG(); +} + +int map_pages_to_xen(unsigned long virt, + mfn_t mfn, + unsigned long nr_mfns, + unsigned int flags) +{ +BUG(); +} + +int __init populate_pt_range(unsigned long virt, unsigned long nr_mfns) +{ +BUG(); +} diff --git a/xen/arch/ppc/setup.c b/xen/arch/ppc/setup.c index 466993987b..06c0a5fa80 100644 --- a/xen/arch/ppc/setup.c +++ b/xen/arch/ppc/setup.c @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include #include +#include +#include #include #include #include @@ -7,8 +10,6 @@ /* Xen stack for bringing up the first CPU. */ unsigned char __initdata cpu0_boot_stack[STACK_SIZE] __aligned(STACK_SIZE); -void __init setup_initial_pagetables(void); - void __init noreturn start_xen(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) @@ -39,3 +40,8 @@ void __init noreturn start_xen(unsigned long r3, unsigned long r4, unreachable(); } + +void arch_get_xen_caps(xen_capabilities_info_t *info) +{ +BUG(); +} diff --git a/xen/arch/ppc/stubs.c b/xen/arch/ppc/stubs.c new file mode 100644 index 00..2b3ee94115 --- /dev/null +++ b/xen/arch/ppc/stubs.c @@ -0,0 +1,351 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include +#include +#include +#include +#include +#include +#include + +#include + +/* smpboot.c */ + +cpumask_t cpu_online_map; +cpumask_t cpu_present_map; +cpumask_t cpu_possible_map; + +/* ID of the PCPU we're running on */ +DEFINE_PER_CPU(unsigned int, cpu_id); +/* XXX these seem awfully x86ish... */ +/* representing HT siblings of each logical CPU */ +DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_mask); +/* representing HT and core siblings of each logical CPU */ +DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_mask); + +nodemask_t __read_mostly node_online_map = { { [0] = 1UL } }; + +/* time.c */ + +s_time_t get_s_time(void) +{ +BUG(); +} + +int reprogram_timer(s_time_t timeout) +{ +BUG(); +} + +void send_timer_event(struct vcpu *v) +{ +BUG(); +} + +/* traps.c */ + +void show_execution_state(const struct cpu_user_regs *regs) +{ +BUG(); +} + +void arch_hypercall_tasklet_result(struct vcpu *v, long res) +{ +BUG(); +} + +void vcpu_show_execution_state(struct vcpu *v) +{ +BUG(); +} + +/* shutdown.c */ + +void machine_restart(unsigned int delay_millisecs) +{ +BUG(); +} + +void machine_halt(void) +{ +BUG(); +} + +/* vm_event.c */ + +void vm_event_fill_regs(vm_event_request_t *req) +{ +BUG(); +} + +void vm_event_set_registers(struct vcpu *v, vm_event_response_t *rsp) +{ +BUG(); +} + +void vm_event_monitor_next_interrupt(struct vcpu *v) +{ +/* Not supported on PPC. */ +} + +/* domctl.c */ +void arch_get_domain_info(const struct domain *d, + struct xen_domctl_getdomaininfo *info) +{ +BUG(); +} + +/* monitor.c */ + +int arch_monitor_domctl_event(struct domain *d, + struct xen_domctl_monitor_op *mop) +{ +BUG(); +} + +/* smp.c */ + +void arch_flush_tlb_mask(const cpumask_t *mask) +{ +BUG(); +} + +void smp_send_event_check_mask(const cpumask_t *mask) +{ +BUG();
[PATCH 6/9] ns16550: Guard accesses to `vuart` field by CONFIG_ARM
When CONFIG_ARM is defined, a `vuart` field is added to struct ns16550, but accesses to this field in ns16550_uart_dt_init weren't correctly guarded. Fix build on !ARM platforms that define CONFIG_HAS_DEVICE_TREE by correctly guarding access to the vuart field in this function. Signed-off-by: Shawn Anastasio --- xen/drivers/char/ns16550.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c index 212a9c49ae..c0598efb27 100644 --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -1797,11 +1797,13 @@ static int __init ns16550_uart_dt_init(struct dt_device_node *dev, uart->dw_usr_bsy = dt_device_is_compatible(dev, "snps,dw-apb-uart"); +#ifdef CONFIG_ARM uart->vuart.base_addr = uart->io_base; uart->vuart.size = uart->io_size; uart->vuart.data_off = UART_THR <reg_shift; uart->vuart.status_off = UART_LSR<reg_shift; uart->vuart.status = UART_LSR_THRE|UART_LSR_TEMT; +#endif /* Register with generic serial driver. */ serial_register_uart(uart - ns16550_com, &ns16550_driver, uart); -- 2.30.2
[PATCH 7/9] xen/ppc: Define bug frames table in linker script
Define the bug frames table in ppc's linker script as is done by other architectures. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/xen.lds.S | 10 ++ 1 file changed, 10 insertions(+) diff --git a/xen/arch/ppc/xen.lds.S b/xen/arch/ppc/xen.lds.S index 2fa81d5a83..692aa34add 100644 --- a/xen/arch/ppc/xen.lds.S +++ b/xen/arch/ppc/xen.lds.S @@ -41,6 +41,16 @@ SECTIONS . = ALIGN(PAGE_SIZE); .rodata : { _srodata = .; /* Read-only data */ +/* Bug frames table */ + __start_bug_frames = .; + *(.bug_frames.0) + __stop_bug_frames_0 = .; + *(.bug_frames.1) + __stop_bug_frames_1 = .; + *(.bug_frames.2) + __stop_bug_frames_2 = .; + *(.bug_frames.3) + __stop_bug_frames_3 = .; *(.rodata) *(.rodata.*) *(.data.rel.ro) -- 2.30.2
[PATCH 5/9] xen/ppc: Define minimal stub headers required for full build
Additionally, change inclusion of asm/ headers to corresponding xen/ ones throughout arch/ppc now that they work. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/Kconfig | 1 + xen/arch/ppc/include/asm/altp2m.h| 39 xen/arch/ppc/include/asm/bug.h | 7 + xen/arch/ppc/include/asm/cache.h | 2 + xen/arch/ppc/include/asm/config.h| 9 + xen/arch/ppc/include/asm/cpufeature.h| 9 + xen/arch/ppc/include/asm/current.h | 42 xen/arch/ppc/include/asm/delay.h | 11 + xen/arch/ppc/include/asm/desc.h | 0 xen/arch/ppc/include/asm/device.h| 53 + xen/arch/ppc/include/asm/div64.h | 14 ++ xen/arch/ppc/include/asm/domain.h| 46 xen/arch/ppc/include/asm/event.h | 35 xen/arch/ppc/include/asm/flushtlb.h | 23 ++ xen/arch/ppc/include/asm/grant_table.h | 0 xen/arch/ppc/include/asm/guest_access.h | 54 + xen/arch/ppc/include/asm/guest_atomics.h | 14 ++ xen/arch/ppc/include/asm/hardirq.h | 18 ++ xen/arch/ppc/include/asm/hypercall.h | 0 xen/arch/ppc/include/asm/io.h| 15 ++ xen/arch/ppc/include/asm/iocap.h | 7 + xen/arch/ppc/include/asm/iommu.h | 7 + xen/arch/ppc/include/asm/irq.h | 32 +++ xen/arch/ppc/include/asm/mem_access.h| 0 xen/arch/ppc/include/asm/mm.h| 255 ++- xen/arch/ppc/include/asm/monitor.h | 48 + xen/arch/ppc/include/asm/nospec.h| 18 ++ xen/arch/ppc/include/asm/numa.h | 26 +++ xen/arch/ppc/include/asm/p2m.h | 105 ++ xen/arch/ppc/include/asm/page.h | 19 ++ xen/arch/ppc/include/asm/paging.h| 7 + xen/arch/ppc/include/asm/pci.h | 7 + xen/arch/ppc/include/asm/percpu.h| 26 +++ xen/arch/ppc/include/asm/procarea.h | 38 xen/arch/ppc/include/asm/processor.h | 6 + xen/arch/ppc/include/asm/random.h| 9 + xen/arch/ppc/include/asm/regs.h | 2 + xen/arch/ppc/include/asm/setup.h | 6 + xen/arch/ppc/include/asm/smp.h | 18 ++ xen/arch/ppc/include/asm/softirq.h | 8 + xen/arch/ppc/include/asm/spinlock.h | 15 ++ xen/arch/ppc/include/asm/system.h| 243 - xen/arch/ppc/include/asm/time.h | 20 ++ xen/arch/ppc/include/asm/vm_event.h | 49 + xen/arch/ppc/include/asm/xenoprof.h | 0 xen/arch/ppc/mm-radix.c | 2 +- xen/arch/ppc/opal.c | 2 - xen/arch/ppc/tlb-radix.c | 2 +- xen/include/public/hvm/save.h| 2 + xen/include/public/pmu.h | 2 + xen/include/public/xen.h | 2 + 51 files changed, 1368 insertions(+), 7 deletions(-) create mode 100644 xen/arch/ppc/include/asm/altp2m.h create mode 100644 xen/arch/ppc/include/asm/cpufeature.h create mode 100644 xen/arch/ppc/include/asm/current.h create mode 100644 xen/arch/ppc/include/asm/delay.h create mode 100644 xen/arch/ppc/include/asm/desc.h create mode 100644 xen/arch/ppc/include/asm/device.h create mode 100644 xen/arch/ppc/include/asm/div64.h create mode 100644 xen/arch/ppc/include/asm/domain.h create mode 100644 xen/arch/ppc/include/asm/event.h create mode 100644 xen/arch/ppc/include/asm/flushtlb.h create mode 100644 xen/arch/ppc/include/asm/grant_table.h create mode 100644 xen/arch/ppc/include/asm/guest_access.h create mode 100644 xen/arch/ppc/include/asm/guest_atomics.h create mode 100644 xen/arch/ppc/include/asm/hardirq.h create mode 100644 xen/arch/ppc/include/asm/hypercall.h create mode 100644 xen/arch/ppc/include/asm/io.h create mode 100644 xen/arch/ppc/include/asm/iocap.h create mode 100644 xen/arch/ppc/include/asm/iommu.h create mode 100644 xen/arch/ppc/include/asm/irq.h create mode 100644 xen/arch/ppc/include/asm/mem_access.h create mode 100644 xen/arch/ppc/include/asm/monitor.h create mode 100644 xen/arch/ppc/include/asm/nospec.h create mode 100644 xen/arch/ppc/include/asm/numa.h create mode 100644 xen/arch/ppc/include/asm/p2m.h create mode 100644 xen/arch/ppc/include/asm/paging.h create mode 100644 xen/arch/ppc/include/asm/pci.h create mode 100644 xen/arch/ppc/include/asm/percpu.h create mode 100644 xen/arch/ppc/include/asm/procarea.h create mode 100644 xen/arch/ppc/include/asm/random.h create mode 100644 xen/arch/ppc/include/asm/setup.h create mode 100644 xen/arch/ppc/include/asm/smp.h create mode 100644 xen/arch/ppc/include/asm/softirq.h create mode 100644 xen/arch/ppc/include/asm/spinlock.h create mode 100644 xen/arch/ppc/include/asm/time.h create mode 100644 xen/arch/ppc/include/asm/vm_event.h create mode 100644 xen/arch/ppc/include/asm/xenoprof.h diff --git a/xen/arch/ppc/Kconfig b/xen/arch/ppc/Kconfig index ab116ffb2a..a6eae597af 100644 --- a/xen/arch/ppc/Kconfig +++ b/xen/arch/ppc/Kconfig @@ -1,6 +1,7 @@ config PPC def_bool y
[PATCH 9/9] xen/ppc: Enable full Xen build
Bring ppc's Makefile and arch.mk in line with arm and x86 to disable the build overrides and enable the full Xen build. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/Makefile | 16 +++- xen/arch/ppc/arch.mk | 3 --- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile index 969910b3b6..7b68b5ace2 100644 --- a/xen/arch/ppc/Makefile +++ b/xen/arch/ppc/Makefile @@ -12,10 +12,24 @@ $(TARGET): $(TARGET)-syms cp -f $< $@ $(TARGET)-syms: $(objtree)/prelink.o $(obj)/xen.lds - $(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds -N $< $(build_id_linker) -o $@ + $(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds -N $< \ + $(objtree)/common/symbols-dummy.o -o $(dot-target).0 + $(NM) -pa --format=sysv $(dot-target).0 \ + | $(objtree)/tools/symbols $(all_symbols) --sysv --sort \ + > $(dot-target).0.S + $(MAKE) $(build)=$(@D) $(dot-target).0.o + $(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds -N $< \ + $(dot-target).0.o -o $(dot-target).1 + $(NM) -pa --format=sysv $(dot-target).1 \ + | $(objtree)/tools/symbols $(all_symbols) --sysv --sort \ + > $(dot-target).1.S + $(MAKE) $(build)=$(@D) $(dot-target).1.o + $(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds -N $< $(build_id_linker) \ + $(dot-target).1.o -o $@ $(NM) -pa --format=sysv $@ \ | $(objtree)/tools/symbols --all-symbols --xensyms --sysv --sort \ > $@.map + rm -f $(@D)/.$(@F).[0-9]* $(obj)/xen.lds: $(src)/xen.lds.S FORCE $(call if_changed_dep,cpp_lds_S) diff --git a/xen/arch/ppc/arch.mk b/xen/arch/ppc/arch.mk index d05cbf1df5..917ad0e6a8 100644 --- a/xen/arch/ppc/arch.mk +++ b/xen/arch/ppc/arch.mk @@ -7,6 +7,3 @@ CFLAGS += -m64 -mlittle-endian -mcpu=$(ppc-march-y) CFLAGS += -mstrict-align -mcmodel=medium -mabi=elfv2 -fPIC -mno-altivec -mno-vsx -msoft-float LDFLAGS += -m elf64lppc - -# TODO: Drop override when more of the build is working -override ALL_OBJS-y = arch/$(SRCARCH)/built_in.o common/libfdt/built_in.o lib/built_in.o -- 2.30.2
Re: [PATCH 2/3] xen/ppc: Relocate kernel to physical address 0 on boot
On 8/1/23 1:08 AM, Jan Beulich wrote: > On 01.08.2023 01:37, Shawn Anastasio wrote: >> On 7/31/23 10:46 AM, Jan Beulich wrote: >>> On 29.07.2023 00:21, Shawn Anastasio wrote: >>>> +/* If we're at the correct address, skip copy */ >>>> +cmpld %r1, %r12 >>>> +beq .L_correct_address >>> >>> Can this ever be the case, especially with the MMU-off behavior you >>> describe in the comment above? Wouldn't you need to ignore the top >>> four bits in the comparison? >> >> It will always be the case after the code jumps to XEN_VIRT_START after >> the copy takes place. > > Well, of course. > >> I could have it jump past the copy loop entirely, >> but then I'd need to duplicate the TOC setup. > > I don't think I understand this part of your reply: .L_correct_address > _is_ past the copy loop. Sorry, let me elaborate. I meant that I could have the end of the copy loop (the mtctr + btctr preceeding .L_correct_address) jump to (XEN_VIRT_START + .L_correct_address) as opposed to XEN_VIRT_START so that the address comparison you originally commented on wouldn't be hit again. This would mean adding another TOC setup block at .L_correct_address, though, since we'd be skipping over the one at the beginning of the routine and the TOC needs to be reconfigured after the relocation. >>>> +/* Copy bytes until _end */ >>>> +LOAD_REG_ADDR(%r11, _end) >>>> +addi%r1, %r1, -8 >>>> +li %r13, -8 >>>> +.L_copy_xen: >>>> +ldu %r10, 8(%r1) >>>> +stdu%r10, 8(%r13) >>>> +cmpld %r1, %r11 >>>> +blt .L_copy_xen >>>> + >>>> +/* Jump to XEN_VIRT_START */ >>>> +mtctr %r12 >>>> +bctr >>>> +.L_correct_address: >>> >>> Can the two regions potentially overlap? Looking at the ELF header >>> it's not clear to me what guarantees there are that this can't >>> happen. >> >> As I understand it, any bootloader that placed the kernel at a low >> enough address for this to be an issue wouldn't be able to boot Linux or >> FreeBSD, so in practice it's a safe bet that this won't be the case. > > Fair enough then. > > Jan Thanks, Shawn
Re: [PATCH 4/4] xen/ppc: Implement early serial console on PowerNV
On 8/7/23 10:05 AM, Jan Beulich wrote: > On 02.08.2023 02:11, Shawn Anastasio wrote: >> Implement the OPAL firmware calls required to write to the serial >> console on PowerNV systems. Unlike pseries/Open Firmware, the OPAL >> firmware interface can be used past early boot and as such the relevant >> functions are not marked as __init. >> >> Signed-off-by: Shawn Anastasio > > Constraint as before and with two nits > Acked-by: Jan Beulich > >> @@ -20,8 +22,20 @@ >> * Load the address of a symbol from the TOC into the specified GPR. >> */ >> #define LOAD_REG_ADDR(reg,name) >> \ >> -addis reg,%r2,name@toc@ha; >> \ >> -addi reg,reg,name@toc@l >> +addis reg, %r2, name@toc@ha; >> \ >> +addi reg, reg, name@toc@l >> + >> +/* >> + * Declare a global assembly function with a proper TOC setup prologue >> + */ >> +#define _GLOBAL_TOC(name) >> \ >> +.balign 4; >> \ >> +.type name, @function; >> \ >> +.globl name; >> \ >> +name: >> \ >> +0: addis %r2, %r12, (.TOC.-0b)@ha; >> \ >> +addi %r2, %r2, (.TOC.-0b)@l; >> \ > > Strictly speaking the - want surrounding by blanks, but I wonder whether > to PPC eyes these constructs look more natural without. Please clarify. This is admittedly very subjective, but to my eyes the code as-is looks perfectly natural. That said, I wouldn't be opposed to adding spaces if that's what you prefer. >> --- /dev/null >> +++ b/xen/arch/ppc/ppc64/opal-calls.S >> @@ -0,0 +1,81 @@ >> +/* SPDX-License-Identifier: GPL-2.0-or-later */ >> +/* >> + * Adapted from Linux's arch/powerpc/boot/opal-calls.S >> + * >> + * Copyright (c) 2016 IBM Corporation. >> + * Copyright Raptor Engineering, LLC >> + */ >> + >> +#include >> +#include >> +#include >> + >> +.text >> + >> +#define OPAL_CALL(name, token) \ >> +.globl name;\ >> +name: \ >> +li %r0, token; \ >> +b opal_call >> + >> + _GLOBAL_TOC(opal_call) > > Any reason for the leading blank here? No -- that was a mistake on my part. > > Where necessary I again think these small items can be taken care of > while committing. Sounds good. > Jan Thanks, Shawn
Re: [PATCH 1/4] xen/ppc: Switch to medium PIC code model
On 8/2/23 2:16 AM, Jan Beulich wrote: > On 02.08.2023 02:11, Shawn Anastasio wrote: >> --- a/xen/arch/ppc/include/asm/asm-defns.h >> +++ b/xen/arch/ppc/include/asm/asm-defns.h >> @@ -16,6 +16,13 @@ >> lis reg, (val) @h; >> \ >> ori reg, reg, (val) @l; >> \ >> >> +/* >> + * Load the address of a symbol from the TOC into the specified GPR. >> + */ >> +#define LOAD_REG_ADDR(reg,name) >> \ >> +addis reg,%r2,name@toc@ha; >> \ >> +addi reg,reg,name@toc@l > > Didn't you indicate you'd add blanks after the commas (also) here? > >> --- a/xen/arch/ppc/ppc64/head.S >> +++ b/xen/arch/ppc/ppc64/head.S >> @@ -1,6 +1,7 @@ >> /* SPDX-License-Identifier: GPL-2.0-or-later */ >> >> #include >> +#include >> >> .section .text.header, "ax", %progbits >> >> @@ -11,16 +12,19 @@ ENTRY(start) >> FIXUP_ENDIAN >> >> /* set up the TOC pointer */ >> -LOAD_IMM32(%r2, .TOC.) >> +bcl 20, 31, 1f > > Hard tab slipped in. > > I'm happy to take care of both while committing; then: > Acked-by: Jan Beulich Thanks, Jan. Just to clarify, are there any outstanding comments that I need to address in this series, or are they all able to be handled by you during commit? > Jan - Shawn
Re: [PATCH 1/9] xen/common: Add missing #includes treewide
On 8/7/23 10:39 AM, Jan Beulich wrote: > On 03.08.2023 01:02, Shawn Anastasio wrote: >> A few files treewide depend on defininitions in headers that they >> don't include. This works when arch headers end up including the >> required headers by chance, but broke on ppc64 with only minimal/stub >> arch headers. >> >> Signed-off-by: Shawn Anastasio > > I'm okay with the changes in principle, but I'd like to ask a question > nevertheless, perhaps also for other REST maintainers (whom you should > have Cc-ed, btw) to chime in. > >> --- a/xen/common/memory.c >> +++ b/xen/common/memory.c >> @@ -28,6 +28,7 @@ >> #include >> #include >> #include >> +#include >> #include >> #include > > I realize there are several asm/*.h being included here already. Yet > generally I think common .c files would better not include any of > them directly; only xen/*.h ones should (and even there one might see > possible restrictions on what's "legitimate"). Do you recall what it > was that's needed from asm/page.h here ... The references to invalidate_icache (memory.c:310), clear_page (memory.c:1867), and copy_page (memory.c:1876) all need asm/page.h to be included somehow. I'm not sure which file ends up including asm/page.h for build to work on x86/arm, but with my minimal PPC headers it wasn't getting incidentally included and build was failing. > >> --- a/xen/common/xmalloc_tlsf.c >> +++ b/xen/common/xmalloc_tlsf.c >> @@ -27,6 +27,7 @@ >> #include >> #include >> #include >> +#include > > ... and here? Here it's the PAGE_ALIGN used at xmalloc_tlsf.c:549 > >> --- a/xen/include/xen/domain.h >> +++ b/xen/include/xen/domain.h >> @@ -4,6 +4,7 @@ >> >> #include >> >> +#include >> #include > > While following our sorting guidelines, this still looks a little odd. > We typically would include public/xen.h first, but then almost all other > public headers include it anyway. So I'm inclined to suggest to replace > (rather than amend) the existing #include here. To be clear, you're suggesting replacing the include of to ? I've tested this and it works fine, as expected. > > Then again I wonder why this include is needed. xen/domain.h is > effectively included everywhere, yet I would have hoped public/domctl.h > isn't. domctl.h is required because of the reference to `struct xen_domctl_createdomain` on domain.h:84. Alternatively, we could get away with a forward declaration of the struct. > Jan Thanks, Shawn
Re: [PATCH 2/9] xen/ppc: Add public/arch-ppc.h
On 8/7/23 10:51 AM, Jan Beulich wrote: > On 03.08.2023 01:02, Shawn Anastasio wrote: >> Signed-off-by: Shawn Anastasio >> --- >> xen/include/public/arch-ppc.h | 140 ++ >> 1 file changed, 140 insertions(+) >> create mode 100644 xen/include/public/arch-ppc.h >> >> diff --git a/xen/include/public/arch-ppc.h b/xen/include/public/arch-ppc.h >> new file mode 100644 >> index 00..0eb7ce4208 >> --- /dev/null >> +++ b/xen/include/public/arch-ppc.h >> @@ -0,0 +1,140 @@ >> +/* >> + * Permission is hereby granted, free of charge, to any person obtaining a >> copy >> + * of this software and associated documentation files (the "Software"), to >> + * deal in the Software without restriction, including without limitation >> the >> + * rights to use, copy, modify, merge, publish, distribute, sublicense, >> and/or >> + * sell copies of the Software, and to permit persons to whom the Software >> is >> + * furnished to do so, subject to the following conditions: >> + * >> + * The above copyright notice and this permission notice shall be included >> in >> + * all copies or substantial portions of the Software. >> + * >> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS >> OR >> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, >> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >> THE >> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER >> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING >> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER >> + * DEALINGS IN THE SOFTWARE. > > Any reason for a spelled out license rather than an SPDX header? > This was an oversight when importing the file from the old Xen 3.2 source tree. I'll drop the license text in favor of an SPDX header. >> + * Copyright (C) IBM Corp. 2005, 2006 >> + * Copyright (C) Raptor Engineering, LLC 2023 >> + * >> + * Authors: Hollis Blanchard >> + * Timothy Pearson >> + */ >> + >> +#ifndef __XEN_PUBLIC_ARCH_PPC64_H__ >> +#define __XEN_PUBLIC_ARCH_PPC64_H__ > > The 64 wants dropping here, considering the name of the header. Ditto. Will fix. >> +#define int64_aligned_t int64_t __attribute__((aligned(8))) >> +#define uint64_aligned_t uint64_t __attribute__((aligned(8))) > > I understand arch-arm.h has it this way too, but in public headers I > think we're better off using __aligned__ (in the example here). Sure, I can make that change. >> +#ifndef __ASSEMBLY__ >> +#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ >> +typedef union { type *p; unsigned long q; } \ >> +__guest_handle_ ## name;\ >> +typedef union { type *p; uint64_aligned_t q; } \ >> +__guest_handle_64_ ## name >> + >> +#define __DEFINE_XEN_GUEST_HANDLE(name, type) \ >> +___DEFINE_XEN_GUEST_HANDLE(name, type); \ >> +___DEFINE_XEN_GUEST_HANDLE(const_##name, const type) >> +#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, >> name) >> +#define __XEN_GUEST_HANDLE(name)__guest_handle_64_ ## name >> +#define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name) >> +#define XEN_GUEST_HANDLE_PARAM(name)__guest_handle_ ## name >> +#define set_xen_guest_handle_raw(hnd, val) \ >> +do {\ >> +__typeof__(&(hnd)) _sxghr_tmp = &(hnd); \ > > In new code, can you please avoid underscore-prefixed macro locals, > which violate name space rules set forth by the standard? We appear > to be adopting underscore-suffixed naming for such locals. Sure, will fix. >> +_sxghr_tmp->q = 0; \ >> +_sxghr_tmp->p = val;\ > > "val" need parenthesizing here. Will fix. >> +} while ( 0 ) >> +#define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val) >> + >> +#ifdef __XEN_TOOLS__ >> +#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) >> +#endif >> + >> +typedef uint64_t xen_pfn_t; >> +#define PRI_xen_pfn PRIx64 >> +#define PRIu_xen_pfn PRIu64 >> + >> +/* >> + * Maximum number of virtual CPUs in legacy multi-processor guests. >> + * Only one. All other VCPUS must use VCPUOP
Re: [PATCH 3/9] xen/ppc: Implement atomic.h
On 8/7/23 11:13 AM, Jan Beulich wrote: > On 03.08.2023 01:02, Shawn Anastasio wrote: >> Implement atomic.h for PPC, based off of the original Xen 3.2 >> implementation. > > Since likely that originally came from Linux, did you cross check that > Linux hasn't gained any bug fixes in the meantime? I did -- the atomic barrier instructions used by linux have changed since this code was originally written, so I've updated them to be inline with modern linux. > Other than this just a couple of nits; I'm not really qualified to > review in particular the inline assembly here, I'm afraid. > >> --- /dev/null >> +++ b/xen/arch/ppc/include/asm/atomic.h >> @@ -0,0 +1,387 @@ >> +/* SPDX-License-Identifier: GPL-2.0-or-later */ >> +/* >> + * PowerPC64 atomic operations >> + * >> + * Copyright (C) 2001 Paul Mackerras , IBM >> + * Copyright (C) 2001 Anton Blanchard , IBM >> + * Copyright Raptor Engineering LLC >> + * >> + * 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_PPC64_ATOMIC_H_ >> +#define _ASM_PPC64_ATOMIC_H_ > > To fit the name, no "64" please. Will fix. >> +#include >> + >> +#include >> +#include >> + >> +static inline int atomic_read(const atomic_t *v) >> +{ >> +return *(volatile int *)&v->counter; >> +} >> + >> +static inline int _atomic_read(atomic_t v) >> +{ >> +return v.counter; >> +} >> + >> +static inline void atomic_set(atomic_t *v, int i) >> +{ >> +v->counter = i; >> +} >> + >> +static inline void _atomic_set(atomic_t *v, int i) >> +{ >> +v->counter = i; >> +} >> + >> +void __bad_atomic_read(const volatile void *p, void *res); >> +void __bad_atomic_size(void); >> + >> +#define build_atomic_read(name, insn, type) >>\ >> +static inline type name(const volatile type *addr) >>\ >> +{ >>\ >> +type ret; >>\ >> +asm volatile ( insn "%U1%X1 %0,%1" : "=r"(ret) : "m<>"(*addr) ); >>\ > > As I think I had mentioned before, asm() contraints want a blank between > closing quote and opend paren. I.e. like this > > asm volatile ( insn "%U1%X1 %0,%1" : "=r" (ret) : "m<>" (*addr) ); > My mistake, I went through and hand-formatted all of this code to try to be inline with Xen's style but forgot about the constraints. As an aside, I don't suppose there is an automatic formatter somewhere that I've missed? I found an old clang-format fork that claims to add support for Xen's formatting[1] but it seems to only handle a subset of Xen's rules so I haven't found it very useful. [1] https://github.com/NastyaVicodin/llvm-project/commits/main >> +#define read_atomic(p) >>\ >> +({ >>\ >> +union { >>\ >> +typeof(*(p)) val; >>\ >> +char c[0]; >>\ >> +} x_; >>\ >> +read_atomic_size(p, x_.c, sizeof(*(p))); >>\ >> +x_.val; >>\ >> +}) >> + >> +#define write_atomic(p, x) >>\ >> +do >>\ >> +{ >>\ >> +typeof(*(p)) x_ = (x); >>\ >> +write_atomic_size(p, &x_, sizeof(*(p))); >>\ >> +} while ( 0 ) > > Up to here you use under
Re: [PATCH 4/9] xen/ppc: Implement bitops.h
On 8/8/23 3:36 AM, Jan Beulich wrote: > On 03.08.2023 01:03, Shawn Anastasio wrote: >> Implement bitops.h, based on Linux's implementation as of commit >> 5321d1b1afb9a17302c6cec79f0cbf823eb0d3fc > > But with PPC32 bits dropped afaics, and with leading hard tabs replaced > by four spaces - which in turn appears to yield some unhelpful placement > of line-continuing backslashes. And with some > asm-generic/bitops/builtin-*.h expanded. Please mention all adjustments > you made, to allow for some future importing of updates to go as > smoothly as possible. Yes, that is all correct. Additionally, the code was adapted to use 32-bit words for bitmap entries like the rest of Xen's architectures do instead of the 64-bit longs used by the Linux implementation. I provided the reference to the Linux commit for completeness' sake, but to be clear, my changes have caused it to diverge enough where I wouldn't expect direct imports from Linux to be (conveniently) possible. I'll clarify this in the commit message and also fix the macro line-continuing backslash spacing. > Jan Thanks, Shawn
Re: [PATCH 5/9] xen/ppc: Define minimal stub headers required for full build
On 8/8/23 4:12 AM, Jan Beulich wrote: > On 03.08.2023 01:03, Shawn Anastasio wrote: >> --- /dev/null >> +++ b/xen/arch/ppc/include/asm/altp2m.h >> @@ -0,0 +1,39 @@ >> +/* >> + * Alternate p2m >> + * >> + * Copyright (c) 2014, Intel Corporation. >> + * >> + * This program is free software; you can redistribute it and/or modify it >> + * under the terms and conditions of the GNU General Public License, >> + * version 2, as published by the Free Software Foundation. >> + * >> + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. >> + */ > > Please use an SPDX header instead in new code. I also wonder about the > Intel copyright. I realize it's that way in the Arm header that you > apparently copied, but even there it's pretty odd. I don't think such > a pair of stub functions is reasonably copyrightable. Yes, I agree the copyright is a bit strange and was likely just copied on the Arm side from the original x86 header. Since I'm not copying any actually implemented code, I think it's safe to drop this in favor of just a standard SPDX header. I'll make that change. >> +#ifndef __ASM_PPC_ALTP2M_H__ >> +#define __ASM_PPC_ALTP2M_H__ >> + >> +#include > > I don't think this is needed here (nor in Arm's original). All you > need are forward decls of struct domain and struct vcpu. And > xen/bug.h plus xen/types.h. > Fair enough -- and bug.h seems to already include types.h for us, so we only need the one include plus the two forward declarations. I'll update this. >> --- a/xen/arch/ppc/include/asm/bug.h >> +++ b/xen/arch/ppc/include/asm/bug.h >> @@ -4,6 +4,7 @@ >> #define _ASM_PPC_BUG_H >> >> #include >> +#include >> >> /* >> * Power ISA guarantees that an instruction consisting of all zeroes is >> @@ -15,4 +16,10 @@ >> >> #define BUG_FN_REG r0 >> >> +#define BUG() do { \ >> +die(); \ >> +} while (0) > > This looks like it's temporary. I think any construct that later needs > updating wants marking in some common way (such that it's easy to grep > for items left to be dealt with; you have such a comment in e.g. > asm/event.h). Of course if an entire header consists of _only_ stubs, > perhaps a single such comment would suffice. Yes, agreed that this macro deserves a TODO comment. As for the rest of the stub functions that this patch implements, are you suggesting that each file with stubs should contain a similar comment? Another alternative that I thought of would be to define a BUG_UNIMPLEMENTED() macro or similar and call that inside of all the stub functions. >> --- a/xen/arch/ppc/include/asm/cache.h >> +++ b/xen/arch/ppc/include/asm/cache.h >> @@ -3,4 +3,6 @@ >> #ifndef _ASM_PPC_CACHE_H >> #define _ASM_PPC_CACHE_H >> >> +#define __read_mostly __section(".data.read_mostly") > > Not something for you to do, but we really want to move this to > xen/cache.h. > Perfect, will drop this from my series. >> diff --git a/xen/arch/ppc/include/asm/desc.h >> b/xen/arch/ppc/include/asm/desc.h >> new file mode 100644 >> index 00..e69de29bb2 > > Along the lines of the above - common code should not include this > header, and Arm shouldn't need one either. I'll see if I can sort > this. > Ditto. >> --- a/xen/arch/ppc/include/asm/mm.h >> +++ b/xen/arch/ppc/include/asm/mm.h >> @@ -1,19 +1,270 @@ >> #ifndef _ASM_PPC_MM_H >> #define _ASM_PPC_MM_H >> >> +#include >> +#include >> +#include >> #include >> #include >> >> +void setup_initial_pagetables(void); >> + >> +extern unsigned long total_pages; >> + >> #define pfn_to_paddr(pfn) ((paddr_t)(pfn) << PAGE_SHIFT) >> #define paddr_to_pfn(pa) ((unsigned long)((pa) >> PAGE_SHIFT)) >> +#define paddr_to_pdx(pa)mfn_to_pdx(maddr_to_mfn(pa)) >> +#define gfn_to_gaddr(gfn) pfn_to_paddr(gfn_x(gfn)) >> +#define gaddr_to_gfn(ga)_gfn(paddr_to_pfn(ga)) >> +#define mfn_to_maddr(mfn) pfn_to_paddr(mfn_x(mfn)) >> +#define maddr_to_mfn(ma)_mfn(paddr_to_pfn(ma)) >> +#define vmap_to_mfn(va) maddr_to_mfn(virt_to_maddr((vaddr_t)va)) >
Re: [PATCH 3/3] xen/ppc: Implement initial Radix MMU support
On 8/1/23 8:18 AM, Jan Beulich wrote: > On 29.07.2023 00:21, Shawn Anastasio wrote: >> --- /dev/null >> +++ b/xen/arch/ppc/include/asm/bitops.h >> @@ -0,0 +1,11 @@ >> +#ifndef _ASM_PPC_BITOPS_H >> +#define _ASM_PPC_BITOPS_H >> + >> +#include > > Not a big deal, but ... > >> +/* PPC bit number conversion */ >> +#define PPC_BITLSHIFT(be) (BITS_PER_LONG - 1 - (be)) >> +#define PPC_BIT(bit)(1UL << PPC_BITLSHIFT(bit)) >> +#define PPC_BITMASK(bs, be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) >> + >> +#endif /* _ASM_PPC_BITOPS_H */ > > ... nothing here looks to require that #include. > Good point, I'll drop it. >> --- /dev/null >> +++ b/xen/arch/ppc/include/asm/mm.h >> @@ -0,0 +1,19 @@ >> +#ifndef _ASM_PPC_MM_H >> +#define _ASM_PPC_MM_H >> + >> +#include > > This is included by xen/config.h, which in turn is included from the > compiler command line. > Thanks for letting me know. Will drop. >> --- /dev/null >> +++ b/xen/arch/ppc/include/asm/page.h >> @@ -0,0 +1,178 @@ >> +#ifndef _ASM_PPC_PAGE_H >> +#define _ASM_PPC_PAGE_H >> + >> +#include >> + >> +#include >> +#include >> + >> +#define PDE_VALID PPC_BIT(0) >> +#define PDE_NLB_MASK 0xfUL >> +#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_CHANGEPPC_BIT(56) >> + >> +/* PTE Attributes */ >> +#define PTE_ATT_SAOPPC_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_EXECUTEPPC_BIT(63) >> + >> +/* Field shifts/masks */ >> +#define PTE_RPN_MASK 0x1fffUL >> +#define PTE_RPN_SHIFT 12UL >> +#define PTE_ATT_MASK 0x3UL >> +#define PTE_ATT_SHIFT 4UL >> +#define PTE_EAA_MASK 0xfUL > > Did you consider introducing just *_MASK values, utilizing MASK_INSR() > and MASK_EXTR() instead of open-coded shifting/masking? > I actually wasn't aware of MASK_INSR/MASK_EXTR when writing this. I've just looked into it though, and I don't think using them makes the code much cleaner. Specifically I'm looking at the implementations of `pte_to_paddr` and `pde_to_paddr` which both need to ensure that the returned value retains its original shift. For example, with pte_to_paddr, this change would be: - return be64_to_cpu(pte.pte) & (PTE_RPN_MASK << PTE_RPN_SHIFT); + return MASK_EXTR(be64_to_cpu(pte.pte), PTE_RPN_MASK) << PTE_RPN_SHIFT; In addition to updating the definitions of the *_MASK macros to include the right-most padding zeros. - #define PTE_RPN_MASK 0x1fffUL + #define PTE_RPN_MASK 0x1fff000UL I don't really think this is an improvement, so I'm tempted to keep the code as-is. If you feel strongly about the usage of MASK_{INSR,EXTR}, though, I could make the change. >> +#define PTE_XEN_BASE (PTE_VALID | PTE_EAA_PRIVILEGED | PTE_REFERENCE) >> +#define PTE_XEN_RW (PTE_XEN_BASE | PTE_EAA_READ | PTE_EAA_WRITE | >> PTE_CHANGE) >> +#define PTE_XEN_RO (PTE_XEN_BASE | PTE_EAA_READ) >> +#define PTE_XEN_RX (PTE_XEN_BASE | PTE_EAA_READ | PTE_EAA_EXECUTE) >> + >> +/* >> + * Radix Tree layout for 64KB pages: >> + * >> + * [ L1 (ROOT) PAGE DIRECTORY (8192 * sizeof(pde_t)) ] >> + * | >> + * | >> + * v >> + *[ L2 PAGE DIRECTORY (512 * sizeof(pde_t)) ] >> + * | >> + * | >> + * v >> + *[ L3 PAGE DIRECTORY (512 * sizeof(pde_t)) ] >> + * | >> + * | >> + * v >> + * [ L4 PAGE TABLE (32 * sizeof(pte_t)) ] >> + * | >> + * | >> + * v >> + *[ PAGE TABLE ENTRY ] >> + */ >> + >> +#define XEN_PT_ENTRIES_LOG2_LVL_1 13 /* 2**13 entries, maps 2**13 * 512GB = >> 4PB */ >> +#define XEN_PT_ENTRIES_LOG2_LVL_2 9 /* 2**9 entries, maps 2**9 * 1GB = >> 512GB */ >> +#define XEN_PT_ENTRIES_LOG2_LVL_3 9 /* 2**9 entries, maps 2**9 * 1GB = >> 512GB */ >> +#define XEN_PT_ENTR
[PATCH v2 0/3] xen/ppc: Add early Radix MMU support
Hello all, This series adds support for bringing up the Radix MMU with basic identity-mapped page tables. In order to simplify the memory layout, the series changes XEN_VIRT _START to 0xC000___, which has a couple of convenient properties. When the MMU is off, the top 4 address bits are ignored by the hardware, so this is equivalent to physical address 0. When the MMU is enabled, the top 4 address bits are used to select the memory quadrant, and 0xC corresponds to quadrant 3 which is used for kernel memory. Thus, by linking the kernel here and ensuring its physical load address is 0x0, we are able to run at the correct address both before and after the MMU is enabled. Additionally, as the Radix MMU was only added in ISA 3.0 (POWER9), this series also drops support for POWER8 for now, to avoid having a non-working build configuration in-tree. Thanks, Shawn Shawn Anastasio (3): xen/ppc: Bump minimum target ISA to 3.0 (POWER9) xen/ppc: Relocate kernel to physical address 0 on boot xen/ppc: Implement initial Radix MMU support xen/arch/ppc/Kconfig | 7 +- xen/arch/ppc/Makefile| 2 + xen/arch/ppc/arch.mk | 1 - xen/arch/ppc/include/asm/bitops.h| 9 + xen/arch/ppc/include/asm/config.h| 2 +- xen/arch/ppc/include/asm/mm.h| 18 ++ xen/arch/ppc/include/asm/page-bits.h | 3 +- xen/arch/ppc/include/asm/page.h | 178 ++ xen/arch/ppc/include/asm/processor.h | 34 xen/arch/ppc/include/asm/regs.h | 138 ++ xen/arch/ppc/include/asm/types.h | 1 + xen/arch/ppc/mm-radix.c | 268 +++ xen/arch/ppc/ppc64/head.S| 42 + xen/arch/ppc/setup.c | 3 + xen/arch/ppc/tlb-radix.c | 96 ++ 15 files changed, 793 insertions(+), 9 deletions(-) create mode 100644 xen/arch/ppc/include/asm/bitops.h create mode 100644 xen/arch/ppc/include/asm/mm.h create mode 100644 xen/arch/ppc/include/asm/page.h create mode 100644 xen/arch/ppc/include/asm/regs.h create mode 100644 xen/arch/ppc/mm-radix.c create mode 100644 xen/arch/ppc/tlb-radix.c -- 2.30.2
[PATCH v2 1/3] xen/ppc: Bump minimum target ISA to 3.0 (POWER9)
In preparation for implementing ISA3+ Radix MMU support, drop ISA 2.07B from the supported ISA list to avoid having a non-working configuration in tree. It can be re-added at a later point when Hash MMU support is added. Signed-off-by: Shawn Anastasio --- v2: no changes. xen/arch/ppc/Kconfig | 7 +-- xen/arch/ppc/arch.mk | 1 - 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/xen/arch/ppc/Kconfig b/xen/arch/ppc/Kconfig index b32dce39b8..ab116ffb2a 100644 --- a/xen/arch/ppc/Kconfig +++ b/xen/arch/ppc/Kconfig @@ -20,15 +20,10 @@ menu "ISA Selection" choice prompt "Base ISA" - default POWER_ISA_2_07B + default POWER_ISA_3_00 help This selects the base ISA version that Xen will target. -config POWER_ISA_2_07B - bool "Power ISA 2.07B (POWER8)" - help - Target version 2.07B of the Power ISA (POWER8) or later - config POWER_ISA_3_00 bool "Power ISA 3.00 (POWER9)" help diff --git a/xen/arch/ppc/arch.mk b/xen/arch/ppc/arch.mk index 3bf79bac37..d05cbf1df5 100644 --- a/xen/arch/ppc/arch.mk +++ b/xen/arch/ppc/arch.mk @@ -1,7 +1,6 @@ # Power-specific definitions -ppc-march-$(CONFIG_POWER_ISA_2_07B) := power8 ppc-march-$(CONFIG_POWER_ISA_3_00) := power9 CFLAGS += -m64 -mlittle-endian -mcpu=$(ppc-march-y) -- 2.30.2
[PATCH v2 3/3] xen/ppc: Implement initial Radix MMU support
Add code to construct early identity-mapped page tables as well as the required process and partition tables to enable the MMU. Signed-off-by: Shawn Anastasio --- v2: - Add missing ')' to mm.h/maddr_to_virt definition - Add missing parens around `va` argument in XEN_PT_INDEX_LVL - Drop '&' asm constraint modifier in processor.h/mfmsr() - Fix asm constraint formatting in processor.h - Change mtspr,mfspr to functions in processor.h - Drop unnecessary _Static_assert in mm-radix.c - Drop unnecessary cast in setup_initial_mapping - Use __va() to obtain pde/pte addresses in setup_initial_mapping - Wrap >80col lines in mm-radix.c - Drop unnecessary parameters in setup_{process,partition}_table - Add __init to setup_{process,partition}_table - Drop unnecessary opal.c changes - Drop manual prototype of setup_initial_pagetables in setup.c in favor of using the one already in asm/mm.h - Fix formatting of tlbiel asm block in tlb-radix.c xen/arch/ppc/Makefile| 2 + xen/arch/ppc/include/asm/bitops.h| 9 + xen/arch/ppc/include/asm/mm.h| 18 ++ xen/arch/ppc/include/asm/page-bits.h | 3 +- xen/arch/ppc/include/asm/page.h | 178 ++ xen/arch/ppc/include/asm/processor.h | 34 xen/arch/ppc/include/asm/regs.h | 138 ++ xen/arch/ppc/include/asm/types.h | 1 + xen/arch/ppc/mm-radix.c | 268 +++ xen/arch/ppc/ppc64/head.S| 15 ++ xen/arch/ppc/setup.c | 3 + xen/arch/ppc/tlb-radix.c | 96 ++ 12 files changed, 764 insertions(+), 1 deletion(-) create mode 100644 xen/arch/ppc/include/asm/bitops.h create mode 100644 xen/arch/ppc/include/asm/mm.h create mode 100644 xen/arch/ppc/include/asm/page.h create mode 100644 xen/arch/ppc/include/asm/regs.h create mode 100644 xen/arch/ppc/mm-radix.c create mode 100644 xen/arch/ppc/tlb-radix.c diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile index 0c0a7884a1..a059ac4c0a 100644 --- a/xen/arch/ppc/Makefile +++ b/xen/arch/ppc/Makefile @@ -2,8 +2,10 @@ obj-$(CONFIG_PPC64) += ppc64/ obj-y += boot-of.init.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.init.o +obj-y += mm-radix.o obj-y += opal.o obj-y += setup.o +obj-y += tlb-radix.o $(TARGET): $(TARGET)-syms cp -f $< $@ diff --git a/xen/arch/ppc/include/asm/bitops.h b/xen/arch/ppc/include/asm/bitops.h new file mode 100644 index 00..548e97b414 --- /dev/null +++ b/xen/arch/ppc/include/asm/bitops.h @@ -0,0 +1,9 @@ +#ifndef _ASM_PPC_BITOPS_H +#define _ASM_PPC_BITOPS_H + +/* PPC bit number conversion */ +#define PPC_BITLSHIFT(be) (BITS_PER_LONG - 1 - (be)) +#define PPC_BIT(bit) (1UL << PPC_BITLSHIFT(bit)) +#define PPC_BITMASK(bs, be)((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) + +#endif /* _ASM_PPC_BITOPS_H */ diff --git a/xen/arch/ppc/include/asm/mm.h b/xen/arch/ppc/include/asm/mm.h new file mode 100644 index 00..c85a7ed686 --- /dev/null +++ b/xen/arch/ppc/include/asm/mm.h @@ -0,0 +1,18 @@ +#ifndef _ASM_PPC_MM_H +#define _ASM_PPC_MM_H + +#include + +#define pfn_to_paddr(pfn) ((paddr_t)(pfn) << PAGE_SHIFT) +#define paddr_to_pfn(pa) ((unsigned long)((pa) >> PAGE_SHIFT)) + +#define virt_to_maddr(va) ((paddr_t)((vaddr_t)(va) & PADDR_MASK)) +#define maddr_to_virt(pa) ((void *)((paddr_t)(pa) | XEN_VIRT_START)) + +/* Convert between Xen-heap virtual addresses and machine addresses. */ +#define __pa(x) (virt_to_maddr(x)) +#define __va(x) (maddr_to_virt(x)) + +void setup_initial_pagetables(void); + +#endif /* _ASM_PPC_MM_H */ diff --git a/xen/arch/ppc/include/asm/page-bits.h b/xen/arch/ppc/include/asm/page-bits.h index 4c01bf9716..0286177520 100644 --- a/xen/arch/ppc/include/asm/page-bits.h +++ b/xen/arch/ppc/include/asm/page-bits.h @@ -2,6 +2,7 @@ #define __PPC_PAGE_BITS_H__ #define PAGE_SHIFT 16 /* 64 KiB Pages */ -#define PADDR_BITS 48 +#define PADDR_BITS 53 +#define VADDR_BITS 52 #endif /* __PPC_PAGE_BITS_H__ */ diff --git a/xen/arch/ppc/include/asm/page.h b/xen/arch/ppc/include/asm/page.h new file mode 100644 index 00..9b49424714 --- /dev/null +++ b/xen/arch/ppc/include/asm/page.h @@ -0,0 +1,178 @@ +#ifndef _ASM_PPC_PAGE_H +#define _ASM_PPC_PAGE_H + +#include + +#include +#include + +#define PDE_VALID PPC_BIT(0) +#define PDE_NLB_MASK 0xfUL +#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_CHANGEPPC_BIT(56) + +/* PTE Attributes */ +#define PTE_ATT_SAOPPC_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
[PATCH v2 2/3] xen/ppc: Relocate kernel to physical address 0 on boot
Introduce a small assembly loop in `start` to copy the kernel to physical address 0 before continuing. This ensures that the physical address lines up with XEN_VIRT_START (0xc000) and allows us to identity map the kernel when the MMU is set up in the next patch. We are also able to start execution at XEN_VIRT_START after the copy since hardware will ignore the top 4 address bits when operating in Real Mode (MMU off). Signed-off-by: Shawn Anastasio --- v2: - Fix definition of XEN_VIRT_START macro which incorrectly used _AT instead of _AC. - Use _start instead of start as symbol referring to beginning of Xen binary xen/arch/ppc/include/asm/config.h | 2 +- xen/arch/ppc/ppc64/head.S | 27 +++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/xen/arch/ppc/include/asm/config.h b/xen/arch/ppc/include/asm/config.h index d060f0dca7..b76f940431 100644 --- a/xen/arch/ppc/include/asm/config.h +++ b/xen/arch/ppc/include/asm/config.h @@ -39,7 +39,7 @@ name: #endif -#define XEN_VIRT_START _AT(UL, 0xc000) +#define XEN_VIRT_START _AC(0xc000, UL) #define SMP_CACHE_BYTES (1 << 6) diff --git a/xen/arch/ppc/ppc64/head.S b/xen/arch/ppc/ppc64/head.S index 8f1e5d3ad2..d91bd7f92d 100644 --- a/xen/arch/ppc/ppc64/head.S +++ b/xen/arch/ppc/ppc64/head.S @@ -17,6 +17,33 @@ ENTRY(start) addis %r2, %r12, .TOC.-1b@ha addi%r2, %r2, .TOC.-1b@l +/* + * Copy Xen to physical address zero and jump to XEN_VIRT_START + * (0xc000). This works because the hardware will ignore the top + * four address bits when the MMU is off. + */ +LOAD_REG_ADDR(%r1, _start) +LOAD_IMM64(%r12, XEN_VIRT_START) + +/* If we're at the correct address, skip copy */ +cmpld %r1, %r12 +beq .L_correct_address + +/* Copy bytes until _end */ +LOAD_REG_ADDR(%r11, _end) +addi%r1, %r1, -8 +li %r13, -8 +.L_copy_xen: +ldu %r10, 8(%r1) +stdu%r10, 8(%r13) +cmpld %r1, %r11 +blt .L_copy_xen + +/* Jump to XEN_VIRT_START */ +mtctr %r12 +bctr +.L_correct_address: + /* set up the initial stack */ LOAD_REG_ADDR(%r1, cpu0_boot_stack) li %r11, 0 -- 2.30.2
[PATCH v3 1/3] xen/ppc: Bump minimum target ISA to 3.0 (POWER9)
In preparation for implementing ISA3+ Radix MMU support, drop ISA 2.07B from the supported ISA list to avoid having a non-working configuration in tree. It can be re-added at a later point when Hash MMU support is added. Signed-off-by: Shawn Anastasio --- v3: no changes. v2: no changes. xen/arch/ppc/Kconfig | 7 +-- xen/arch/ppc/arch.mk | 1 - 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/xen/arch/ppc/Kconfig b/xen/arch/ppc/Kconfig index b32dce39b8..ab116ffb2a 100644 --- a/xen/arch/ppc/Kconfig +++ b/xen/arch/ppc/Kconfig @@ -20,15 +20,10 @@ menu "ISA Selection" choice prompt "Base ISA" - default POWER_ISA_2_07B + default POWER_ISA_3_00 help This selects the base ISA version that Xen will target. -config POWER_ISA_2_07B - bool "Power ISA 2.07B (POWER8)" - help - Target version 2.07B of the Power ISA (POWER8) or later - config POWER_ISA_3_00 bool "Power ISA 3.00 (POWER9)" help diff --git a/xen/arch/ppc/arch.mk b/xen/arch/ppc/arch.mk index 3bf79bac37..d05cbf1df5 100644 --- a/xen/arch/ppc/arch.mk +++ b/xen/arch/ppc/arch.mk @@ -1,7 +1,6 @@ # Power-specific definitions -ppc-march-$(CONFIG_POWER_ISA_2_07B) := power8 ppc-march-$(CONFIG_POWER_ISA_3_00) := power9 CFLAGS += -m64 -mlittle-endian -mcpu=$(ppc-march-y) -- 2.30.2
[PATCH v3 2/3] xen/ppc: Relocate kernel to physical address 0 on boot
Introduce a small assembly loop in `start` to copy the kernel to physical address 0 before continuing. This ensures that the physical address lines up with XEN_VIRT_START (0xc000) and allows us to identity map the kernel when the MMU is set up in the next patch. We are also able to start execution at XEN_VIRT_START after the copy since hardware will ignore the top 4 address bits when operating in Real Mode (MMU off). Signed-off-by: Shawn Anastasio --- v3: no changes. v2: - Fix definition of XEN_VIRT_START macro which incorrectly used _AT instead of _AC. - Use _start instead of start as symbol referring to beginning of Xen binary xen/arch/ppc/include/asm/config.h | 2 +- xen/arch/ppc/ppc64/head.S | 27 +++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/xen/arch/ppc/include/asm/config.h b/xen/arch/ppc/include/asm/config.h index d060f0dca7..30438d22d2 100644 --- a/xen/arch/ppc/include/asm/config.h +++ b/xen/arch/ppc/include/asm/config.h @@ -39,7 +39,7 @@ name: #endif -#define XEN_VIRT_START _AT(UL, 0xc000) +#define XEN_VIRT_START _AC(0xc000, UL) #define SMP_CACHE_BYTES (1 << 6) diff --git a/xen/arch/ppc/ppc64/head.S b/xen/arch/ppc/ppc64/head.S index 8f1e5d3ad2..149af2c472 100644 --- a/xen/arch/ppc/ppc64/head.S +++ b/xen/arch/ppc/ppc64/head.S @@ -17,6 +17,33 @@ ENTRY(start) addis %r2, %r12, .TOC.-1b@ha addi%r2, %r2, .TOC.-1b@l +/* + * Copy Xen to physical address zero and jump to XEN_VIRT_START + * (0xc000). This works because the hardware will ignore the top + * four address bits when the MMU is off. + */ +LOAD_REG_ADDR(%r1, _start) +LOAD_IMM64(%r12, XEN_VIRT_START) + +/* If we're at the correct address, skip copy */ +cmpld %r1, %r12 +beq .L_correct_address + +/* Copy bytes until _end */ +LOAD_REG_ADDR(%r11, _end) +addi%r1, %r1, -8 +li %r13, -8 +.L_copy_xen: +ldu %r10, 8(%r1) +stdu%r10, 8(%r13) +cmpld %r1, %r11 +blt .L_copy_xen + +/* Jump to XEN_VIRT_START */ +mtctr %r12 +bctr +.L_correct_address: + /* set up the initial stack */ LOAD_REG_ADDR(%r1, cpu0_boot_stack) li %r11, 0 -- 2.30.2
[PATCH v3 0/3] xen/ppc: Add early Radix MMU support
(v3: Apologies for the noise, but v2 was submitted in error and was missing a few changes to patch 3 that were discussed) Hello all, This series adds support for bringing up the Radix MMU with basic identity-mapped page tables. In order to simplify the memory layout, the series changes XEN_VIRT _START to 0xC000___, which has a couple of convenient properties. When the MMU is off, the top 4 address bits are ignored by the hardware, so this is equivalent to physical address 0. When the MMU is enabled, the top 4 address bits are used to select the memory quadrant, and 0xC corresponds to quadrant 3 which is used for kernel memory. Thus, by linking the kernel here and ensuring its physical load address is 0x0, we are able to run at the correct address both before and after the MMU is enabled. Additionally, as the Radix MMU was only added in ISA 3.0 (POWER9), this series also drops support for POWER8 for now, to avoid having a non-working build configuration in-tree. Thanks, Shawn Shawn Anastasio (3): xen/ppc: Bump minimum target ISA to 3.0 (POWER9) xen/ppc: Relocate kernel to physical address 0 on boot xen/ppc: Implement initial Radix MMU support xen/arch/ppc/Kconfig | 7 +- xen/arch/ppc/Makefile| 2 + xen/arch/ppc/arch.mk | 1 - xen/arch/ppc/include/asm/bitops.h| 9 + xen/arch/ppc/include/asm/config.h| 2 +- xen/arch/ppc/include/asm/mm.h| 18 ++ xen/arch/ppc/include/asm/page-bits.h | 3 +- xen/arch/ppc/include/asm/page.h | 179 ++ xen/arch/ppc/include/asm/processor.h | 34 xen/arch/ppc/include/asm/regs.h | 138 ++ xen/arch/ppc/include/asm/types.h | 1 + xen/arch/ppc/mm-radix.c | 265 +++ xen/arch/ppc/ppc64/head.S| 42 + xen/arch/ppc/setup.c | 3 + xen/arch/ppc/tlb-radix.c | 96 ++ 15 files changed, 791 insertions(+), 9 deletions(-) create mode 100644 xen/arch/ppc/include/asm/bitops.h create mode 100644 xen/arch/ppc/include/asm/mm.h create mode 100644 xen/arch/ppc/include/asm/page.h create mode 100644 xen/arch/ppc/include/asm/regs.h create mode 100644 xen/arch/ppc/mm-radix.c create mode 100644 xen/arch/ppc/tlb-radix.c -- 2.30.2
[PATCH v3 3/3] xen/ppc: Implement initial Radix MMU support
Add code to construct early identity-mapped page tables as well as the required process and partition tables to enable the MMU. Signed-off-by: Shawn Anastasio --- v3: - Add XEN_PT_SIZE_LVL() macro for calculating the size in bytes of a page directory/page table structure. - Add alignment to struct lvl$N_{pd,pt} types. - Don't require aligned `paddr` in paddr_to_{pde,pte} - Fix RTS_FIELD comment bit numbering v2: - Add missing ')' to mm.h/maddr_to_virt definition - Add missing parens around `va` argument in XEN_PT_INDEX_LVL - Drop '&' asm constraint modifier in processor.h/mfmsr() - Fix asm constraint formatting in processor.h - Change mtspr,mfspr to functions in processor.h - Drop unnecessary _Static_assert in mm-radix.c - Drop unnecessary cast in setup_initial_mapping - Use __va() to obtain pde/pte addresses in setup_initial_mapping - Wrap >80col lines in mm-radix.c - Drop unnecessary parameters in setup_{process,partition}_table - Add __init to setup_{process,partition}_table - Drop unnecessary opal.c changes - Drop manual prototype of setup_initial_pagetables in setup.c in favor of using the one already in asm/mm.h - Fix formatting of tlbiel asm block in tlb-radix.c xen/arch/ppc/Makefile| 2 + xen/arch/ppc/include/asm/bitops.h| 9 + xen/arch/ppc/include/asm/mm.h| 18 ++ xen/arch/ppc/include/asm/page-bits.h | 3 +- xen/arch/ppc/include/asm/page.h | 179 ++ xen/arch/ppc/include/asm/processor.h | 34 xen/arch/ppc/include/asm/regs.h | 138 ++ xen/arch/ppc/include/asm/types.h | 1 + xen/arch/ppc/mm-radix.c | 265 +++ xen/arch/ppc/ppc64/head.S| 15 ++ xen/arch/ppc/setup.c | 3 + xen/arch/ppc/tlb-radix.c | 96 ++ 12 files changed, 762 insertions(+), 1 deletion(-) create mode 100644 xen/arch/ppc/include/asm/bitops.h create mode 100644 xen/arch/ppc/include/asm/mm.h create mode 100644 xen/arch/ppc/include/asm/page.h create mode 100644 xen/arch/ppc/include/asm/regs.h create mode 100644 xen/arch/ppc/mm-radix.c create mode 100644 xen/arch/ppc/tlb-radix.c diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile index 0c0a7884a1..a059ac4c0a 100644 --- a/xen/arch/ppc/Makefile +++ b/xen/arch/ppc/Makefile @@ -2,8 +2,10 @@ obj-$(CONFIG_PPC64) += ppc64/ obj-y += boot-of.init.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.init.o +obj-y += mm-radix.o obj-y += opal.o obj-y += setup.o +obj-y += tlb-radix.o $(TARGET): $(TARGET)-syms cp -f $< $@ diff --git a/xen/arch/ppc/include/asm/bitops.h b/xen/arch/ppc/include/asm/bitops.h new file mode 100644 index 00..548e97b414 --- /dev/null +++ b/xen/arch/ppc/include/asm/bitops.h @@ -0,0 +1,9 @@ +#ifndef _ASM_PPC_BITOPS_H +#define _ASM_PPC_BITOPS_H + +/* PPC bit number conversion */ +#define PPC_BITLSHIFT(be) (BITS_PER_LONG - 1 - (be)) +#define PPC_BIT(bit) (1UL << PPC_BITLSHIFT(bit)) +#define PPC_BITMASK(bs, be)((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) + +#endif /* _ASM_PPC_BITOPS_H */ diff --git a/xen/arch/ppc/include/asm/mm.h b/xen/arch/ppc/include/asm/mm.h new file mode 100644 index 00..c85a7ed686 --- /dev/null +++ b/xen/arch/ppc/include/asm/mm.h @@ -0,0 +1,18 @@ +#ifndef _ASM_PPC_MM_H +#define _ASM_PPC_MM_H + +#include + +#define pfn_to_paddr(pfn) ((paddr_t)(pfn) << PAGE_SHIFT) +#define paddr_to_pfn(pa) ((unsigned long)((pa) >> PAGE_SHIFT)) + +#define virt_to_maddr(va) ((paddr_t)((vaddr_t)(va) & PADDR_MASK)) +#define maddr_to_virt(pa) ((void *)((paddr_t)(pa) | XEN_VIRT_START)) + +/* Convert between Xen-heap virtual addresses and machine addresses. */ +#define __pa(x) (virt_to_maddr(x)) +#define __va(x) (maddr_to_virt(x)) + +void setup_initial_pagetables(void); + +#endif /* _ASM_PPC_MM_H */ diff --git a/xen/arch/ppc/include/asm/page-bits.h b/xen/arch/ppc/include/asm/page-bits.h index 4c01bf9716..0286177520 100644 --- a/xen/arch/ppc/include/asm/page-bits.h +++ b/xen/arch/ppc/include/asm/page-bits.h @@ -2,6 +2,7 @@ #define __PPC_PAGE_BITS_H__ #define PAGE_SHIFT 16 /* 64 KiB Pages */ -#define PADDR_BITS 48 +#define PADDR_BITS 53 +#define VADDR_BITS 52 #endif /* __PPC_PAGE_BITS_H__ */ diff --git a/xen/arch/ppc/include/asm/page.h b/xen/arch/ppc/include/asm/page.h new file mode 100644 index 00..51667a5e96 --- /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 + +#include +#include + +#define PDE_VALID PPC_BIT(0) +#define PDE_NLB_MASK 0xfUL +#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_CHANGEPPC_BIT(56) + +/* PTE Attributes */ +#define PTE
[PATCH 0/3] Initial support for Power
Hello all, This patch series adds support for building a minimal image (head.o-only) for Power ISA 2.07B+ (POWER8+) systems. The first patch boots to an infinite loop and the second adds early serial console support on pseries VMs, with bare metal support planned next. Since Xen previously had support for a much older version of the ISA in version 3.2.3, we were able to carry over some headers and support routines from that version. Unlike that initial port though, this effort focuses solely on POWER8+ CPUs that are capable of running in Little Endian mode. With an appropriate powerpc64le-linux-gnu cross-toolchain, the minimal image can be built with: $ make XEN_TARGET_ARCH=ppc64 -C xen openpower_defconfig $ make XEN_TARGET_ARCH=ppc64 SUBSYSTEMS=xen -C xen TARGET=ppc64/head.o The resulting head.o can then be booted in a standard QEMU/pseries VM: $ qemu-system-ppc64 -M pseries-5.2 -m 256M -kernel xen/ppc64/head.o \ -vga none -serial mon:stdio -nographic Thanks, Shawn Shawn Anastasio (3): xen: Add files needed for minimal Power build xen/ppc: Implement early serial printk on PaPR/pseries maintainers: Add PPC64 maintainer MAINTAINERS | 3 + config/ppc64.mk | 5 + xen/Makefile | 5 +- xen/arch/ppc/Kconfig | 42 + xen/arch/ppc/Kconfig.debug | 5 + xen/arch/ppc/Makefile| 18 ++ xen/arch/ppc/Rules.mk| 0 xen/arch/ppc/arch.mk | 11 ++ xen/arch/ppc/boot_of.c | 122 + xen/arch/ppc/configs/openpower_defconfig | 14 ++ xen/arch/ppc/early_printk.c | 36 xen/arch/ppc/include/asm/boot.h | 31 xen/arch/ppc/include/asm/bug.h | 6 + xen/arch/ppc/include/asm/byteorder.h | 74 xen/arch/ppc/include/asm/cache.h | 6 + xen/arch/ppc/include/asm/config.h| 66 +++ xen/arch/ppc/include/asm/early_printk.h | 14 ++ xen/arch/ppc/include/asm/msr.h | 67 +++ xen/arch/ppc/include/asm/page-bits.h | 7 + xen/arch/ppc/include/asm/processor.h | 223 +++ xen/arch/ppc/include/asm/reg_defs.h | 218 ++ xen/arch/ppc/include/asm/string.h| 6 + xen/arch/ppc/include/asm/types.h | 64 +++ xen/arch/ppc/ppc64/Makefile | 1 + xen/arch/ppc/ppc64/asm-offsets.c | 55 ++ xen/arch/ppc/ppc64/head.S| 126 + xen/arch/ppc/setup.c | 32 xen/arch/ppc/xen.lds.S | 173 ++ 28 files changed, 1428 insertions(+), 2 deletions(-) create mode 100644 config/ppc64.mk create mode 100644 xen/arch/ppc/Kconfig create mode 100644 xen/arch/ppc/Kconfig.debug create mode 100644 xen/arch/ppc/Makefile create mode 100644 xen/arch/ppc/Rules.mk create mode 100644 xen/arch/ppc/arch.mk create mode 100644 xen/arch/ppc/boot_of.c create mode 100644 xen/arch/ppc/configs/openpower_defconfig create mode 100644 xen/arch/ppc/early_printk.c create mode 100644 xen/arch/ppc/include/asm/boot.h create mode 100644 xen/arch/ppc/include/asm/bug.h create mode 100644 xen/arch/ppc/include/asm/byteorder.h create mode 100644 xen/arch/ppc/include/asm/cache.h create mode 100644 xen/arch/ppc/include/asm/config.h create mode 100644 xen/arch/ppc/include/asm/early_printk.h create mode 100644 xen/arch/ppc/include/asm/msr.h create mode 100644 xen/arch/ppc/include/asm/page-bits.h create mode 100644 xen/arch/ppc/include/asm/processor.h create mode 100644 xen/arch/ppc/include/asm/reg_defs.h create mode 100644 xen/arch/ppc/include/asm/string.h create mode 100644 xen/arch/ppc/include/asm/types.h create mode 100644 xen/arch/ppc/ppc64/Makefile create mode 100644 xen/arch/ppc/ppc64/asm-offsets.c create mode 100644 xen/arch/ppc/ppc64/head.S create mode 100644 xen/arch/ppc/setup.c create mode 100644 xen/arch/ppc/xen.lds.S -- 2.30.2
[PATCH 3/3] maintainers: Add PPC64 maintainer
Signed-off-by: Shawn Anastasio --- MAINTAINERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 1bb7a6a839..bcd36f9019 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -451,6 +451,9 @@ M: Wei Liu S: Supported T: git https://xenbits.xenproject.org/git-http/ovmf.git +PPC64 +M: Shawn Anastasio + POWER MANAGEMENT M: Jan Beulich S: Supported -- 2.30.2
[PATCH 1/3] xen: Add files needed for minimal Power build
Add the build system changes required to build for ppc64le (POWER8+). Following in the footsteps of the initial riscv port, only building the head.o target, which boots to an infinite loop, is supported: $ make XEN_TARGET_ARCH=ppc64 -C xen openpower_defconfig $ make XEN_TARGET_ARCH=ppc64 SUBSYSTEMS=xen -C xen TARGET=ppc64/head.o This port targets POWER8+ CPUs running in Little Endian mode specifically, and does not boot on older machines. Additionally, this initial skeleton only implements the PaPR/pseries boot protocol which allows it to be booted in a standard QEMU virtual machine: $ qemu-system-ppc64 -M pseries-5.2 -m 256M -kernel ppc64/head.o Where possible, this patch uses header definitions and support routines from the original Xen PowerPC port present in Xen 3.2.3. Though we are targeting a much newer ISA than that original port did, some of the definitions have remained similar enough for reuse. Signed-off-by: Shawn Anastasio --- config/ppc64.mk | 5 + xen/Makefile | 5 +- xen/arch/ppc/Kconfig | 42 + xen/arch/ppc/Kconfig.debug | 0 xen/arch/ppc/Makefile| 17 ++ xen/arch/ppc/Rules.mk| 0 xen/arch/ppc/arch.mk | 11 ++ xen/arch/ppc/configs/openpower_defconfig | 13 ++ xen/arch/ppc/include/asm/config.h| 63 +++ xen/arch/ppc/include/asm/msr.h | 67 +++ xen/arch/ppc/include/asm/page-bits.h | 7 + xen/arch/ppc/include/asm/processor.h | 173 ++ xen/arch/ppc/include/asm/reg_defs.h | 218 +++ xen/arch/ppc/ppc64/Makefile | 1 + xen/arch/ppc/ppc64/asm-offsets.c | 0 xen/arch/ppc/ppc64/head.S| 67 +++ xen/arch/ppc/setup.c | 14 ++ xen/arch/ppc/xen.lds.S | 173 ++ 18 files changed, 874 insertions(+), 2 deletions(-) create mode 100644 config/ppc64.mk create mode 100644 xen/arch/ppc/Kconfig create mode 100644 xen/arch/ppc/Kconfig.debug create mode 100644 xen/arch/ppc/Makefile create mode 100644 xen/arch/ppc/Rules.mk create mode 100644 xen/arch/ppc/arch.mk create mode 100644 xen/arch/ppc/configs/openpower_defconfig create mode 100644 xen/arch/ppc/include/asm/config.h create mode 100644 xen/arch/ppc/include/asm/msr.h create mode 100644 xen/arch/ppc/include/asm/page-bits.h create mode 100644 xen/arch/ppc/include/asm/processor.h create mode 100644 xen/arch/ppc/include/asm/reg_defs.h create mode 100644 xen/arch/ppc/ppc64/Makefile create mode 100644 xen/arch/ppc/ppc64/asm-offsets.c create mode 100644 xen/arch/ppc/ppc64/head.S create mode 100644 xen/arch/ppc/setup.c create mode 100644 xen/arch/ppc/xen.lds.S diff --git a/config/ppc64.mk b/config/ppc64.mk new file mode 100644 index 00..a46de35cf1 --- /dev/null +++ b/config/ppc64.mk @@ -0,0 +1,5 @@ +CONFIG_PPC64 := y +CONFIG_PPC64_64 := y +CONFIG_PPC64_$(XEN_OS) := y + +CONFIG_XEN_INSTALL_SUFFIX := diff --git a/xen/Makefile b/xen/Makefile index e89fc461fc..db5454fb58 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -38,7 +38,7 @@ EFI_MOUNTPOINT ?= $(BOOT_DIR)/efi ARCH=$(XEN_TARGET_ARCH) SRCARCH=$(shell echo $(ARCH) | \ sed -e 's/x86.*/x86/' -e s'/arm\(32\|64\)/arm/g' \ - -e s'/riscv.*/riscv/g') + -e s'/riscv.*/riscv/g' -e s'/ppc.*/ppc/g') export ARCH SRCARCH # Allow someone to change their config file @@ -244,7 +244,7 @@ include $(XEN_ROOT)/Config.mk export TARGET_SUBARCH := $(XEN_TARGET_ARCH) export TARGET_ARCH := $(shell echo $(XEN_TARGET_ARCH) | \ sed -e 's/x86.*/x86/' -e s'/arm\(32\|64\)/arm/g' \ --e s'/riscv.*/riscv/g') +-e s'/riscv.*/riscv/g' -e s'/ppc.*/ppc/g') export CONFIG_SHELL := $(SHELL) export CC CXX LD NM OBJCOPY OBJDUMP ADDR2LINE @@ -563,6 +563,7 @@ _clean: $(Q)$(MAKE) $(clean)=xsm $(Q)$(MAKE) $(clean)=crypto $(Q)$(MAKE) $(clean)=arch/arm + $(Q)$(MAKE) $(clean)=arch/ppc $(Q)$(MAKE) $(clean)=arch/riscv $(Q)$(MAKE) $(clean)=arch/x86 $(Q)$(MAKE) $(clean)=test diff --git a/xen/arch/ppc/Kconfig b/xen/arch/ppc/Kconfig new file mode 100644 index 00..e80a5fb036 --- /dev/null +++ b/xen/arch/ppc/Kconfig @@ -0,0 +1,42 @@ +config PPC + def_bool y + +config PPC64 + def_bool y + select 64BIT + +config ARCH_DEFCONFIG + string + default "arch/ppc/configs/openpower_defconfig" + +menu "Architecture Features" + +source "arch/Kconfig" + +endmenu + +menu "ISA Selection" + +choice + prompt "Base ISA" + default POWER_ISA_2_07B if PPC64 + help + This selects the base ISA version that Xen will target. + +c
[PATCH 2/3] xen/ppc: Implement early serial printk on PaPR/pseries
On typical Power VMs (e.g. QEMU's -M pseries), a variety of services are provided by OpenFirmware, including an early serial console. Implement the required interfaces to call into OpenFirmware and write to the serial console. Since OpenFirmware runs in 32-bit Big Endian mode and Xen runs in 64-bit Little Endian mode, a thunk is required to save/restore any potentially-clobbered registers as well as to perform the required endianness switch. Thankfully, linux already has such a routine, which was imported into head.S. Support for bare metal (PowerNV) will be implemented in a future patch. Signed-off-by: Shawn Anastasio --- xen/arch/ppc/Kconfig.debug | 5 + xen/arch/ppc/Makefile| 3 +- xen/arch/ppc/boot_of.c | 122 +++ xen/arch/ppc/configs/openpower_defconfig | 1 + xen/arch/ppc/early_printk.c | 36 +++ xen/arch/ppc/include/asm/boot.h | 31 ++ xen/arch/ppc/include/asm/bug.h | 6 ++ xen/arch/ppc/include/asm/byteorder.h | 74 ++ xen/arch/ppc/include/asm/cache.h | 6 ++ xen/arch/ppc/include/asm/config.h| 3 + xen/arch/ppc/include/asm/early_printk.h | 14 +++ xen/arch/ppc/include/asm/processor.h | 54 +- xen/arch/ppc/include/asm/string.h| 6 ++ xen/arch/ppc/include/asm/types.h | 64 xen/arch/ppc/ppc64/asm-offsets.c | 55 ++ xen/arch/ppc/ppc64/head.S| 59 +++ xen/arch/ppc/setup.c | 20 +++- 17 files changed, 555 insertions(+), 4 deletions(-) create mode 100644 xen/arch/ppc/boot_of.c create mode 100644 xen/arch/ppc/early_printk.c create mode 100644 xen/arch/ppc/include/asm/boot.h create mode 100644 xen/arch/ppc/include/asm/bug.h create mode 100644 xen/arch/ppc/include/asm/byteorder.h create mode 100644 xen/arch/ppc/include/asm/cache.h create mode 100644 xen/arch/ppc/include/asm/early_printk.h create mode 100644 xen/arch/ppc/include/asm/string.h create mode 100644 xen/arch/ppc/include/asm/types.h diff --git a/xen/arch/ppc/Kconfig.debug b/xen/arch/ppc/Kconfig.debug index e69de29bb2..3c25a446e8 100644 --- a/xen/arch/ppc/Kconfig.debug +++ b/xen/arch/ppc/Kconfig.debug @@ -0,0 +1,5 @@ +config EARLY_PRINTK +bool "Enable early printk" +default DEBUG +help + Enables early printk debug messages \ No newline at end of file diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile index b3ad837d4b..00b3b7baf3 100644 --- a/xen/arch/ppc/Makefile +++ b/xen/arch/ppc/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_PPC64) += ppc64/ -obj-y += setup.o +obj-y += setup.o boot_of.o +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o $(TARGET): $(TARGET)-syms cp -f $< $@ diff --git a/xen/arch/ppc/boot_of.c b/xen/arch/ppc/boot_of.c new file mode 100644 index 00..9447d92661 --- /dev/null +++ b/xen/arch/ppc/boot_of.c @@ -0,0 +1,122 @@ +/* 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. + * + * Copyright IBM Corp. 2005, 2006, 2007 + * Copyright Raptor Engineering, LLC + * + * Authors: Jimi Xenidis + * Hollis Blanchard + * Shawn Anastasio + */ + +#include +#include +#include +#include +#include + +#define ADDR(x) (uint32_t)(unsigned long)(x) + +/* OF entrypoint*/ +static unsigned long of_vec; + +/* OF device handles*/ +static int bof_chosen; +static int of_out; + +static int of_call(const char *service, uint32_t nargs, uint32_t nrets, + int32_t rets[], ...) +{ +int rc; +va_list args; +int i; +struct of_service s = { 0 }; + +s.ofs_service = cpu_to_be32(ADDR(service)); +s.ofs_nargs = cpu_to_be32(nargs); +s.ofs_nrets = cpu_to_be32(nrets); + +/* copy all the params into the args array */ +va_start(args, rets); + +for ( i = 0; i < nargs; i++ ) +{ +s.ofs_args[i] = cpu_to_be32(va_arg(args, uint32_t)); +} + +va_end(args); + +rc = enter_prom(&s, of_vec); + +/* yes always to the copy, just in case */ +for ( i = 0; i < nrets; i++ ) +{ +rets[i] = be32_to_cpu(s.ofs_args[i + nargs]); +} + +return rc; +} + +static int of_finddevice(const char *devspec) +{ +int rets[1] = {
Re: [PATCH 0/3] Initial support for Power
On Wed Jun 7, 2023 at 1:07 PM CDT, Andrew Cooper wrote: > Oh wow - this is a surprise, but certainly a good one. I'm glad to hear that! > We've recently done just a similar exercise with RISCV64, starting with > getting cross-compilation and a basic smoke test into our CI. I see. I used the initial RISC-V patch as a model for patch 1, though I didn't realize that the TARGET= override were unnecessary for getting a minimal image building. > We use gitlab CI, and one example is > https://gitlab.com/xen-project/xen/-/pipelines/889871648 (search for > riscv64 in amongst all the x86 and ARM). > > The configuration is all in tree, in the automation/ directory. > Relevant files to copy/tweak are: > > automation/build/archlinux/current-riscv64.dockerfile (x86 cross compile > container) > automation/scripts/qemu-smoke-riscv64.sh (smoke test script) > automation/gitlab-ci/{build,test}.yaml (wire the jobs up) > > The smoke test looks on stdout for "All set up" which can be any string > put out via earlyprintk. Thanks for the pointer -- I'll use this as a model to implement a similar smoke test for PPC64. > If you look around in the Xen tree at bb62c25e3e5c and take the makefile > override's in particular, you should be able to get `make -C xen build` > work without any magic TARGET= overrides, and without most of the > headers you've added in patch 1. The trick is to have a head.S which > doesn't include any files (except the config.h it gets implicitly). Perfect. I'll start work on a v2 without the TARGET= overrides and without the headers in patch #1. > We're still trying to do some re-arranging to the common / arch split to > remove unnecessary boilerplate. Having a set of PPC headers too will > make it easier to spot the rough edges in the current boundary. Great. I've been using arch/arm and arch/riscv as models for which headers to define (as well as the build errors that inevitably pop up when including xen/lib.h or similar). Is this a reasonable approach for now? > Looking to the future, where could XenProject get some real hardware to > put into our CI systems? We'd want to do that in due course. As an employee of Raptor Engineering, my recommendation for an OpenPOWER system would definitely be the Talos II or Blackbird families from Raptor Computing Systems: https://www.raptorcs.com/ :) > I see you've nominated yourself as maintainer, which is of course fine. > How much time do you have to put towards this? It is some part of a > full time job, or just your own free time? I'm currently working on the port full-time for Raptor Engineering. > Do you have any suggested reading for those of us who are invariably > going to need to learn some of the CPU/platform/architecture details, > but aren't really PPC-literate right now? We have a pretty extensive library of documentation covering the ISA as well as CPU and platform details available here: https://wiki.raptorcs.com/wiki/Category:Documentation > Thanks, and welcome. Thanks! Shawn
Re: [PATCH 0/3] Initial support for Power
On Wed Jun 7, 2023 at 2:30 PM CDT, Andrew Cooper wrote: > Ok, in which case you probably want a first patch series doing: > > 1) New docker container (only - this wants to be taken early and set up > in CI) > 2) one-or-more initial build system + head.S infinite loop patch. > Probably the maintainer patch too. > 3) Wiring the build(s) into build.yaml > > You'll want to join the https://gitlab.com/xen-project/ and I can set > you up with a place to run the full CI (we have a reasonably custom > setup which the communal runners don't like). You may also want to hang > out on oftc.org #xendevel and/or the matrix bridge thereof. > > Then a second patch series doing early printk, and adding the smoke test > script and wiring it into test.yaml. Sounds good. I've gone ahead and requested access to that GitLab organization and will get to work on a series doing the things you've requested. P.S. It seems mail from my server is getting rejected by your server, so I'm unable to respond to you directly. Once I have access to my corporate email this should be resolved, but until then I'll reach out to you from a personal email address. Thanks.
Re: [PATCH 2/3] xen/ppc: Implement early serial printk on PaPR/pseries
On Fri Jun 9, 2023 at 5:12 AM CDT, Julien Grall wrote: > Strictly speaking we can refuse any code. That count for license as > well. Anyway, I didn't request a change here. I merely pointed out that > any use of GPLv2+ should be justified because on Arm most of the people > don't pay attention on the license and pick the one from an existing file. Hi Julien, The choice of GPLv2+ for many of the files in this patchset was indeed inherited from old IBM-written Xen code that the files in question were derived from. I did not realize it was permissible or even desirable to relicense those to GPLv2-only. As for the new files, GPLv2+ was chosen to remain consistent and to open the door for future derivations from GPLv2+ licensed code, either from the older Xen tree or from the Linux ppc tree, much of which is also licensed as GPLv2+. If it would reduce friction, these files could be relicensed to GPLv2-only. Thanks, Shawn
Re: [PATCH 1/3] xen: Add files needed for minimal Power build
On Fri Jun 9, 2023 at 4:15 AM CDT, Jan Beulich wrote: > > --- /dev/null > > +++ b/config/ppc64.mk > > @@ -0,0 +1,5 @@ > > +CONFIG_PPC64 := y > > +CONFIG_PPC64_64 := y > > +CONFIG_PPC64_$(XEN_OS) := y > > The first of the 64-s here are a little odd; looking at RISC-V's > counterpart, wouldn't this want to be > > CONFIG_PPC := y > CONFIG_PPC_64 := y > CONFIG_PPC_$(XEN_OS) := y> Good point, this was definitely an oversight on my part. I'll clean this up in v2. > > --- /dev/null > > +++ b/xen/arch/ppc/Kconfig > > @@ -0,0 +1,42 @@ > > +config PPC > > + def_bool y > > Is this necessary? Iirc PPC is frequently used as a name for 32-bit PPC > (but then also elsewhere as covering both 32- and 64-bit), so I'm not > sure we want this without having a need for it. This was mostly modeled after riscv/Kconfig. The idea was that this option guards PPC support in general (both 32- and 64-bit) and the subsequent option specifically opts in to 64-bit. Given that this effort is only targeting 64-bit mode, though, the argument could definitely be made that having the two options is redundant, but I believe that is also the case for the risc-v port. > > +config PPC64 > > + def_bool y > > + select 64BIT > > + > > +config ARCH_DEFCONFIG > > + string > > + default "arch/ppc/configs/openpower_defconfig" > > + > > +menu "Architecture Features" > > + > > +source "arch/Kconfig" > > + > > +endmenu > > + > > +menu "ISA Selection" > > + > > +choice > > + prompt "Base ISA" > > + default POWER_ISA_2_07B if PPC64 > > + help > > + This selects the base ISA version that Xen will target. > > + > > +config POWER_ISA_2_07B > > + bool "POWER ISA 2.07B+" > > + help > > + Target version 2.07B+ of the POWER ISA (POWER8+) > > + > > +config POWER_ISA_3_00 > > + bool "POWER ISA 3.00+" > > + help > > + Target version 3.00+ of the POWER ISA (POWER9+) > > What are the + in here meant to indicate? Since this is about a baseline > ISA, I find such a use (presumably standing for "or newer") ambiguous. Fair point. The + was intended as an "or newer" but I agree that it's ambiguous (for instance, it might be interpreted as a part of the ISA's name). I'll remove it in v2, along with a renaming of "POWER ISA" to "Power ISA" which I originally overlooked. > Jan Thanks, Shawn
Re: [PATCH 2/3] xen/ppc: Implement early serial printk on PaPR/pseries
On Fri Jun 9, 2023 at 4:22 AM CDT, Jan Beulich wrote: > > xen/arch/ppc/Kconfig.debug | 5 + > > xen/arch/ppc/Makefile| 3 +- > > xen/arch/ppc/boot_of.c | 122 +++ > > xen/arch/ppc/configs/openpower_defconfig | 1 + > > xen/arch/ppc/early_printk.c | 36 +++ > > xen/arch/ppc/include/asm/boot.h | 31 ++ > > xen/arch/ppc/include/asm/bug.h | 6 ++ > > xen/arch/ppc/include/asm/byteorder.h | 74 ++ > > xen/arch/ppc/include/asm/cache.h | 6 ++ > > xen/arch/ppc/include/asm/config.h| 3 + > > xen/arch/ppc/include/asm/early_printk.h | 14 +++ > > xen/arch/ppc/include/asm/processor.h | 54 +- > > xen/arch/ppc/include/asm/string.h| 6 ++ > > xen/arch/ppc/include/asm/types.h | 64 > > xen/arch/ppc/ppc64/asm-offsets.c | 55 ++ > > xen/arch/ppc/ppc64/head.S| 59 +++ > > xen/arch/ppc/setup.c | 20 +++- > > 17 files changed, 555 insertions(+), 4 deletions(-) > > create mode 100644 xen/arch/ppc/boot_of.c > > Unless required, in new additions we tend to prefer dashes over > underscores. In filenames it is pretty rare that dashes really need > avoiding. Thanks for pointing that out -- I'll fix this in v2. > > --- a/xen/arch/ppc/Kconfig.debug > > +++ b/xen/arch/ppc/Kconfig.debug > > @@ -0,0 +1,5 @@ > > +config EARLY_PRINTK > > +bool "Enable early printk" > > +default DEBUG > > +help > > + Enables early printk debug messages > > \ No newline at end of file > > There are many examples of this throughout the patch, which you want to > take care of. Ditto. > > --- /dev/null > > +++ b/xen/arch/ppc/boot_of.c > > @@ -0,0 +1,122 @@ > > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > > By default we mean to use ... > > > --- /dev/null > > +++ b/xen/arch/ppc/early_printk.c > > @@ -0,0 +1,36 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > ... the more modern form of this (GPL-2.0-only). Anything deviating from > that may want justifying in the description. Got it -- I'll clean this up as well. > Jan Thanks, Shawn
Re: [PATCH 3/3] maintainers: Add PPC64 maintainer
On Fri Jun 9, 2023 at 4:04 AM CDT, Jan Beulich wrote: > On 07.06.2023 17:06, Shawn Anastasio wrote: > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -451,6 +451,9 @@ M: Wei Liu > > S: Supported > > T: git https://xenbits.xenproject.org/git-http/ovmf.git > > > > +PPC64 > > +M: Shawn Anastasio > > + > > POWER MANAGEMENT > > M: Jan Beulich > > S: Supported > > Nit: You want to move your insertion further down, to maintain alphabetic > sorting. You further want at least one F: line; see e.g. RISC-V's entry. Will fix in v2. > Jan Thanks, Shawn
Re: [PATCH 2/3] xen/ppc: Implement early serial printk on PaPR/pseries
On Fri Jun 9, 2023 at 11:07 AM CDT, Julien Grall wrote: > Thanks for the explanations. To clarify, are you saying that all the > files will be GPLv2+ or just some? My idea was to license any file where I expect there to derivations from existing code as GPLv2+, and fall back to GPLv2-only for newly-written files for which I expect there to be no reuse of existing GPLv2+ code. > If the latter, then my concern would be that if you need to import > GPLv2-only code, then you may need to write your code in a different > file. This may become messy to handle and some developer may end up to > be confused. Agreed, and I definitely want to minimize confusion. Ultimately I think situations like this will be unavoidable, though, since derivations will likely need to be made from both GPLv2-only and GPLv2+ code. > Cheers, Thanks, Shawn
[PATCH v2 0/4] Initial support for Power
Hello all, This patch series adds support for building a minimal image (head.o-only) for Power ISA 2.07B+ (POWER8+) systems. The first patch boots to an infinite loop and the second adds early serial console support on pseries VMs, with bare metal support planned next. Since Xen previously had support for a much older version of the ISA in version 3.2.3, we were able to carry over some headers and support routines from that version. Unlike that initial port though, this effort focuses solely on POWER8+ CPUs that are capable of running in Little Endian mode. With an appropriate powerpc64le-linux-gnu cross-toolchain, the minimal image can be built with: $ make XEN_TARGET_ARCH=ppc64 -C xen openpower_defconfig $ make XEN_TARGET_ARCH=ppc64 SUBSYSTEMS=xen -C xen TARGET=ppc64/head.o The resulting head.o can then be booted in a standard QEMU/pseries VM: $ qemu-system-ppc64 -M pseries-5.2 -m 256M -kernel xen/ppc64/head.o \ -vga none -serial mon:stdio -nographic Thanks, Shawn -- Changes from v2: - Add ppc64le cross-build container patch - Add ppc64le cross build CI job patch - Drop serial output patch (will be in future patch series) - Drop setup.c and unneeded headers from minimal build patch - Fixed ordering of MAINTAINERS patch + add F: line - Fix config/ppc64.mk option names - Clarify Kconfig Baseline ISA option help strings Shawn Anastasio (4): automation: Add container for ppc64le builds xen: Add files needed for minimal ppc64le build automation: Add ppc64le cross-build jobs maintainers: Add ppc64 maintainer MAINTAINERS | 4 + .../build/debian/bullseye-ppc64le.dockerfile | 28 +++ automation/gitlab-ci/build.yaml | 60 ++ automation/scripts/containerize | 1 + config/ppc64.mk | 5 + xen/Makefile | 5 +- xen/arch/ppc/Kconfig | 42 + xen/arch/ppc/Kconfig.debug| 0 xen/arch/ppc/Makefile | 16 ++ xen/arch/ppc/Rules.mk | 0 xen/arch/ppc/arch.mk | 11 ++ xen/arch/ppc/configs/openpower_defconfig | 13 ++ xen/arch/ppc/include/asm/config.h | 63 +++ xen/arch/ppc/include/asm/page-bits.h | 7 + xen/arch/ppc/ppc64/Makefile | 1 + xen/arch/ppc/ppc64/asm-offsets.c | 0 xen/arch/ppc/ppc64/head.S | 27 +++ xen/arch/ppc/xen.lds.S| 173 ++ 18 files changed, 454 insertions(+), 2 deletions(-) create mode 100644 automation/build/debian/bullseye-ppc64le.dockerfile create mode 100644 config/ppc64.mk create mode 100644 xen/arch/ppc/Kconfig create mode 100644 xen/arch/ppc/Kconfig.debug create mode 100644 xen/arch/ppc/Makefile create mode 100644 xen/arch/ppc/Rules.mk create mode 100644 xen/arch/ppc/arch.mk create mode 100644 xen/arch/ppc/configs/openpower_defconfig create mode 100644 xen/arch/ppc/include/asm/config.h create mode 100644 xen/arch/ppc/include/asm/page-bits.h create mode 100644 xen/arch/ppc/ppc64/Makefile create mode 100644 xen/arch/ppc/ppc64/asm-offsets.c create mode 100644 xen/arch/ppc/ppc64/head.S create mode 100644 xen/arch/ppc/xen.lds.S -- 2.30.2
[PATCH v2 2/4] xen: Add files needed for minimal ppc64le build
Add the build system changes required to build for ppc64le (POWER8+). As of now the resulting image simply boots to an infinite loop. $ make XEN_TARGET_ARCH=ppc64 -C xen openpower_defconfig $ make XEN_TARGET_ARCH=ppc64 SUBSYSTEMS=xen -C xen build This port targets POWER8+ CPUs running in Little Endian mode specifically, and does not boot on older machines. Additionally, this initial skeleton only implements the PaPR/pseries boot protocol which allows it to be booted in a standard QEMU virtual machine: $ qemu-system-ppc64 -M pseries-5.2 -m 256M -kernel xen/xen Signed-off-by: Shawn Anastasio --- config/ppc64.mk | 5 + xen/Makefile | 5 +- xen/arch/ppc/Kconfig | 42 ++ xen/arch/ppc/Kconfig.debug | 0 xen/arch/ppc/Makefile| 16 +++ xen/arch/ppc/Rules.mk| 0 xen/arch/ppc/arch.mk | 11 ++ xen/arch/ppc/configs/openpower_defconfig | 13 ++ xen/arch/ppc/include/asm/config.h| 63 + xen/arch/ppc/include/asm/page-bits.h | 7 + xen/arch/ppc/ppc64/Makefile | 1 + xen/arch/ppc/ppc64/asm-offsets.c | 0 xen/arch/ppc/ppc64/head.S| 27 xen/arch/ppc/xen.lds.S | 173 +++ 14 files changed, 361 insertions(+), 2 deletions(-) create mode 100644 config/ppc64.mk create mode 100644 xen/arch/ppc/Kconfig create mode 100644 xen/arch/ppc/Kconfig.debug create mode 100644 xen/arch/ppc/Makefile create mode 100644 xen/arch/ppc/Rules.mk create mode 100644 xen/arch/ppc/arch.mk create mode 100644 xen/arch/ppc/configs/openpower_defconfig create mode 100644 xen/arch/ppc/include/asm/config.h create mode 100644 xen/arch/ppc/include/asm/page-bits.h create mode 100644 xen/arch/ppc/ppc64/Makefile create mode 100644 xen/arch/ppc/ppc64/asm-offsets.c create mode 100644 xen/arch/ppc/ppc64/head.S create mode 100644 xen/arch/ppc/xen.lds.S diff --git a/config/ppc64.mk b/config/ppc64.mk new file mode 100644 index 00..597f0668c3 --- /dev/null +++ b/config/ppc64.mk @@ -0,0 +1,5 @@ +CONFIG_PPC := y +CONFIG_PPC64 := y +CONFIG_PPC_$(XEN_OS) := y + +CONFIG_XEN_INSTALL_SUFFIX := diff --git a/xen/Makefile b/xen/Makefile index e89fc461fc..db5454fb58 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -38,7 +38,7 @@ EFI_MOUNTPOINT ?= $(BOOT_DIR)/efi ARCH=$(XEN_TARGET_ARCH) SRCARCH=$(shell echo $(ARCH) | \ sed -e 's/x86.*/x86/' -e s'/arm\(32\|64\)/arm/g' \ - -e s'/riscv.*/riscv/g') + -e s'/riscv.*/riscv/g' -e s'/ppc.*/ppc/g') export ARCH SRCARCH # Allow someone to change their config file @@ -244,7 +244,7 @@ include $(XEN_ROOT)/Config.mk export TARGET_SUBARCH := $(XEN_TARGET_ARCH) export TARGET_ARCH := $(shell echo $(XEN_TARGET_ARCH) | \ sed -e 's/x86.*/x86/' -e s'/arm\(32\|64\)/arm/g' \ --e s'/riscv.*/riscv/g') +-e s'/riscv.*/riscv/g' -e s'/ppc.*/ppc/g') export CONFIG_SHELL := $(SHELL) export CC CXX LD NM OBJCOPY OBJDUMP ADDR2LINE @@ -563,6 +563,7 @@ _clean: $(Q)$(MAKE) $(clean)=xsm $(Q)$(MAKE) $(clean)=crypto $(Q)$(MAKE) $(clean)=arch/arm + $(Q)$(MAKE) $(clean)=arch/ppc $(Q)$(MAKE) $(clean)=arch/riscv $(Q)$(MAKE) $(clean)=arch/x86 $(Q)$(MAKE) $(clean)=test diff --git a/xen/arch/ppc/Kconfig b/xen/arch/ppc/Kconfig new file mode 100644 index 00..a0a70adef4 --- /dev/null +++ b/xen/arch/ppc/Kconfig @@ -0,0 +1,42 @@ +config PPC + def_bool y + +config PPC64 + def_bool y + select 64BIT + +config ARCH_DEFCONFIG + string + default "arch/ppc/configs/openpower_defconfig" + +menu "Architecture Features" + +source "arch/Kconfig" + +endmenu + +menu "ISA Selection" + +choice + prompt "Base ISA" + default POWER_ISA_2_07B if PPC64 + help + This selects the base ISA version that Xen will target. + +config POWER_ISA_2_07B + bool "Power ISA 2.07B" + help + Target version 2.07B of the Power ISA (POWER8) + +config POWER_ISA_3_00 + bool "Power ISA 3.00" + help + Target version 3.00 of the Power ISA (POWER9) + +endchoice + +endmenu + +source "common/Kconfig" + +source "drivers/Kconfig" diff --git a/xen/arch/ppc/Kconfig.debug b/xen/arch/ppc/Kconfig.debug new file mode 100644 index 00..e69de29bb2 diff --git a/xen/arch/ppc/Makefile b/xen/arch/ppc/Makefile new file mode 100644 index 00..10b101cf9c --- /dev/null +++ b/xen/arch/ppc/Makefile @@ -0,0 +1,16 @@ +obj-$(CONFIG_PPC64) += ppc64/ + +$(TARGET): $(TARGET)-syms + cp -f $< $@ + +$(TARGET)-syms: $(objtree)/prelink.o $(obj)/xen.lds + $(LD
[PATCH v2 3/4] automation: Add ppc64le cross-build jobs
Add build jobs to cross-compile Xen for ppc64le. Signed-off-by: Shawn Anastasio --- automation/gitlab-ci/build.yaml | 60 + 1 file changed, 60 insertions(+) diff --git a/automation/gitlab-ci/build.yaml b/automation/gitlab-ci/build.yaml index 420ffa5acb..bd8c7332db 100644 --- a/automation/gitlab-ci/build.yaml +++ b/automation/gitlab-ci/build.yaml @@ -183,6 +183,33 @@ variables: <<: *gcc +.ppc64le-cross-build-tmpl: + <<: *build + variables: +XEN_TARGET_ARCH: ppc64 + tags: +- x86_64 + +.ppc64le-cross-build: + extends: .ppc64le-cross-build-tmpl + variables: +debug: n + +.ppc64le-cross-build-debug: + extends: .ppc64le-cross-build-tmpl + variables: +debug: y + +.gcc-ppc64le-cross-build: + extends: .ppc64le-cross-build + variables: +<<: *gcc + +.gcc-ppc64le-cross-build-debug: + extends: .ppc64le-cross-build-debug + variables: +<<: *gcc + .yocto-test: stage: build image: registry.gitlab.com/xen-project/xen/${CONTAINER} @@ -516,6 +543,39 @@ archlinux-current-gcc-riscv64-debug-randconfig: EXTRA_FIXED_RANDCONFIG: CONFIG_COVERAGE=n +# Power cross-build +debian-bullseye-gcc-ppc64le: + extends: .gcc-ppc64le-cross-build + variables: +CONTAINER: debian:bullseye-ppc64le +KBUILD_DEFCONFIG: openpower_defconfig +HYPERVISOR_ONLY: y + +debian-bullseye-gcc-ppc64le-debug: + extends: .gcc-ppc64le-cross-build-debug + variables: +CONTAINER: debian:bullseye-ppc64le +KBUILD_DEFCONFIG: openpower_defconfig +HYPERVISOR_ONLY: y + +debian-bullseye-gcc-ppc64le-randconfig: + extends: .gcc-ppc64le-cross-build + variables: +CONTAINER: debian:bullseye-ppc64le +KBUILD_DEFCONFIG: openpower_defconfig +RANDCONFIG: y +EXTRA_FIXED_RANDCONFIG: + CONFIG_COVERAGE=n + +debian-bullseye-gcc-ppc64le-debug-randconfig: + extends: .gcc-ppc64le-cross-build-debug + variables: +CONTAINER: debian:bullseye-ppc64le +KBUILD_DEFCONFIG: openpower_defconfig +RANDCONFIG: y +EXTRA_FIXED_RANDCONFIG: + CONFIG_COVERAGE=n + # Yocto test jobs yocto-qemuarm64: extends: .yocto-test-arm64 -- 2.30.2
[PATCH v2 1/4] automation: Add container for ppc64le builds
Add a container for cross-compiling xen for ppc64le. Signed-off-by: Shawn Anastasio --- .../build/debian/bullseye-ppc64le.dockerfile | 28 +++ automation/scripts/containerize | 1 + 2 files changed, 29 insertions(+) create mode 100644 automation/build/debian/bullseye-ppc64le.dockerfile diff --git a/automation/build/debian/bullseye-ppc64le.dockerfile b/automation/build/debian/bullseye-ppc64le.dockerfile new file mode 100644 index 00..8a87631b52 --- /dev/null +++ b/automation/build/debian/bullseye-ppc64le.dockerfile @@ -0,0 +1,28 @@ +FROM debian:bullseye-slim +LABEL maintainer.name="The Xen Project" \ + maintainer.email="xen-devel@lists.xenproject.org" + +ENV DEBIAN_FRONTEND=noninteractive +ENV USER root + +# Add compiler path +ENV CROSS_COMPILE powerpc64le-linux-gnu- + +RUN mkdir /build +WORKDIR /build + +# build depends +RUN apt-get update && \ +apt-get --quiet --yes --no-install-recommends install \ +bison \ +build-essential \ +checkpolicy \ +flex \ +gawk \ +gcc-powerpc64le-linux-gnu \ +make \ +python3-minimal \ +&& \ +apt-get autoremove -y && \ +apt-get clean && \ +rm -rf /var/lib/apt/lists* /tmp/* /var/tmp/* diff --git a/automation/scripts/containerize b/automation/scripts/containerize index 5476ff0ea1..6d46f63665 100755 --- a/automation/scripts/containerize +++ b/automation/scripts/containerize @@ -33,6 +33,7 @@ case "_${CONTAINER}" in _focal) CONTAINER="${BASE}/ubuntu:focal" ;; _jessie) CONTAINER="${BASE}/debian:jessie" ;; _jessie-i386) CONTAINER="${BASE}/debian:jessie-i386" ;; +_bullseye-ppc64le) CONTAINER="${BASE}/debian:bullseye-ppc64le" ;; _stretch|_) CONTAINER="${BASE}/debian:stretch" ;; _stretch-i386) CONTAINER="${BASE}/debian:stretch-i386" ;; _buster-gcc-ibt) CONTAINER="${BASE}/debian:buster-gcc-ibt" ;; -- 2.30.2
[PATCH v2 4/4] maintainers: Add ppc64 maintainer
Signed-off-by: Shawn Anastasio --- MAINTAINERS | 4 1 file changed, 4 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 1bb7a6a839..8966175400 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -460,6 +460,10 @@ X: xen/arch/x86/acpi/lib.c F: xen/drivers/cpufreq/ F: xen/include/acpi/cpufreq/ +PPC64 +M: Shawn Anastasio +F: xen/arch/ppc + PUBLIC I/O INTERFACES AND PV DRIVERS DESIGNS M: Juergen Gross S: Supported -- 2.30.2