|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
Hi Bhupinder, On 21/02/17 11:25, Bhupinder Thakur wrote: 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 [...] +static int vpl011_mmio_write(struct vcpu *v, mmio_info_t *info, register_t r, void *priv) See my comment on the vpl011_mmio_read about the structure of the function. This register is not required in the SBSA UART. + v->domain->arch.vpl011.control = r; + break; + case VPL011_UARTDR_OFFSET: + vpl011_write_data(v->domain, ch); The implicit casting of register_t to ch is a bit confusing. Also I would prefer to use uint8_t as it reflects the size of the field. Lastly, what if vpl011_write_data is returning an error? + break; + case VPL011_UARTIMSC_OFFSET: + v->domain->arch.vpl011.intr_mask = r; You need to sanitize the value written and make sure reserved field and Write As Ones register and handle correctly (see the spec). + if ( (v->domain->arch.vpl011.raw_intr_status & v->domain->arch.vpl011.intr_mask) ) This line and the line below are over 80 columns. Also the code in general would benefits if you define a local variable to point to v->domain->arch.vpl011. + vgic_vcpu_inject_spi(v->domain, (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]); I don't think we need an HVM_PARAM for the pl011 SPI. We cannot hardcode this in the guest layout (see include/public/arch-arm.h).
{ } are not necessary.
+ vgic_vcpu_inject_spi(v->domain, (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]); + } The if is exactly the same as the on in IMSC. This is the call of an helper to check the interrupt state and inject one if necessary. + break; + case VPL011_UARTRSR_OFFSET: // nothing to clear The coding style for single line comment in Xen is /* ... */ Also, I think we may want to handle Overrun error as the ring may be full. + break; + case VPL011_UARTFR_OFFSET: // these are all RO registers + case VPL011_UARTRIS_OFFSET: + case VPL011_UARTMIS_OFFSET: + case VPL011_UARTDMACR_OFFSET: Please have a look at the vGICv2/vGICv3 emulation see how we implemented write ignore register. See my comment about the prinkt in the read emulation. Only newline is sufficient. This was mention by Konrad and I will try to avoid repeating his comments. Why do you need the cast?Also I cannot find any code in this series which destroy the ring. Please have a helper called vpl011_unmap_guest_page to do this job and call when the domain is destroyed. See my comment above about having an helper for this code. The backend console does not necessarily live in DOM0. Anyway, Konrad requested to drop the comment and I am happy with that. + */ + rc = raw_evtchn_send(d, + d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN], NULL); You are using a function that is been defined in a later patch (i.w #3). All the patch should be able to compile without applying upcoming patch to allow bisection. Ideally, Xen should still be functional for every patch. But it is a best effort. This function does not seem to be used outside of this file. So why do you export it? Same has for vpl011_read_data. vpl011_data_avail is returning an error but you don't check. What is the point of it then? +} + +int domain_vpl011_init(struct domain *d) I was expected a destroy function to clean-up the vpl011 emulation. This line looks wrong to me. The console backend may not live in the same domain as the toolstack. It makes little sense to hardcode the MMIO region and not the SPI. Also, I would rather avoid to introduce new HVM_PARAM when not necessary. So hardcoding the value looks more sensible to me. + + /* + * register mmio handler + */ + register_mmio_handler (d, &vpl011_mmio_handler, GUEST_PL011_BASE, GUEST_PL011_SIZE, NULL); Coding style. No space between the function name and (. + + /* + * 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; The domain structure is already zeroed. So no need to 0 it again. + + return 0; +} Missing e-macs magic here. 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 Header should live in include. [...] +#ifndef _VPL011_H_ + +#define _VPL011_H_ + +/* + * register offsets + */ We already define the PL011 register in include/asm-arm/pl011-uart.h. Please re-use them rather than re-inventing the wheel. +#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 [...] The communication between Xen and the console backend is based on the PV console ring. It would be easier to re-use it rather than recreating one. This should go in arch/arm/Kconfig Spurious line. I think the structure should be defined in vpl011.h. } __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) + Spurious line. #define GUEST_RAM_BANKS 2 #define GUEST_RAM0_BASE xen_mk_ullong(0x40000000) /* 3GB of low RAM @ 1GB */ Cheers, -- Julien Grall _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |