Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 May 2011 13:27:28 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r221959 - in projects/pseries: conf powerpc/conf powerpc/powerpc powerpc/pseries
Message-ID:  <201105151327.p4FDRSIu040692@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: nwhitehorn
Date: Sun May 15 13:27:28 2011
New Revision: 221959
URL: http://svn.freebsd.org/changeset/base/221959

Log:
  Add initial code to support the IBM POWER hypervisor (e.g. LPARs on pSeries)
  machines, based on initial work by Andreas Tobler. This is sufficient to
  boot to the kernel complaining about not having drivers for anything on
  a POWER5+ P285 and on the POWER7 LPAR emulator recently added by IBM to
  QEMU. The specification for the hypervisor was provided in the PAPR 2.4
  documentation provided by the Power.org consortium.

Added:
  projects/pseries/powerpc/pseries/
  projects/pseries/powerpc/pseries/mmu_phyp.c   (contents, props changed)
  projects/pseries/powerpc/pseries/phyp-hvcall.S   (contents, props changed)
  projects/pseries/powerpc/pseries/phyp-hvcall.h   (contents, props changed)
  projects/pseries/powerpc/pseries/platform_chrp.c   (contents, props changed)
Modified:
  projects/pseries/conf/files.powerpc
  projects/pseries/conf/options.powerpc
  projects/pseries/powerpc/conf/GENERIC64
  projects/pseries/powerpc/powerpc/cpu.c

Modified: projects/pseries/conf/files.powerpc
==============================================================================
--- projects/pseries/conf/files.powerpc	Sun May 15 13:25:26 2011	(r221958)
+++ projects/pseries/conf/files.powerpc	Sun May 15 13:27:28 2011	(r221959)
@@ -205,6 +205,9 @@ powerpc/ps3/ps3bus.c		optional	ps3
 powerpc/ps3/ps3pic.c		optional	ps3
 powerpc/ps3/ps3_syscons.c	optional	ps3 sc
 powerpc/ps3/ps3-hvcall.S	optional	ps3 sc
+powerpc/pseries/phyp-hvcall.S	optional	pseries powerpc64
+powerpc/pseries/mmu_phyp.c	optional	pseries powerpc64
+powerpc/pseries/platform_chrp.c	optional	pseries
 powerpc/psim/iobus.c 		optional	psim
 powerpc/psim/ata_iobus.c	optional	ata psim
 powerpc/psim/openpic_iobus.c	optional	psim

Modified: projects/pseries/conf/options.powerpc
==============================================================================
--- projects/pseries/conf/options.powerpc	Sun May 15 13:25:26 2011	(r221958)
+++ projects/pseries/conf/options.powerpc	Sun May 15 13:27:28 2011	(r221959)
@@ -20,6 +20,7 @@ MPC85XX			opt_platform.h
 POWERMAC		opt_platform.h
 PS3			opt_platform.h
 MAMBO
+PSERIES
 PSIM
 
 SC_OFWFB		opt_ofwfb.h

Modified: projects/pseries/powerpc/conf/GENERIC64
==============================================================================
--- projects/pseries/powerpc/conf/GENERIC64	Sun May 15 13:25:26 2011	(r221958)
+++ projects/pseries/powerpc/conf/GENERIC64	Sun May 15 13:27:28 2011	(r221959)
@@ -29,6 +29,7 @@ makeoptions	DEBUG=-g		#Build kernel with
 options 	POWERMAC		#NewWorld Apple PowerMacs
 options		PS3			#Sony Playstation 3
 options		MAMBO			#IBM Mambo Full System Simulator
+options		PSERIES			#PAPR-compliant systems (e.g. IBM p)
 
 options 	SCHED_ULE		#ULE scheduler
 options 	INET			#InterNETworking

