Author: nwhitehorn Date: Tue Sep 17 17:37:04 2013 New Revision: 255643 URL: http://svnweb.freebsd.org/changeset/base/255643
Log: Merge in support for PAPR-compliant (Power Architecture Platform Requirements) systems from the projects/pseries branch. This in principle includes all IBM POWER hardware released in the last 15 years with the exception of POWER3-based systems when run in 64-bit mode. The main development target, however, has been the PAPR logical partition support that is the default target in KVM on POWER and QEMU -- mileage may vary on actual hardware at present. Much of the heavy lifting here was done by Andreas Tobler. Approved by: re (kib) Added: head/sys/powerpc/pseries/ head/sys/powerpc/pseries/mmu_phyp.c (contents, props changed) head/sys/powerpc/pseries/phyp-hvcall.S (contents, props changed) head/sys/powerpc/pseries/phyp-hvcall.h (contents, props changed) head/sys/powerpc/pseries/phyp_console.c (contents, props changed) head/sys/powerpc/pseries/platform_chrp.c (contents, props changed) head/sys/powerpc/pseries/plpar_iommu.c (contents, props changed) head/sys/powerpc/pseries/plpar_iommu.h (contents, props changed) head/sys/powerpc/pseries/rtas_dev.c (contents, props changed) head/sys/powerpc/pseries/rtas_pci.c (contents, props changed) head/sys/powerpc/pseries/vdevice.c (contents, props changed) head/sys/powerpc/pseries/xics.c (contents, props changed) Modified: head/sys/conf/files.powerpc head/sys/conf/options.powerpc head/sys/powerpc/conf/DEFAULTS head/sys/powerpc/conf/GENERIC head/sys/powerpc/conf/GENERIC64 Modified: head/sys/conf/files.powerpc ============================================================================== --- head/sys/conf/files.powerpc Tue Sep 17 17:31:53 2013 (r255642) +++ head/sys/conf/files.powerpc Tue Sep 17 17:37:04 2013 (r255643) @@ -225,6 +225,15 @@ powerpc/ps3/ps3disk.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/phyp_console.c optional pseries powerpc64 +powerpc/pseries/platform_chrp.c optional pseries +powerpc/pseries/plpar_iommu.c optional pseries powerpc64 +powerpc/pseries/rtas_dev.c optional pseries +powerpc/pseries/rtas_pci.c optional pseries pci +powerpc/pseries/vdevice.c optional pseries powerpc64 +powerpc/pseries/xics.c optional pseries powerpc64 powerpc/psim/iobus.c optional psim powerpc/psim/ata_iobus.c optional ata psim powerpc/psim/openpic_iobus.c optional psim Modified: head/sys/conf/options.powerpc ============================================================================== --- head/sys/conf/options.powerpc Tue Sep 17 17:31:53 2013 (r255642) +++ head/sys/conf/options.powerpc Tue Sep 17 17:37:04 2013 (r255643) @@ -22,6 +22,7 @@ MPC85XX opt_platform.h POWERMAC opt_platform.h PS3 opt_platform.h MAMBO +PSERIES PSIM WII opt_platform.h Modified: head/sys/powerpc/conf/DEFAULTS ============================================================================== --- head/sys/powerpc/conf/DEFAULTS Tue Sep 17 17:31:53 2013 (r255642) +++ head/sys/powerpc/conf/DEFAULTS Tue Sep 17 17:37:04 2013 (r255643) @@ -9,6 +9,7 @@ device mem # Memory and kernel memory # UART chips on this platform device uart_ns8250 +options GEOM_PART_BSD options GEOM_PART_MBR options NEW_PCIB Modified: head/sys/powerpc/conf/GENERIC ============================================================================== --- head/sys/powerpc/conf/GENERIC Tue Sep 17 17:31:53 2013 (r255642) +++ head/sys/powerpc/conf/GENERIC Tue Sep 17 17:37:04 2013 (r255643) @@ -30,6 +30,7 @@ makeoptions WITH_CTF=1 options POWERMAC #NewWorld Apple PowerMacs options PSIM #GDB PSIM ppc simulator options MAMBO #IBM Mambo Full System Simulator +options PSERIES #PAPR-compliant systems options SCHED_ULE #ULE scheduler options PREEMPTION #Enable kernel thread preemption Modified: head/sys/powerpc/conf/GENERIC64 ============================================================================== --- head/sys/powerpc/conf/GENERIC64 Tue Sep 17 17:31:53 2013 (r255642) +++ head/sys/powerpc/conf/GENERIC64 Tue Sep 17 17:37:04 2013 (r255643) @@ -30,6 +30,7 @@ makeoptions WITH_CTF=1 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 PREEMPTION #Enable kernel thread preemption @@ -131,6 +132,9 @@ device uart device uart_z8530 # Ethernet hardware +device em # Intel PRO/1000 Gigabit Ethernet Family +device igb # Intel PRO/1000 PCIE Server Gigabit Family +device ixgbe # Intel PRO/10GbE PCIE Ethernet Family device glc # Sony Playstation 3 Ethernet # PCI Ethernet NICs that use the common MII bus controller code. @@ -139,6 +143,8 @@ device bge # Broadcom BCM570xx Gigabit device gem # Sun GEM/Sun ERI/Apple GMAC device dc # DEC/Intel 21143 and various workalikes device fxp # Intel EtherExpress PRO/100B (82557, 82558) +device re # RealTek 8139C+/8169/8169S/8110S +device rl # RealTek 8129/8139 # Pseudo devices. device loop # Network loopback Added: head/sys/powerpc/pseries/mmu_phyp.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/powerpc/pseries/mmu_phyp.c Tue Sep 17 17:37:04 2013 (r255643) @@ -0,0 +1,420 @@ +/* + * 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/cdefs.h> +__FBSDID("$FreeBSD$"); + +#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/uma.h> + +#include <powerpc/aim/mmu_oea64.h> + +#include "mmu_if.h" +#include "moea64_if.h" + +#include "phyp-hvcall.h" + +extern int n_slbs; + +/* + * 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]; + uint32_t nptlp, shift = 0, slb_encoding = 0; + phandle_t dev, node, root; + int idx, len, res; + + moea64_early_bootstrap(mmup, kernelstart, kernelend); + + 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 (res <= 0) + panic("mmu_phyp: unknown PFT size"); + final_pteg_count = 1 << prop[1]; + res = OF_getprop(node, "ibm,slb-size", prop, sizeof(prop[0])); + if (res > 0) + n_slbs = prop[0]; + + moea64_pteg_count = final_pteg_count / sizeof(struct lpteg); + + /* + * Scan the large page size property for PAPR compatible machines. + * See PAPR D.5 Changes to Section 5.1.4, 'CPU Node Properties' + * for the encoding of the property. + */ + + len = OF_getproplen(node, "ibm,segment-page-sizes"); + if (len > 0) { + /* + * We have to use a variable length array on the stack + * since we have very limited stack space. + */ + cell_t arr[len/sizeof(cell_t)]; + res = OF_getprop(node, "ibm,segment-page-sizes", &arr, + sizeof(arr)); + len /= 4; + idx = 0; + while (len > 0) { + shift = arr[idx]; + slb_encoding = arr[idx + 1]; + nptlp = arr[idx + 2]; + idx += 3; + len -= 3; + while (len > 0 && nptlp) { + idx += 2; + len -= 2; + nptlp--; + } + } + moea64_large_page_shift = shift; + moea64_large_page_size = 1 << shift; + } + + moea64_mid_bootstrap(mmup, kernelstart, kernelend); + moea64_late_bootstrap(mmup, kernelstart, kernelend); +} + +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 + */ + + __asm __volatile ("slbia"); + __asm __volatile ("slbmfee %0,%1; slbie %0;" : "=r"(seg0) : "r"(0)); + 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)); + } +} + +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. + */ + KASSERT(!(pvo_pt->pte_hi & LPTE_LOCKED), + ("Locked pages not supported on PHYP")); + + /* 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); + 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 __inline int +mphyp_pte_spillable_ident(u_int ptegidx, struct lpte *to_evict) +{ + uint64_t slot, junk, k; + struct lpte pt; + int i, j; + + /* Start at a random slot */ + i = mftb() % 8; + k = -1; + for (j = 0; j < 8; j++) { + slot = (ptegidx << 3) + (i + j) % 8; + phyp_pft_hcall(H_READ, 0, slot, 0, 0, &pt.pte_hi, &pt.pte_lo, + &junk); + + if (pt.pte_hi & LPTE_SWBITS) + continue; + + /* This is a candidate, so remember it */ + k = slot; + + /* Try to get a page that has not been used lately */ + if (!(pt.pte_lo & LPTE_REF)) { + memcpy(to_evict, &pt, sizeof(struct lpte)); + return (k); + } + } + + phyp_pft_hcall(H_READ, 0, slot, 0, 0, &to_evict->pte_hi, + &to_evict->pte_lo, &junk); + return (k); +} + +static int +mphyp_pte_insert(mmu_t mmu, u_int ptegidx, struct lpte *pvo_pt) +{ + int64_t result; + struct lpte evicted; + struct pvo_entry *pvo; + uint64_t index, junk; + u_int pteg_bktidx; + + /* Check for locked pages, which we can't support on this system */ + KASSERT(!(pvo_pt->pte_hi & LPTE_LOCKED), + ("Locked pages not supported on PHYP")); + + /* Initialize PTE */ + 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); + KASSERT(result == H_PTEG_FULL, ("Page insertion error: %ld " + "(ptegidx: %#x/%#x, PTE %#lx/%#lx", result, ptegidx, + moea64_pteg_count, pvo_pt->pte_hi, pvo_pt->pte_lo)); + + /* + * Next try secondary 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); + KASSERT(result == H_PTEG_FULL, ("Secondary page insertion error: %ld", + result)); + + /* + * Out of luck. Find a PTE to sacrifice. + */ + pteg_bktidx = ptegidx; + index = mphyp_pte_spillable_ident(pteg_bktidx, &evicted); + if (index == -1L) { + pteg_bktidx ^= moea64_pteg_mask; + index = mphyp_pte_spillable_ident(pteg_bktidx, &evicted); + } + + if (index == -1L) { + /* No freeable slots in either PTEG? We're hosed. */ + panic("mphyp_pte_insert: overflow"); + return (-1); + } + + if (pteg_bktidx == ptegidx) + pvo_pt->pte_hi &= ~LPTE_HID; + else + pvo_pt->pte_hi |= LPTE_HID; + + /* + * Synchronize the sacrifice PTE with its PVO, then mark both + * invalid. The PVO will be reused when/if the VM system comes + * here after a fault. + */ + + if (evicted.pte_hi & LPTE_HID) + pteg_bktidx ^= moea64_pteg_mask; /* PTEs indexed by primary */ + + LIST_FOREACH(pvo, &moea64_pvo_table[pteg_bktidx], pvo_olink) { + if (pvo->pvo_pte.lpte.pte_hi == evicted.pte_hi) { + KASSERT(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID, + ("Invalid PVO for valid PTE!")); + phyp_hcall(H_REMOVE, 0, index, 0); + PVO_PTEGIDX_CLR(pvo); + moea64_pte_overflow++; + break; + } + } + + KASSERT(pvo->pvo_pte.lpte.pte_hi == evicted.pte_hi, + ("Unable to find PVO for spilled PTE")); + + /* + * Set the new PTE. + */ + result = phyp_pft_hcall(H_ENTER, H_EXACT, index, pvo_pt->pte_hi, + pvo_pt->pte_lo, &index, &evicted.pte_lo, &junk); + if (result == H_SUCCESS) + return (index & 0x07); + + panic("Page replacement error: %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: head/sys/powerpc/pseries/phyp-hvcall.S ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/powerpc/pseries/phyp-hvcall.S Tue Sep 17 17:37:04 2013 (r255643) @@ -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: head/sys/powerpc/pseries/phyp-hvcall.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/powerpc/pseries/phyp-hvcall.h Tue Sep 17 17:37:04 2013 (r255643) @@ -0,0 +1,305 @@ +/*- + * 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: head/sys/powerpc/pseries/phyp_console.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/powerpc/pseries/phyp_console.c Tue Sep 17 17:37:04 2013 (r255643) @@ -0,0 +1,420 @@ +/*- + * Copyright (C) 2011 by 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 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/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/kdb.h> +#include <sys/kernel.h> +#include <sys/priv.h> +#include <sys/systm.h> +#include <sys/module.h> +#include <sys/types.h> +#include <sys/conf.h> +#include <sys/cons.h> +#include <sys/tty.h> +#include <machine/bus.h> + +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> +#include <dev/uart/uart.h> +#include <dev/uart/uart_cpu.h> +#include <dev/uart/uart_bus.h> + +#include "phyp-hvcall.h" +#include "uart_if.h" + +struct uart_phyp_softc { + device_t dev; + phandle_t node; + int vtermid; + + struct tty *tp; + struct resource *irqres; + int irqrid; + struct callout callout; + void *sc_icookie; + int polltime; + + struct mtx sc_mtx; + int protocol; + + union { + uint64_t u64[2]; + char str[16]; + } phyp_inbuf; + uint64_t inbuflen; + uint8_t outseqno; +}; + +static struct uart_phyp_softc *console_sc = NULL; +#if defined(KDB) +static int alt_break_state; +#endif + +enum { + HVTERM1, HVTERMPROT +}; + +#define VS_DATA_PACKET_HEADER 0xff +#define VS_CONTROL_PACKET_HEADER 0xfe +#define VSV_SET_MODEM_CTL 0x01 +#define VSV_MODEM_CTL_UPDATE 0x02 +#define VSV_RENEGOTIATE_CONNECTION 0x03 +#define VS_QUERY_PACKET_HEADER 0xfd +#define VSV_SEND_VERSION_NUMBER 0x01 +#define VSV_SEND_MODEM_CTL_STATUS 0x02 +#define VS_QUERY_RESPONSE_PACKET_HEADER 0xfc + +static int uart_phyp_probe(device_t dev); +static int uart_phyp_attach(device_t dev); +static void uart_phyp_intr(void *v); + +static device_method_t uart_phyp_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, uart_phyp_probe), + DEVMETHOD(device_attach, uart_phyp_attach), + + DEVMETHOD_END +}; + +static driver_t uart_phyp_driver = { + "uart", + uart_phyp_methods, + sizeof(struct uart_phyp_softc), +}; + +DRIVER_MODULE(uart_phyp, vdevice, uart_phyp_driver, uart_devclass, 0, 0); + +static cn_probe_t uart_phyp_cnprobe; +static cn_init_t uart_phyp_cninit; +static cn_term_t uart_phyp_cnterm; +static cn_getc_t uart_phyp_cngetc; +static cn_putc_t uart_phyp_cnputc; +static cn_grab_t uart_phyp_cngrab; +static cn_ungrab_t uart_phyp_cnungrab; *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"