[RFC] arm64: Early printk support for virtio-mmio console devices.

Pranavkumar Sawargaonkar pranavkumar at linaro.org
Tue Apr 23 01:53:38 EDT 2013


On 22 April 2013 10:45, Rusty Russell <rusty at rustcorp.com.au> wrote:
> Anup Patel <anup.patel at linaro.org> writes:
>> On 22 April 2013 06:51, Rusty Russell <rusty at rustcorp.com.au> wrote:
>>>
>>> Pranavkumar Sawargaonkar <pranavkumar at linaro.org> writes:
>>> > On 18 April 2013 12:21, Rusty Russell <rusty at rustcorp.com.au> wrote:
>>> >>
>>> >> PranavkumarSawargaonkar <pranavkumar at linaro.org> writes:
>>> >> > From: Pranavkumar Sawargaonkar <pranavkumar at linaro.org>
>>> >> >
>>> >> > This patch implements early printk support for virtio-mmio console
>>> >> > devices without using any hypercalls.
>>> >>
>>> >> This makes some sense, though not sure that early console *read* makes
>>> >> much sense.  I can see the PCI version of this being useful as well.
>>> >
>>> > Read can be useful for "mach-virt" which will have only virtio console
>>> > as a console device. Then if someone wants to have UEFI or any other
>>> > boot-loader emulation, which expects user to input few things, in that
>>> > case read might become handy.
>>>
>>> But implementing virtio inside a bootloader has already been done for
>>> coreboot, for example.  A bootloader probably wants a virtio block
>>> device, so a console is trivial.
>>>
>>> A single writable field for debugging makes sense.  Anything more is far
>>> less certain.
>>
>> The early read can be handy for bootloader who don't want to implement
>> complete VirtIO programming.
>
> I've said this twice already.  This is the last time.
>
> 1) We do not add complexity unless we have to.
> 2) Making it optional does not make it significantly less complex.
> 3) Having two ways of doing the same thing is always ugly.
> 4) Having an emergency output method makes sense for several use cases,
>    an emergency input method does not.
Okay,  i will restructure my patch by keeping just output write part
and post it back.

Thanks,
Pranav

> 5) A bootloader which uses virtio to get the images to boot can
>    implement a console in less than 10 lines.
> 6) A bootloader which does not use any virtio devices but nonetheless
>    wants to obtain input can implement a simple console in well under 100
>    lines.  See below.
>
> Finally, in case you still don't understand:
>
> My task is to make this decision, and I've made it.  Arguing with me is
> only useful if you bring new facts which you can change my mind.
>
> Hope that clarifies,
> Rusty.
>
> #define VIRTIO_MMIO_GUEST_PAGE_SIZE     0x028
> #define VIRTIO_MMIO_QUEUE_SEL           0x030
> #define VIRTIO_MMIO_QUEUE_NUM_MAX       0x034
> #define VIRTIO_MMIO_QUEUE_NUM           0x038
> #define VIRTIO_MMIO_QUEUE_ALIGN         0x03c
> #define VIRTIO_MMIO_QUEUE_PFN           0x040
> #define VIRTIO_MMIO_QUEUE_NOTIFY        0x050
>
> struct vring_desc {
>         __u64 addr;
>         __u32 len;
>         __u16 flags;
>         __u16 next;
> };
>
> struct vring_used_elem {
>         __u32 id;
>         __u32 len;
> };
>
> struct vconsole_ring {
>         struct vring_desc desc[2];
>         __u16 avail_flags;
>         __u16 avail_idx;
>         __u16 available[2];
>         __u16 used_event_idx;
>         __u16 pad; /* Hit 4-byte boundary */
>
>         // A ring of used descriptor heads with free-running index.
>         __u16 used_flags;
>         __u16 used_idx;
>         struct vring_used_elem used[2];
>         __u16 avail_event_idx;
> };
>
> static char console_in;
> static struct vconsole_ring vc_ring = {
>         { { PHYSICAL_ADDR(console_in), 1, 2, 0 } },
>         1, /* No interrupts */
> }
>
> static void post_buffer(void *base)
> {
>         vc_ring->avail_idx++;
>         wmb();
>         writel(0, base + VIRTIO_MMIO_QUEUE_NOTIFY);
> }
>
> bool vc_read(void *base, char *c)
> {
>         mb();
>         if (vc_ring->used_idx != vc_ring->avail_idx)
>                 return false;
>         *c = console_in;
>         post_buffer(base);
>         return true;
> }
>
> void vc_init(void *base)
> {
>         /* Alignment of 4 bytes, don't waste any. */
>         writel(4, base + VIRTIO_MMIO_GUEST_PAGE_SIZE);
>
>         /* Setup incoming vq. */
>         writel(0, base + VIRTIO_MMIO_QUEUE_SEL);
>
>         /* 2 elements */
>         writel(2, base + VIRTIO_MMIO_QUEUE_NUM);
>         /* Alignment of 4 bytes */
>         writel(4, base + VIRTIO_MMIO_QUEUE_ALIGN);
>         /* Location of queue. */
>         writel(PHYSICAL_ADDR(&vc_ring) >> 4, base + VIRTIO_MMIO_QUEUE_PFN);
>
>         post_buffer(base);
> }



More information about the linux-arm-kernel mailing list