Modified: projects/pseries/powerpc/powerpc/cpu.c
==============================================================================
--- projects/pseries/powerpc/powerpc/cpu.c	Sun May 15 13:25:26 2011	(r221958)
+++ projects/pseries/powerpc/powerpc/cpu.c	Sun May 15 13:27:28 2011	(r221959)
@@ -127,6 +127,20 @@ static const struct cputab models[] = {
         { "IBM PowerPC 970MP",		IBM970MP,	REVFMT_MAJMIN,
 	   PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
 	   cpu_970_setup },
+        { "IBM POWER4",		IBMPOWER4,	REVFMT_MAJMIN,
+	   PPC_FEATURE_64 | PPC_FEATURE_HAS_FPU, NULL },
+        { "IBM POWER4+",	IBMPOWER4PLUS,	REVFMT_MAJMIN,
+	   PPC_FEATURE_64 | PPC_FEATURE_HAS_FPU, NULL },
+        { "IBM POWER5",		IBMPOWER5,	REVFMT_MAJMIN,
+	   PPC_FEATURE_64 | PPC_FEATURE_HAS_FPU, NULL },
+        { "IBM POWER5+",	IBMPOWER5PLUS,	REVFMT_MAJMIN,
+	   PPC_FEATURE_64 | PPC_FEATURE_HAS_FPU, NULL },
+        { "IBM POWER6",		IBMPOWER6,	REVFMT_MAJMIN,
+	   PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
+	   NULL },
+        { "IBM POWER7",		IBMPOWER7,	REVFMT_MAJMIN,
+	   PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
+	   NULL },
         { "Motorola PowerPC 7400",	MPC7400,	REVFMT_MAJMIN,
 	   PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
         { "Motorola PowerPC 7410",	MPC7410,	REVFMT_MAJMIN,

Added: projects/pseries/powerpc/pseries/mmu_phyp.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/pseries/powerpc/pseries/mmu_phyp.c	Sun May 15 13:27:28 2011	(r221959)
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2010 Andreas Tobler
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/msgbuf.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+#include <sys/vmmeter.h>
+
+#include <dev/ofw/openfirm.h>
+#include <machine/ofw_machdep.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_pageout.h>
+#include <vm/vm_pager.h>
+#include <vm/uma.h>
+
+#include <powerpc/aim/mmu_oea64.h>
+
+#include "mmu_if.h"
+#include "moea64_if.h"
+
+#include "phyp-hvcall.h"
+
+/*
+ * Kernel MMU interface
+ */
+
+static void	mphyp_bootstrap(mmu_t mmup, vm_offset_t kernelstart,
+		    vm_offset_t kernelend);
+static void	mphyp_cpu_bootstrap(mmu_t mmup, int ap);
+static void	mphyp_pte_synch(mmu_t, uintptr_t pt, struct lpte *pvo_pt);
+static void	mphyp_pte_clear(mmu_t, uintptr_t pt, struct lpte *pvo_pt,
+		    uint64_t vpn, u_int64_t ptebit);
+static void	mphyp_pte_unset(mmu_t, uintptr_t pt, struct lpte *pvo_pt,
+		    uint64_t vpn);
+static void	mphyp_pte_change(mmu_t, uintptr_t pt, struct lpte *pvo_pt,
+		    uint64_t vpn);
+static int	mphyp_pte_insert(mmu_t, u_int ptegidx, struct lpte *pvo_pt);
+static uintptr_t mphyp_pvo_to_pte(mmu_t, const struct pvo_entry *pvo);
+
+#define VSID_HASH_MASK		0x0000007fffffffffULL
+
+
+static mmu_method_t mphyp_methods[] = {
+        MMUMETHOD(mmu_bootstrap,        mphyp_bootstrap),
+        MMUMETHOD(mmu_cpu_bootstrap,    mphyp_cpu_bootstrap),
+
+	MMUMETHOD(moea64_pte_synch,     mphyp_pte_synch),
+        MMUMETHOD(moea64_pte_clear,     mphyp_pte_clear),
+        MMUMETHOD(moea64_pte_unset,     mphyp_pte_unset),
+        MMUMETHOD(moea64_pte_change,    mphyp_pte_change),
+        MMUMETHOD(moea64_pte_insert,    mphyp_pte_insert),
+        MMUMETHOD(moea64_pvo_to_pte,    mphyp_pvo_to_pte),
+
+        { 0, 0 }
+};
+
+MMU_DEF_INHERIT(pseries_mmu, "mmu_phyp", mphyp_methods, 0, oea64_mmu);
+
+static void
+mphyp_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
+{
+	uint64_t final_pteg_count = 0;
+	char buf[8];
+	uint32_t prop[2];
+        phandle_t dev, node, root;
+        int res;
+
+	printf("%s: %d\n", __FILE__, __LINE__);
+
+	moea64_early_bootstrap(mmup, kernelstart, kernelend);
+	printf("%s: %d\n", __FILE__, __LINE__);
+
+	root = OF_peer(0);
+
+        dev = OF_child(root);
+	while (dev != 0) {
+                res = OF_getprop(dev, "name", buf, sizeof(buf));
+                if (res > 0 && strcmp(buf, "cpus") == 0)
+                        break;
+                dev = OF_peer(dev);
+        }
+
+	node = OF_child(dev);
+
+	while (node != 0) {
+                res = OF_getprop(node, "device_type", buf, sizeof(buf));
+                if (res > 0 && strcmp(buf, "cpu") == 0)
+                        break;
+                node = OF_peer(node);
+        }
+	
+	res = OF_getprop(node, "ibm,pft-size", prop, sizeof(prop));
+	if (prop != NULL)
+		final_pteg_count = 1 << prop[1];
+
+	printf("final_pteg_count: %#x\n", (u_int)final_pteg_count);
+
+	moea64_pteg_count = final_pteg_count / sizeof(struct lpteg);
+
+	printf("%s: %d\n", __FILE__, __LINE__);
+	moea64_mid_bootstrap(mmup, kernelstart, kernelend);
+	printf("%s: %d\n", __FILE__, __LINE__);
+	moea64_late_bootstrap(mmup, kernelstart, kernelend);
+	printf("%s: %d\n", __FILE__, __LINE__);
+}
+
+static void
+mphyp_cpu_bootstrap(mmu_t mmup, int ap)
+{
+	struct slb *slb = PCPU_GET(slb);
+	register_t seg0;
+	int i;
+
+	/*
+	 * Install kernel SLB entries
+	 */
+
+	printf("%s: %d\n", __FILE__, __LINE__);
+        __asm __volatile ("slbia");
+        __asm __volatile ("slbmfee %0,%1; slbie %0;" : "=r"(seg0) : "r"(0));
+	printf("%s: %d\n", __FILE__, __LINE__);
+	for (i = 0; i < 64; i++) {
+		if (!(slb[i].slbe & SLBE_VALID))
+			continue;
+
+		__asm __volatile ("slbmte %0, %1" ::
+		    "r"(slb[i].slbv), "r"(slb[i].slbe));
+	}
+	printf("%s: %d\n", __FILE__, __LINE__);
+}
+
+static void
+mphyp_pte_synch(mmu_t mmu, uintptr_t slot, struct lpte *pvo_pt)
+{
+	struct lpte pte;
+	uint64_t junk;
+
+	phyp_pft_hcall(H_READ, 0, slot, 0, 0, &pte.pte_hi, &pte.pte_lo,
+	    &junk);
+
+	pvo_pt->pte_lo |= pte.pte_lo & (LPTE_CHG | LPTE_REF);
+}
+
+static void
+mphyp_pte_clear(mmu_t mmu, uintptr_t slot, struct lpte *pvo_pt, uint64_t vpn,
+    u_int64_t ptebit)
+{
+
+	if (ptebit & LPTE_CHG)
+		phyp_hcall(H_CLEAR_MOD, 0, slot);
+	if (ptebit & LPTE_REF)
+		phyp_hcall(H_CLEAR_REF, 0, slot);
+}
+
+static void
+mphyp_pte_unset(mmu_t mmu, uintptr_t slot, struct lpte *pvo_pt, uint64_t vpn)
+{
+
+	/* XXX: last argument can check the VPN -- set flag to enable */
+	phyp_hcall(H_REMOVE, 0, slot, vpn);
+}
+
+static void
+mphyp_pte_change(mmu_t mmu, uintptr_t slot, struct lpte *pvo_pt, uint64_t vpn)
+{
+	struct lpte evicted;
+	uint64_t index, junk;
+	int64_t result;
+
+	/*
+	 * NB: this is protected by the global table lock, so this two-step
+	 * is safe, except for the scratch-page case. No CPUs on which we run
+	 * this code should be using scratch pages.
+	 */
+
+	/* XXX: optimization using H_PROTECT for common case? */
+	result = phyp_hcall(H_REMOVE, 0, slot, vpn);
+	if (result != H_SUCCESS)
+		panic("mphyp_pte_change() invalidation failure: %ld\n", result);
+	phyp_pft_hcall(H_ENTER, H_EXACT, slot, pvo_pt->pte_hi,
+	    pvo_pt->pte_lo, &index, &evicted.pte_lo, &junk);
+	if (result != H_SUCCESS)
+		panic("mphyp_pte_change() insertion failure: %ld\n", result);
+}
+
+static int
+mphyp_pte_insert(mmu_t mmu, u_int ptegidx, struct lpte *pvo_pt)
+{
+	int64_t result;
+	struct lpte evicted;
+	uint64_t index, junk;
+	u_int pteg_bktidx;
+
+	pvo_pt->pte_hi |= LPTE_VALID;
+	pvo_pt->pte_hi &= ~LPTE_HID;
+	evicted.pte_hi = 0;
+
+	/*
+	 * First try primary hash.
+	 */
+	pteg_bktidx = ptegidx;
+	result = phyp_pft_hcall(H_ENTER, 0, pteg_bktidx << 3, pvo_pt->pte_hi,
+	    pvo_pt->pte_lo, &index, &evicted.pte_lo, &junk);
+	if (result == H_SUCCESS)
+		return (index & 0x07);
+
+	/*
+	 * First try primary hash.
+	 */
+	pteg_bktidx ^= moea64_pteg_mask;
+	pvo_pt->pte_hi |= LPTE_HID;
+	result = phyp_pft_hcall(H_ENTER, 0, pteg_bktidx << 3,
+	    pvo_pt->pte_hi, pvo_pt->pte_lo, &index, &evicted.pte_lo, &junk);
+	if (result == H_SUCCESS)
+		return (index & 0x07);
+
+	panic("OVERFLOW (%ld)", result);
+	return (-1);
+}
+
+static __inline u_int
+va_to_pteg(uint64_t vsid, vm_offset_t addr, int large)
+{
+	uint64_t hash;
+	int shift;
+
+	shift = large ? moea64_large_page_shift : ADDR_PIDX_SHFT;
+	hash = (vsid & VSID_HASH_MASK) ^ (((uint64_t)addr & ADDR_PIDX) >>
+	    shift);
+	return (hash & moea64_pteg_mask);
+}
+
+static uintptr_t
+mphyp_pvo_to_pte(mmu_t mmu, const struct pvo_entry *pvo)
+{
+	uint64_t vsid;
+	u_int ptegidx;
+
+	/* If the PTEG index is not set, then there is no page table entry */
+	if (!PVO_PTEGIDX_ISSET(pvo))
+		return (-1);
+
+	vsid = PVO_VSID(pvo);
+	ptegidx = va_to_pteg(vsid, PVO_VADDR(pvo), pvo->pvo_vaddr & PVO_LARGE);
+
+	/*
+	 * We can find the actual pte entry without searching by grabbing
+	 * the PTEG index from 3 unused bits in pvo_vaddr and by
+	 * noticing the HID bit.
+	 */
+	if (pvo->pvo_pte.lpte.pte_hi & LPTE_HID)
+		ptegidx ^= moea64_pteg_mask;
+
+	return ((ptegidx << 3) | PVO_PTEGIDX_GET(pvo));
+}
+

Added: projects/pseries/powerpc/pseries/phyp-hvcall.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/pseries/powerpc/pseries/phyp-hvcall.S	Sun May 15 13:27:28 2011	(r221959)
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (C) 2010 Andreas Tobler
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <machine/asm.h>
+
+/* Hypervisor entry call. */
+#define  hc  .long 0x44000022
+
+/*
+ * Simple HV calls take the same arguments, with the same ABI, as this
+ * C function
+ */
+ASENTRY(phyp_hcall)
+	mflr	%r0
+	std	%r0,16(%r1)
+	hc				/* invoke the hypervisor */
+	ld	%r0,16(%r1)
+	mtlr	%r0
+	blr				/* return r3 = status */
+
+/*
+ * PFT HV calls take a special ABI (see PAPR 14.5.4.1)
+ *
+ * r3-r7 arguments passed unchanged, r8-r10 are addresses of return values
+ * HV takes the same r3-r7, but returns values in r3, r4-r6
+ */
+ASENTRY(phyp_pft_hcall)
+	mflr	%r0
+	std	%r0,16(%r1)
+	stdu	%r1,-80(%r1)
+	std	%r8,48(%r1)		/* save arguments */
+	std	%r9,56(%r1)
+	std	%r10,64(%r1)
+	hc				/* invoke the hypervisor */
+	ld	%r11,48(%r1)		/* store results */
+	std	%r4,0(%r11)
+	ld	%r11,56(%r1)
+	std	%r5,0(%r11)
+	ld	%r11,64(%r1)
+	std	%r6,0(%r11)
+	ld	%r1,0(%r1)		/* exit */
+	ld	%r0,16(%r1)
+	mtlr	%r0
+	blr				/* return r3 = status */
+

Added: projects/pseries/powerpc/pseries/phyp-hvcall.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/pseries/powerpc/pseries/phyp-hvcall.h	Sun May 15 13:27:28 2011	(r221959)
@@ -0,0 +1,304 @@
+/*-
+ * Copyright (C) 2010 Andreas Tobler
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef	_PSERIES_PHYP_HVCALL_H_
+#define	_PSERIES_PHYP_HVCALL_H_
+
+/* Information taken from: Power.org PAPR, Version 2.4 (December 7, 2009). */
+
+#include <sys/types.h>
+
+/* Return codes. */
+
+#define H_SUCCESS       0
+#define H_BUSY          1  /* Hardware Busy -- Retry Later. */
+#define H_CLOSED        2  /* Virtual I/O connection is closed. */
+#define H_NOT_AVAILABLE 3
+#define H_CONSTRAINED   4  /* The request called for resources in excess of
+			      the maximum allowed. The resultant allocation
+			      was constrained to maximum allowed. */
+#define H_PARTIAL       5  /* The request completed only partially successful.
+			      Parameters were valid but some specific hcall
+			      function condition prevented fully completing the
+			      architected function, see the specific hcall
+			      definition for possible reasons. */
+#define H_IN_PROGRESS     14
+#define H_PAGE_REGISTERED 15
+#define H_PARTIAL_STORE   16
+#define H_PENDING         17
+#define H_CONTINUE        18
+
+#define H_LONG_BUSY_ORDER_1_MS   9900  /* This return code is identical to
+					  H_BUSY, but with the added bonus of a
+					  hint to the partition OS. If the
+					  partition OS can delay for 1
+					  millisecond, the hcall will likely
+					  succeed on a new hcall with no further
+					  busy return codes. If the partition OS
+					  cannot handle a delay, they are
+					  certainly free to immediately turn
+					  around and try again. */
+#define H_LONG_BUSY_ORDER_10_MS  9901  /* Similar to H_LONG_BUSY_ORDER_1_MS, but
+					  the hint is 10mSec wait this time. */
+
+#define H_LONG_BUSY_ORDER_100_MS 9902  /* Similar to H_LONG_BUSY_ORDER_1_MS, but
+					  the hint is 100mSec wait this time. */ 
+
+#define H_LONG_BUSY_ORDER_1_S    9903  /* Similar to H_LONG_BUSY_ORDER_1_MS, but
+					  the hint is 1Sec wait this time. */
+#define H_LONG_BUSY_ORDER_10_S   9904  /* Similar to H_LONG_BUSY_ORDER_1_MS, but
+					  the hint is 10Sec wait this time. */
+#define H_LONG_BUSY_ORDER_100_S  9905  /* Similar to H_LONG_BUSY_ORDER_1_MS, but
+					  the hint is 100Sec wait this time. */
+
+#define H_HARDWARE   -1  /* Error. */
+#define H_FUNCTION   -2  /* Not supported. */
+#define H_PRIVILEGE  -3  /* Caller not in privileged mode. */
+#define H_PARAMETER  -4  /* Outside valid range for partition or conflicting. */
+#define H_BAD_MODE   -5  /* Illegal MSR value. */
+#define H_PTEG_FULL  -6  /* The requested pteg was full. */
+#define H_NOT_FOUND  -7  /* The requested entitiy was not found. */
+#define H_RESERVED_DABR -8  /* The requested address is reserved by the
+			       hypervisor on this processor. */
+#define H_NOMEM      -9
+#define H_AUTHORITY -10  /* The caller did not have authority to perform the
+			    function. */
+#define H_PERMISSION -11  /* The mapping specified by the request does not
+			     allow for the requested transfer. */
+#define H_DROPPED   -12  /* One or more packets could not be delivered to
+			    their requested destinations. */
+#define H_S_PARM   -13  /* The source parameter is illegal. */
+#define H_D_PARM   -14  /* The destination parameter is illegal. */
+#define H_R_PARM   -15  /* The remote TCE mapping is illegal. */
+#define H_RESOURCE  -16  /* One or more required resources are in use. */
+#define H_ADAPTER_PARM -17  /* Invalid adapter. */
+#define H_RH_PARM  -18  /* Resource not valid or logical partition
+			   conflicting. */
+#define H_RCQ_PARM -19  /* RCQ not valid or logical partition conflicting. */
+#define H_SCQ_PARM -20  /* SCQ not valid or logical partition conflicting. */
+#define H_EQ_PARM -21  /* EQ not valid or logical partition conflicting. */
+#define H_RT_PARM -22  /* Invalid resource type. */
+#define H_ST_PARM -23  /* Invalid service type. */
+#define H_SIGT_PARM -24 /* Invalid signalling type. */
+#define H_TOKEN_PARM -25  /* Invalid token. */
+#define H_MLENGTH_PARM -27  /* Invalid memory length. */
+#define H_MEM_PARM -28  /* Invalid memory I/O virtual address. */
+#define H_MEM_ACCESS_PARM -29  /* Invalid memory access control. */
+#define H_ATTR_PARM -30  /* Invalid attribute value. */
+#define H_PORT_PARM -31  /* Invalid port number. */
+#define H_MCG_PARM -32  /* Invalid multicast group. */
+#define H_VL_PARM -33  /* Invalid virtual lane. */
+#define H_TSIZE_PARM -34  /* Invalid trace size. */
+#define H_TRACE_PARM -35  /* Invalid trace buffer. */
+#define H_MASK_PARM -37  /* Invalid mask value. */
+#define H_MCG_FULL -38  /* Multicast attachments exceeded. */
+#define H_ALIAS_EXIST -39  /* Alias QP already defined. */
+#define H_P_COUNTER -40  /* Invalid counter specification. */
+#define H_TABLE_FULL -41  /* Resource page table full. */
+#define H_ALT_TABLE -42  /* Alternate table already exists / alternate page
+			    table not available. */
+#define H_MR_CONDITION -43  /* Invalid memory region condition. */
+#define H_NOT_ENOUGH_RESOURCES -44  /* Insufficient resources. */
+#define H_R_STATE -45  /* Invalid resource state condition or sequencing
+			  error. */
+#define H_RESCINDED -46
+#define H_ABORTED -54
+#define H_P2 -55
+#define H_P3 -56
+#define H_P4 -57
+#define H_P5 -58
+#define H_P6 -59
+#define H_P7 -60
+#define H_P8 -61
+#define H_P9 -62
+#define H_NOOP -63
+#define H_TOO_BIG -64
+
+#define H_UNSUPPORTED -67  /* Parameter value outside of the range supported
+			      by this implementation. */
+
+/* Flags. */
+/* Table 168. Page Frame Table Access flags field definition. */
+#define H_EXACT                 (1UL<<(63-24))
+#define H_R_XLATE               (1UL<<(63-25))
+#define H_READ_4                (1UL<<(63-26))
+
+/* Table 178. CMO Page Usage State flags Definition. */
+#define H_PAGE_STATE_CHANGE     (1UL<<(63-28))
+#define H_PAGE_UNUSED           ((1UL<<(63-29)) | (1UL<<(63-30)))
+#define H_PAGE_SET_UNUSED       (H_PAGE_STATE_CHANGE | H_PAGE_UNUSED)
+#define H_PAGE_SET_LOANED       (H_PAGE_SET_UNUSED | (1UL<<(63-31)))
+#define H_PAGE_SET_ACTIVE       H_PAGE_STATE_CHANGE
+
+/* Table 168. Page Frame Table Access flags field definition. */
+#define H_AVPN                  (1UL<<(63-32))
+#define H_ANDCOND               (1UL<<(63-33))
+
+#define H_ICACHE_INVALIDATE     (1UL<<(63-40))
+#define H_ICACHE_SYNCHRONIZE    (1UL<<(63-41))
+
+#define H_ZERO_PAGE             (1UL<<(63-48))
+#define H_COPY_PAGE             (1UL<<(63-49))
+
+#define H_N (1UL<<(63-61))
+#define H_PP1 (1UL<<(63-62))
+#define H_PP2 (1UL<<(63-63))
+
+/* pSeries hypervisor opcodes. */
+#define H_REMOVE		0x04
+#define H_ENTER			0x08
+#define H_READ			0x0c
+#define H_CLEAR_MOD		0x10
+#define H_CLEAR_REF		0x14
+#define H_PROTECT		0x18
+#define H_GET_TCE		0x1c
+#define H_PUT_TCE		0x20
+#define H_SET_SPRG0		0x24
+#define H_SET_DABR		0x28
+#define H_PAGE_INIT		0x2c
+#define H_SET_ASR		0x30
+#define H_ASR_ON		0x34
+#define H_ASR_OFF		0x38
+#define H_LOGICAL_CI_LOAD	0x3c
+#define H_LOGICAL_CI_STORE	0x40
+#define H_LOGICAL_CACHE_LOAD	0x44
+#define H_LOGICAL_CACHE_STORE	0x48
+#define H_LOGICAL_ICBI		0x4c
+#define H_LOGICAL_DCBF		0x50
+#define H_GET_TERM_CHAR		0x54
+#define H_PUT_TERM_CHAR		0x58
+#define H_REAL_TO_LOGICAL	0x5c
+#define H_HYPERVISOR_DATA	0x60
+#define H_EOI			0x64
+#define H_CPPR			0x68
+#define H_IPI			0x6c
+#define H_IPOLL			0x70
+#define H_XIRR			0x74
+#define H_MIGRATE_DMA		0x78
+#define H_PERFMON		0x7c
+#define H_REGISTER_VPA		0xdc
+#define H_CEDE			0xe0
+#define H_CONFER		0xe4
+#define H_PROD			0xe8
+#define H_GET_PPP		0xec
+#define H_SET_PPP		0xf0
+#define H_PURR			0xf4
+#define H_PIC			0xf8
+#define H_REG_CRQ		0xfc
+#define H_FREE_CRQ		0x100
+#define H_VIO_SIGNAL		0x104
+#define H_SEND_CRQ		0x108
+#define H_PUT_RTCE              0x10c
+#define H_COPY_RDMA		0x110
+#define H_REGISTER_LOGICAL_LAN	0x114
+#define H_FREE_LOGICAL_LAN	0x118
+#define H_ADD_LOGICAL_LAN_BUFFER 0x11c
+#define H_SEND_LOGICAL_LAN	0x120
+#define H_BULK_REMOVE		0x124
+#define H_WRITE_RDMA            0x128
+#define H_READ_RDMA             0x12c
+#define H_MULTICAST_CTRL	0x130
+#define H_SET_XDABR		0x134
+#define H_STUFF_TCE		0x138
+#define H_PUT_TCE_INDIRECT	0x13c
+#define H_PUT_RTCE_INDIRECT	0x140
+#define H_CHANGE_LOGICAL_LAN_MAC 0x14c
+#define H_VTERM_PARTNER_INFO	0x150
+#define H_REGISTER_VTERM	0x154
+#define H_FREE_VTERM		0x158
+/* Reserved ....
+#define H_RESET_EVENTS          0x15c
+#define H_ALLOC_RESOURCE        0x160
+#define H_FREE_RESOURCE         0x164
+#define H_MODIFY_QP             0x168
+#define H_QUERY_QP              0x16c
+#define H_REREGISTER_PMR        0x170
+#define H_REGISTER_SMR          0x174
+#define H_QUERY_MR              0x178
+#define H_QUERY_MW              0x17c
+#define H_QUERY_HCA             0x180
+#define H_QUERY_PORT            0x184
+#define H_MODIFY_PORT           0x188
+#define H_DEFINE_AQP1           0x18c
+#define H_GET_TRACE_BUFFER      0x190
+#define H_DEFINE_AQP0           0x194
+#define H_RESIZE_MR             0x198
+#define H_ATTACH_MCQP           0x19c
+#define H_DETACH_MCQP           0x1a0
+#define H_CREATE_RPT            0x1a4
+#define H_REMOVE_RPT            0x1a8
+#define H_REGISTER_RPAGES       0x1ac
+#define H_DISABLE_AND_GETC      0x1b0
+#define H_ERROR_DATA            0x1b4
+#define H_GET_HCA_INFO          0x1b8
+#define H_GET_PERF_COUNT        0x1bc
+#define H_MANAGE_TRACE          0x1c0
+.... */
+#define H_FREE_LOGICAL_LAN_BUFFER 0x1d4
+#define H_POLL_PENDING		0x1d8
+/* Reserved ....
+#define H_QUERY_INT_STATE       0x1e4
+.... */
+#define H_LIOBN_ATTRIBUTES	0x240
+#define H_ILLAN_ATTRIBUTES	0x244
+#define H_REMOVE_RTCE	        0x24c
+/* Reserved ...
+#define H_MODIFY_HEA_QP		0x250
+#define H_QUERY_HEA_QP		0x254
+#define H_QUERY_HEA		0x258
+#define H_QUERY_HEA_PORT	0x25c
+#define H_MODIFY_HEA_PORT	0x260
+#define H_REG_BCMC		0x264
+#define H_DEREG_BCMC		0x268
+#define H_REGISTER_HEA_RPAGES	0x26c
+#define H_DISABLE_AND_GET_HEA	0x270
+#define H_GET_HEA_INFO		0x274
+#define H_ALLOC_HEA_RESOURCE	0x278
+#define H_ADD_CONN		0x284
+#define H_DEL_CONN		0x288
+... */
+#define H_JOIN			0x298
+#define H_DONOR_OPERATION	0x29c
+#define H_VASI_SIGNAL	       	0x2a0
+#define H_VASI_STATE            0x2a4
+#define H_VIOCTL	       	0x2a8
+#define H_VRMASD	       	0x2ac
+#define H_ENABLE_CRQ		0x2b0
+/* Reserved ...
+#define H_GET_EM_PARMS		0x2b8
+... */
+#define H_VPM_STAT	       	0x2bc
+#define H_SET_MPP		0x2d0
+#define H_GET_MPP		0x2d4
+#define MAX_HCALL_OPCODE	H_GET_MPP
+
+int64_t phyp_hcall(uint64_t opcode, ...);
+int64_t phyp_pft_hcall(uint64_t opcode, uint64_t flags, uint64_t pteidx,
+    uint64_t pte_hi, uint64_t pte_lo, uint64_t *pteidx_out, uint64_t *ptelo_out,
+    uint64_t *r6);
+
+#endif /* _PSERIES_PHYP_HVCALL_H_ */

Added: projects/pseries/powerpc/pseries/platform_chrp.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/pseries/powerpc/pseries/platform_chrp.c	Sun May 15 13:27:28 2011	(r221959)
@@ -0,0 +1,250 @@
+/*-
+ * Copyright (c) 2008 Marcel Moolenaar
+ * Copyright (c) 2009 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/smp.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/hid.h>
+#include <machine/platformvar.h>
+#include <machine/pmap.h>
+#include <machine/smp.h>
+#include <machine/spr.h>
+
+#include <dev/ofw/openfirm.h>
+#include <machine/ofw_machdep.h>
+
+#include "platform_if.h"
+
+#ifdef SMP
+extern void *ap_pcpu;
+#endif
+
+static int chrp_probe(platform_t);
+static int chrp_attach(platform_t);
+void chrp_mem_regions(platform_t, struct mem_region **phys, int *physsz,
+    struct mem_region **avail, int *availsz);
+static u_long chrp_timebase_freq(platform_t, struct cpuref *cpuref);
+static int chrp_smp_first_cpu(platform_t, struct cpuref *cpuref);
+static int chrp_smp_next_cpu(platform_t, struct cpuref *cpuref);
+static int chrp_smp_get_bsp(platform_t, struct cpuref *cpuref);
+static int chrp_smp_start_cpu(platform_t, struct pcpu *cpu);
+static void chrp_reset(platform_t);
+
+static platform_method_t chrp_methods[] = {
+	PLATFORMMETHOD(platform_probe, 		chrp_probe),
+	PLATFORMMETHOD(platform_attach,		chrp_attach),
+	PLATFORMMETHOD(platform_mem_regions,	chrp_mem_regions),
+	PLATFORMMETHOD(platform_timebase_freq,	chrp_timebase_freq),
+	
+	PLATFORMMETHOD(platform_smp_first_cpu,	chrp_smp_first_cpu),
+	PLATFORMMETHOD(platform_smp_next_cpu,	chrp_smp_next_cpu),
+	PLATFORMMETHOD(platform_smp_get_bsp,	chrp_smp_get_bsp),
+	PLATFORMMETHOD(platform_smp_start_cpu,	chrp_smp_start_cpu),
+
+	PLATFORMMETHOD(platform_reset,		chrp_reset),
+
+	{ 0, 0 }
+};
+
+static platform_def_t chrp_platform = {
+	"chrp",
+	chrp_methods,
+	0
+};
+
+PLATFORM_DEF(chrp_platform);
+
+static int
+chrp_probe(platform_t plat)
+{
+	if (OF_finddevice("/memory") != -1 || OF_finddevice("/memory@0") != -1)
+		return (BUS_PROBE_GENERIC);
+
+	return (ENXIO);
+}
+
+static int
+chrp_attach(platform_t plat)
+{
+printf("Attaching CHRP\n");
+#ifdef __powerpc64__
+	/* XXX: check for /rtas/ibm,hypertas-functions? */
+	if (!(mfmsr() & PSL_HV))
+		pmap_mmu_install("mmu_phyp", BUS_PROBE_SPECIFIC);
+#endif
+
+	return (0);
+}
+
+void
+chrp_mem_regions(platform_t plat, struct mem_region **phys, int *physsz,
+    struct mem_region **avail, int *availsz)
+{
+	ofw_mem_regions(phys,physsz,avail,availsz);
+}
+
+static u_long
+chrp_timebase_freq(platform_t plat, struct cpuref *cpuref)
+{
+	phandle_t phandle;
+	int32_t ticks = -1;
+
+	phandle = cpuref->cr_hwref;
+
+	OF_getprop(phandle, "timebase-frequency", &ticks, sizeof(ticks));
+
+	if (ticks <= 0)
+		panic("Unable to determine timebase frequency!");
+
+	return (ticks);
+}
+
+
+static int
+chrp_smp_fill_cpuref(struct cpuref *cpuref, phandle_t cpu)
+{
+	cell_t cpuid, res;
+
+	cpuref->cr_hwref = cpu;
+	res = OF_getprop(cpu, "reg", &cpuid, sizeof(cpuid));
+
+	/*
+	 * psim doesn't have a reg property, so assume 0 as for the
+	 * uniprocessor case in the CHRP spec. 
+	 */
+	if (res < 0) {
+		cpuid = 0;
+	}
+
+	cpuref->cr_cpuid = cpuid & 0xff;
+	return (0);
+}
+
+static int
+chrp_smp_first_cpu(platform_t plat, struct cpuref *cpuref)
+{
+	char buf[8];
+	phandle_t cpu, dev, root;
+	int res;
+
+	root = OF_peer(0);
+
+	dev = OF_child(root);
+	while (dev != 0) {
+		res = OF_getprop(dev, "name", buf, sizeof(buf));
+		if (res > 0 && strcmp(buf, "cpus") == 0)
+			break;
+		dev = OF_peer(dev);
+	}
+	if (dev == 0) {
+		/*
+		 * psim doesn't have a name property on the /cpus node,
+		 * but it can be found directly
+		 */
+		dev = OF_finddevice("/cpus");
+		if (dev == 0)
+			return (ENOENT);
+	}
+
+	cpu = OF_child(dev);
+
+	while (cpu != 0) {
+		res = OF_getprop(cpu, "device_type", buf, sizeof(buf));
+		if (res > 0 && strcmp(buf, "cpu") == 0)
+			break;
+		cpu = OF_peer(cpu);
+	}
+	if (cpu == 0)
+		return (ENOENT);
+
+	return (chrp_smp_fill_cpuref(cpuref, cpu));
+}
+
+static int
+chrp_smp_next_cpu(platform_t plat, struct cpuref *cpuref)
+{
+	char buf[8];
+	phandle_t cpu;
+	int res;
+
+	cpu = OF_peer(cpuref->cr_hwref);
+	while (cpu != 0) {
+		res = OF_getprop(cpu, "device_type", buf, sizeof(buf));
+		if (res > 0 && strcmp(buf, "cpu") == 0)
+			break;
+		cpu = OF_peer(cpu);
+	}
+	if (cpu == 0)
+		return (ENOENT);
+
+	return (chrp_smp_fill_cpuref(cpuref, cpu));
+}
+
+static int
+chrp_smp_get_bsp(platform_t plat, struct cpuref *cpuref)
+{
+	ihandle_t inst;
+	phandle_t bsp, chosen;
+	int res;
+
+	chosen = OF_finddevice("/chosen");
+	if (chosen == 0)
+		return (ENXIO);
+
+	res = OF_getprop(chosen, "cpu", &inst, sizeof(inst));
+	if (res < 0)
+		return (ENXIO);
+
+	bsp = OF_instance_to_package(inst);
+	return (chrp_smp_fill_cpuref(cpuref, bsp));
+}
+
+static int
+chrp_smp_start_cpu(platform_t plat, struct pcpu *pc)
+{
+	/* XXX: Uses RTAS call, will add later */
+	return (ENXIO);
+}
+
+static void
+chrp_reset(platform_t platform)
+{
+	OF_reboot();
+}
+



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105151327.p4FDRSIu040692>