From patchwork Tue Feb 21 11:25:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhupinder Thakur X-Patchwork-Id: 9584271 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E49566042F for ; Tue, 21 Feb 2017 11:28:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D0E6128782 for ; Tue, 21 Feb 2017 11:28:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C4B65288DB; Tue, 21 Feb 2017 11:28:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-0.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, RCVD_IN_SORBS_SPAM, RCVD_IN_SORBS_WEB, T_DKIM_INVALID autolearn=no version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8229928782 for ; Tue, 21 Feb 2017 11:28:37 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cg8aN-0002gx-ML; Tue, 21 Feb 2017 11:26:23 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cg8aM-0002gQ-EZ for xen-devel@lists.xenproject.org; Tue, 21 Feb 2017 11:26:22 +0000 Received: from [193.109.254.147] by server-9.bemta-6.messagelabs.com id 98/5C-27165-DD32CA85; Tue, 21 Feb 2017 11:26:21 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrEIsWRWlGSWpSXmKPExsXiVRtsontHeU2 EwcebVhbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8bGJ81sBdu3MFYsf3CHpYGxpZexi5GLQ0hg GqPEna63rCAOi8A8ZokXv7vAHAmBflaJafcnsXcxcgI5MRILO+eyQtgVEieOdrKB2EICWhJHT 81mhbBbmSSOTw/uYuTgYBMwkZjVIQESFhFQkri3ajITiM0sECrx71kb2EhhAXeJqZfuMoLYLA KqEvunPGEGaeUV8JY40+sEsUlO4ua5TmYQm1PAR+LvvpfsEJu8JabdWcE2gVFgASPDKkaN4tS istQiXUNDvaSizPSMktzEzBxdQwMzvdzU4uLE9NScxKRiveT83E2MwNBiAIIdjJ+WBRxilORg UhLlzZZaEyHEl5SfUpmRWJwRX1Sak1p8iFGGg0NJgneOElBOsCg1PbUiLTMHGOQwaQkOHiUR3 iOKQGne4oLE3OLMdIjUKUZ7jlu/Tr1k4ti3/QyQ/LITRO7adfklkxBLXn5eqpQ4bxnIVAGQto zSPLihsKi8xCgrJczLCHSmEE9BalFuZgmq/CtGcQ5GJWHe/SBTeDLzSuB2vwI6iwnorJseK0H OKklESEk1MMrVOn68k/jU4u6v418sChhmiU37bHFCbMKEU0usZwVs88nJ1dFiMUl59n7b0Z4Z /P+W+1nkvPr0curGYxv3V+5uKuH/8qzVqNf0kNmN1j2/HWwD4+wycpYIhHrPfXaWkXHp2fX+W UUR1neuiBbeYSy33/jw8IKz5zLmqz9NrHLODVlzcem7I0JKLMUZiYZazEXFiQBEX94SxQIAAA == X-Env-Sender: bhupinder.thakur@linaro.org X-Msg-Ref: server-10.tower-27.messagelabs.com!1487676379!64852943!1 X-Originating-IP: [74.125.83.52] X-SpamReason: No, hits=0.0 required=7.0 tests=UPPERCASE_25_50 X-StarScan-Received: X-StarScan-Version: 9.2.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 51685 invoked from network); 21 Feb 2017 11:26:20 -0000 Received: from mail-pg0-f52.google.com (HELO mail-pg0-f52.google.com) (74.125.83.52) by server-10.tower-27.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 21 Feb 2017 11:26:20 -0000 Received: by mail-pg0-f52.google.com with SMTP id 1so16553564pgi.1 for ; Tue, 21 Feb 2017 03:26:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DlVmuYIXs5ywJmDBShT78+jnheTZTsjwqJeRy+GlkoA=; b=jG+9TMTAs//LIMcNgyjznHigZ/BbhfqHlhNu2hQHALZnhpZUo2GjXwoJRbmsgwIpkX B9TH6N1RVIOe/kLlM/Q9zkgOqMTRkl9D2TDmGU/20mIcqXo4ya11/cJpLh80PSQbvNra GwmZO4cHj/bCvuh58/cdXvGhJ6FYQ7RQZVMng= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DlVmuYIXs5ywJmDBShT78+jnheTZTsjwqJeRy+GlkoA=; b=ZHoIwSCpWFsS+UeSL1EmiuieSMfPwfH5do8xuiraLflUamCbDqJWNh41jp60/Hqyee 790w77Py+yfXqY4jJmg8d++VLNvP5sNvJYmkq+v5q0fEwtfUSP59X8g7Elcl6wyP2BR8 /QtQtBccEExlcYMR02Lqb7DArf21rGeWpb8jjJzZ11xKmIvlgv7deD/1AnYSj9qkKxwI Uap+SpYmVVch9tB5eki6VOQ9P/VyYvN0rLWce0fPcnjqYZlj6/A0oMLDiJaXLAfMGHRK E2WtAECEAv2YWE8vRk6+6soTb7osrEJHs/JbyvBiw5Lf51JLpYzot9yGOIq7FIpqTDWn FE5g== X-Gm-Message-State: AMke39kxJDXN33xTm010p0Jkj2AcfmpwQ+hXICnEpkOd1BIzU389KkEzR+0RZVmK8YRCnZf8 X-Received: by 10.99.112.75 with SMTP id a11mr33965286pgn.7.1487676378729; Tue, 21 Feb 2017 03:26:18 -0800 (PST) Received: from blr-ubuntu-linaro.wlan.qualcomm.com ([103.5.19.18]) by smtp.gmail.com with ESMTPSA id p66sm40508627pfb.88.2017.02.21.03.26.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 21 Feb 2017 03:26:18 -0800 (PST) From: Bhupinder Thakur To: xen-devel@lists.xenproject.org Date: Tue, 21 Feb 2017 16:55:58 +0530 Message-Id: <1487676368-22356-2-git-send-email-bhupinder.thakur@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1487676368-22356-1-git-send-email-bhupinder.thakur@linaro.org> References: <1487676368-22356-1-git-send-email-bhupinder.thakur@linaro.org> Cc: Julien Grall , Stefano Stabellini Subject: [Xen-devel] [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add emulation code to emulate read/write access to pl011 registers and pl011 interrupts: - It emulates DR read/write by reading and writing from/to the IN and OUT ring buffers and raising an event to dom0 when there is data in the OUT ring buffer and injecting an interrupt to the guest when there is data in the IN ring buffer - Other registers are related to interrupt management and essentially control when interrupts are delivered to the guest Signed-off-by: Bhupinder Thakur --- xen/arch/arm/Makefile | 1 + xen/arch/arm/vpl011.c | 366 ++++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/vpl011.h | 208 ++++++++++++++++++++++++ xen/common/Kconfig | 6 + xen/include/asm-arm/domain.h | 15 ++ xen/include/public/arch-arm.h | 5 + 6 files changed, 601 insertions(+) create mode 100644 xen/arch/arm/vpl011.c create mode 100644 xen/arch/arm/vpl011.h diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index 7afb8a3..a94bdab 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -49,6 +49,7 @@ obj-y += vm_event.o obj-y += vtimer.o obj-y += vpsci.o obj-y += vuart.o +obj-$(CONFIG_VPL011_CONSOLE) += vpl011.o #obj-bin-y += ....o diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c new file mode 100644 index 0000000..88ba968 --- /dev/null +++ b/xen/arch/arm/vpl011.c @@ -0,0 +1,366 @@ +/* + * arch/arm/vpl011.c + * + * Virtual PL011 UART + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include "vpl011.h" + +static int vpl011_mmio_read(struct vcpu *v, mmio_info_t *info, register_t *r, void *priv) +{ + unsigned char ch; + + switch (info->gpa - GUEST_PL011_BASE) + { + case VPL011_UARTCR_OFFSET: + *r = v->domain->arch.vpl011.control; + break; + case VPL011_UARTDR_OFFSET: + vpl011_read_data(v->domain, &ch); + *r = ch; + break; + case VPL011_UARTFR_OFFSET: + *r = v->domain->arch.vpl011.flag; + break; + case VPL011_UARTIMSC_OFFSET: + *r = v->domain->arch.vpl011.intr_mask; + break; + case VPL011_UARTICR_OFFSET: + *r = 0; + break; + case VPL011_UARTRIS_OFFSET: + *r = v->domain->arch.vpl011.raw_intr_status; + break; + case VPL011_UARTMIS_OFFSET: + *r = v->domain->arch.vpl011.raw_intr_status & + v->domain->arch.vpl011.intr_mask; + break; + case VPL011_UARTDMACR_OFFSET: + *r = 0; /* uart DMA is not supported. Here it always returns 0 */ + break; + case VPL011_UARTRSR_OFFSET: + *r = 0; /* it always returns 0 as there are no physical errors */ + break; + default: + printk ("vpl011_mmio_read: invalid switch case %d\n", (int)(info->gpa - GUEST_PL011_BASE)); + break; + } + + return VPL011_EMUL_OK; +} + +static int vpl011_mmio_write(struct vcpu *v, mmio_info_t *info, register_t r, void *priv) +{ + unsigned char ch = r; + + switch (info->gpa - GUEST_PL011_BASE) + { + case VPL011_UARTCR_OFFSET: + v->domain->arch.vpl011.control = r; + break; + case VPL011_UARTDR_OFFSET: + vpl011_write_data(v->domain, ch); + break; + case VPL011_UARTIMSC_OFFSET: + v->domain->arch.vpl011.intr_mask = r; + if ( (v->domain->arch.vpl011.raw_intr_status & v->domain->arch.vpl011.intr_mask) ) + vgic_vcpu_inject_spi(v->domain, (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]); + break; + case VPL011_UARTICR_OFFSET: + /* + * clear all bits which are set in the input + */ + v->domain->arch.vpl011.raw_intr_status &= ~r; + if ( (v->domain->arch.vpl011.raw_intr_status & v->domain->arch.vpl011.intr_mask) ) + { + vgic_vcpu_inject_spi(v->domain, (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]); + } + break; + case VPL011_UARTRSR_OFFSET: // nothing to clear + break; + case VPL011_UARTFR_OFFSET: // these are all RO registers + case VPL011_UARTRIS_OFFSET: + case VPL011_UARTMIS_OFFSET: + case VPL011_UARTDMACR_OFFSET: + break; + default: + printk ("vpl011_mmio_write: switch case not handled %d\n", (int)(info->gpa - GUEST_PL011_BASE)); + break; + } + + return VPL011_EMUL_OK; +} + +static const struct mmio_handler_ops vpl011_mmio_handler = { + .read = vpl011_mmio_read, + .write = vpl011_mmio_write, +}; + + + +int vpl011_map_guest_page(struct domain *d) +{ + int rc=0; + + /* + * map the guest PFN to Xen address space + */ + rc = prepare_ring_for_helper(d, + d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_PFN], + &d->arch.vpl011.ring_page, + (void **)&d->arch.vpl011.ring_buf); + if ( rc < 0 ) + { + printk("Failed to map vpl011 guest PFN\n"); + } + + return rc; +} + +static int vpl011_data_avail(struct domain *d) +{ + int rc=0; + unsigned long flags; + + struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf; + + VPL011_LOCK(d, flags); + + /*` + * check IN ring buffer + */ + if ( !VPL011_IN_RING_EMPTY(intf) ) + { + /* + * clear the RX FIFO empty flag as the ring is not empty + */ + d->arch.vpl011.flag &= ~(VPL011_UARTFR_RXFE); + + /* + * if the buffer is full then set the RX FIFO FULL flag + */ + if ( VPL011_IN_RING_FULL(intf) ) + d->arch.vpl011.flag |= (VPL011_UARTFR_RXFF); + + /* + * set the RX interrupt status + */ + d->arch.vpl011.raw_intr_status |= (VPL011_UARTRIS_RXRIS); + } + + /* + * check OUT ring buffer + */ + if ( !VPL011_OUT_RING_FULL(intf) ) + { + /* + * if the buffer is not full then clear the TX FIFO full flag + */ + d->arch.vpl011.flag &= ~(VPL011_UARTFR_TXFF); + + /* + * set the TX interrupt status + */ + d->arch.vpl011.raw_intr_status |= (VPL011_UARTRIS_TXRIS); + + if ( VPL011_OUT_RING_EMPTY(intf) ) + { + /* + * clear the uart busy flag and set the TX FIFO empty flag + */ + d->arch.vpl011.flag &= ~(VPL011_UARTFR_BUSY); + d->arch.vpl011.flag |= (VPL011_UARTFR_TXFE); + } + } + + VPL011_UNLOCK(d, flags); + + /* + * send an interrupt if it is not masked + */ + if ( (d->arch.vpl011.raw_intr_status & d->arch.vpl011.intr_mask) ) + vgic_vcpu_inject_spi(d, (int)d->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]); + + if ( !VPL011_OUT_RING_EMPTY(intf) ) + { + /* + * raise an interrupt to dom0 + */ + rc = raw_evtchn_send(d, + d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN], NULL); + + if ( rc < 0 ) + printk("Failed to send vpl011 interrupt to dom0\n"); + } + + return rc; +} + +int vpl011_read_data(struct domain *d, unsigned char *data) +{ + int rc=0; + unsigned long flags; + struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf; + + *data = 0; + + VPL011_LOCK(d, flags); + + /* + * if there is data in the ring buffer then copy it to the output buffer + */ + if ( !VPL011_IN_RING_EMPTY(intf) ) + { + *data = intf->in[MASK_VPL011CONS_IDX(intf->in_cons++, intf->in)]; + } + + /* + * if the ring buffer is empty then set the RX FIFO empty flag + */ + if ( VPL011_IN_RING_EMPTY(intf) ) + { + d->arch.vpl011.flag |= (VPL011_UARTFR_RXFE); + d->arch.vpl011.raw_intr_status &= ~(VPL011_UARTRIS_RXRIS); + } + + /* + * clear the RX FIFO full flag + */ + d->arch.vpl011.flag &= ~(VPL011_UARTFR_RXFF); + + VPL011_UNLOCK(d, flags); + + return rc; +} + +int vpl011_write_data(struct domain *d, unsigned char data) +{ + int rc=0; + unsigned long flags; + struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf; + + VPL011_LOCK(d, flags); + + /* + * if there is space in the ring buffer then write the data + */ + if ( !VPL011_OUT_RING_FULL(intf) ) + { + intf->out[MASK_VPL011CONS_IDX(intf->out_prod++, intf->out)] = data; + smp_wmb(); + } + + /* + * if there is no space in the ring buffer then set the + * TX FIFO FULL flag + */ + if ( VPL011_OUT_RING_FULL(intf) ) + { + d->arch.vpl011.flag |= (VPL011_UARTFR_TXFF); + d->arch.vpl011.raw_intr_status &= ~(VPL011_UARTRIS_TXRIS); + } + + /* + * set the uart busy status + */ + d->arch.vpl011.flag |= (VPL011_UARTFR_BUSY); + + /* + * clear the TX FIFO empty flag + */ + d->arch.vpl011.flag &= ~(VPL011_UARTFR_TXFE); + + VPL011_UNLOCK(d, flags); + + /* + * raise an event to dom0 only if it is the first character in the buffer + */ + if ( VPL011_RING_DEPTH(intf, out) == 1 ) + { + rc = raw_evtchn_send(d, + d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN], NULL); + + if ( rc < 0 ) + printk("Failed to send vpl011 interrupt to dom0\n"); + } + + return rc; +} + +static void vpl011_notification(struct vcpu *v, unsigned int port) +{ + vpl011_data_avail(v->domain); +} + +int domain_vpl011_init(struct domain *d) +{ + int rc=0; + + /* + * register xen event channel + */ + rc = alloc_unbound_xen_event_channel(d, 0, current->domain->domain_id, + vpl011_notification); + if (rc < 0) + { + printk ("Failed to allocate vpl011 event channel\n"); + return rc; + } + d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN] = rc; + + /* + * allocate an SPI VIRQ for the guest + */ + d->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ] = vgic_allocate_spi(d); + + /* + * register mmio handler + */ + register_mmio_handler (d, &vpl011_mmio_handler, GUEST_PL011_BASE, GUEST_PL011_SIZE, NULL); + + /* + * initialize the lock + */ + spin_lock_init(&d->arch.vpl011.lock); + + /* + * clear the flag, control and interrupt status registers + */ + d->arch.vpl011.control = 0; + d->arch.vpl011.flag = 0; + d->arch.vpl011.intr_mask = 0; + d->arch.vpl011.intr_clear = 0; + d->arch.vpl011.raw_intr_status = 0; + d->arch.vpl011.masked_intr_status = 0; + + return 0; +} diff --git a/xen/arch/arm/vpl011.h b/xen/arch/arm/vpl011.h new file mode 100644 index 0000000..f2c577f --- /dev/null +++ b/xen/arch/arm/vpl011.h @@ -0,0 +1,208 @@ +/* + * include/xen/vpl011.h + * + * Virtual PL011 UART + * + * 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 . + */ + +#ifndef _VPL011_H_ + +#define _VPL011_H_ + +/* + * register offsets + */ +#define VPL011_UARTDR_OFFSET 0x0 // data register (RW) +#define VPL011_UARTRSR_OFFSET 0x4 // receive status and error clear register (RW) +#define VPL011_UARTFR_OFFSET 0x18 // flag register (RO) +#define VPL011_UARTRIS_OFFSET 0x3c // raw interrupt status register (RO) +#define VPL011_UARTMIS_OFFSET 0x40 // masked interrupt status register (RO) +#define VPL011_UARTIMSC_OFFSET 0x38 // interrupt mask set/clear register (RW) +#define VPL011_UARTICR_OFFSET 0x44 // interrupt clear register (WO) +#define VPL011_UARTCR_OFFSET 0x30 // uart control register +#define VPL011_UARTDMACR_OFFSET 0x48 // uart dma control register + +/* + * control register bits - RW + */ +#define VPL011_UARTCR_UARTEN_BIT 0 +#define VPL011_UARTCR_UARTEN (1<dir ## _prod - (intf)->dir ## _cons)) +#define VPL011_RING_MAX_DEPTH(intf,dir) (sizeof((intf)->dir)-1) + +#define VPL011_IN_RING_EMPTY(intf) (VPL011_RING_DEPTH(intf, in) == 0) + +#define VPL011_OUT_RING_EMPTY(intf) (VPL011_RING_DEPTH(intf, out) == 0) + +#define VPL011_IN_RING_FULL(intf) (VPL011_RING_DEPTH(intf, in) == VPL011_RING_MAX_DEPTH(intf, in)) + +#define VPL011_OUT_RING_FULL(intf) (VPL011_RING_DEPTH(intf, out) == VPL011_RING_MAX_DEPTH(intf,out)) + +#define VPL011_LOCK(d,flags) spin_lock_irqsave(&(d)->arch.vpl011.lock, flags) +#define VPL011_UNLOCK(d,flags) spin_unlock_irqrestore(&(d)->arch.vpl011.lock, flags) + +/* + * MMIO return values + */ +#define VPL011_EMUL_OK 1 +#define VPL011_EMUL_FAIL 0 + +int domain_vpl011_init(struct domain *d); +int vpl011_map_guest_page(struct domain *d); +int vpl011_read_data(struct domain *d, unsigned char *data); +int vpl011_write_data(struct domain *d, unsigned char data); + +#define MASK_VPL011CONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1)) +struct console_interface { + char in[1024]; + char out[2048]; + uint32_t in_cons, in_prod; + uint32_t out_cons, out_prod; +}; +#endif diff --git a/xen/common/Kconfig b/xen/common/Kconfig index f2ecbc4..7e2feac 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -237,4 +237,10 @@ config FAST_SYMBOL_LOOKUP The only user of this is Live patching. If unsure, say Y. + +config VPL011_CONSOLE + bool "Emulated pl011 console support" + default y + ---help--- + Allows a guest to use pl011 UART as a console endmenu diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index 2d6fbb1..ff2403a 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -40,6 +40,7 @@ struct vtimer { uint64_t cval; }; + struct arch_domain { #ifdef CONFIG_ARM_64 @@ -131,6 +132,20 @@ struct arch_domain struct { uint8_t privileged_call_enabled : 1; } monitor; + +#ifdef CONFIG_VPL011_CONSOLE + struct vpl011 { + void *ring_buf; + struct page_info *ring_page; + uint32_t flag; /* flag register */ + uint32_t control; /* control register */ + uint32_t intr_mask; /* interrupt mask register*/ + uint32_t intr_clear; /* interrupt clear register */ + uint32_t raw_intr_status; /* raw interrupt status register */ + uint32_t masked_intr_status; /* masked interrupt register */ + spinlock_t lock; + } vpl011; +#endif } __cacheline_aligned; struct arch_vcpu diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h index bd974fb..1d4548f 100644 --- a/xen/include/public/arch-arm.h +++ b/xen/include/public/arch-arm.h @@ -410,6 +410,10 @@ typedef uint64_t xen_callback_t; #define GUEST_ACPI_BASE 0x20000000ULL #define GUEST_ACPI_SIZE 0x02000000ULL +/* PL011 mappings */ +#define GUEST_PL011_BASE 0x22000000ULL +#define GUEST_PL011_SIZE 0x00001000ULL + /* * 16MB == 4096 pages reserved for guest to use as a region to map its * grant table in. @@ -420,6 +424,7 @@ typedef uint64_t xen_callback_t; #define GUEST_MAGIC_BASE xen_mk_ullong(0x39000000) #define GUEST_MAGIC_SIZE xen_mk_ullong(0x01000000) + #define GUEST_RAM_BANKS 2 #define GUEST_RAM0_BASE xen_mk_ullong(0x40000000) /* 3GB of low RAM @ 1GB */