* domu console issue
@ 2018-11-14 10:21 Peng Fan
2018-11-15 3:18 ` Peng Fan
0 siblings, 1 reply; 2+ messages in thread
From: Peng Fan @ 2018-11-14 10:21 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, Stefano Stabellini
Hi,
I am trying to enable pv console in domu uboot without interrupt, but not work well,
When using xl console to attach domu, there are only a few chars output.
I add some debug info in write_console, and see out_cons are not increased after
notify_remote_by_evtchn. The write_console is taken from Linux driver/tty/hvc/hvc_xen.c
Any suggestions?
Thanks,
Peng.
struct xen_uart_priv {
struct xencons_interface *intf;
u32 evtchn;
int vtermno;
struct hvc_struct *hvc;
grant_ref_t gntref;
};
static int xen_serial_probe(struct udevice *dev)
{
struct xen_uart_priv *priv = dev_get_priv(dev);
uint64_t v = 0;
unsigned long gfn;
int r;
r = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v);
if (r < 0 || v == 0)
return r;
priv->evtchn= v;
r = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v);
if (r < 0 || v == 0)
return -ENODEV;
gfn = v;
priv->intf = (struct xencons_interface *)(gfn << XEN_PAGE_SHIFT);
if (priv->intf == NULL)
return -EINVAL;
return 0;
}
static int xen_serial_pending(struct udevice *dev, bool input)
{
struct xen_uart_priv *priv = dev_get_priv(dev);
struct xencons_interface *intf = priv->intf;
if (!input || intf->in_cons == intf->in_prod)
return 0;
return 1;
}
static int xen_serial_getc(struct udevice *dev)
{
struct xen_uart_priv *priv = dev_get_priv(dev);
struct xencons_interface *intf = priv->intf;
XENCONS_RING_IDX cons, prod;
int recv = 0;
char c;
int num_of_bytes = 1;
while (intf->in_cons == intf->in_prod) {
/* wait */
mb();
}
cons = intf->in_cons;
prod = intf->in_prod;
mb(); /* get pointers before reading ring */
while (cons != prod && recv < num_of_bytes) {
c = intf->in[MASK_XENCONS_IDX(cons++, intf->in)];
recv++;
}
mb(); /* read ring before consuming */
intf->in_cons = cons;
mb(); /* read ring before consuming */
if (recv)
notify_remote_via_evtchn(priv->evtchn);
return c;
}
static int __write_console(struct udevice *dev, const char *data, int len)
{
struct xen_uart_priv *priv = dev_get_priv(dev);
struct xencons_interface *intf = priv->intf;
XENCONS_RING_IDX cons, prod;
int sent = 0;
cons = intf->out_cons;
prod = intf->out_prod;
asm volatile("dsb sy\r\n" : : : "memory");
xen_raw_printk("11 %u %u\n", intf->out_cons, intf->out_prod);
BUG_ON((prod - cons) > sizeof(intf->out));
while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
asm volatile("dsb sy\r\n" : : : "memory");
intf->out_prod = prod;
xen_raw_printk("12 %u %u %d\n", intf->out_cons, intf->out_prod, sent);
if (sent)
notify_remote_via_evtchn(priv->evtchn);
mdelay(1000);
asm volatile("dsb sy\r\n" : : : "memory");
xen_raw_printk("\n");
xen_raw_printk("%u %u %s\n", intf->out_cons, intf->out_prod, &intf->out[MASK_XENCONS_IDX(intf->out_cons, intf->out)]);
return sent;
}
static int write_console(struct udevice *dev, const char *data, int len)
{
struct xen_uart_priv *priv = dev_get_priv(dev);
struct xencons_interface *intf = priv->intf;
int ret = len;
/*
* Make sure the whole buffer is emitted, polling if
* necessary. We don't ever want to rely on the hvc daemon
* because the most interesting console output is when the
* kernel is crippled.
*/
while (len) {
int sent = __write_console(dev, data, len);
data += sent;
len -= sent;
if (unlikely(len))
HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
}
return ret;
}
static int xen_serial_puts(struct udevice *dev, const char *str)
{
struct xen_uart_priv *priv = dev_get_priv(dev);
struct xencons_interface *intf = priv->intf;
XENCONS_RING_IDX cons, prod;
int sent = 0;
int num_of_bytes = strlen(str);
xen_raw_printk("%s", str);
write_console(dev, str, strlen(str));
return 0;
}
static int xen_serial_putc(struct udevice *dev, const char ch)
{
struct xen_uart_priv *priv = dev_get_priv(dev);
struct xencons_interface *intf = priv->intf;
XENCONS_RING_IDX cons, prod;
int sent = 0;
int num_of_bytes = 1;
xen_raw_printk("%c", ch);
write_console(dev, &ch, 1);
return 0;
}
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: domu console issue
2018-11-14 10:21 domu console issue Peng Fan
@ 2018-11-15 3:18 ` Peng Fan
0 siblings, 0 replies; 2+ messages in thread
From: Peng Fan @ 2018-11-15 3:18 UTC (permalink / raw)
To: Peng Fan, xen-devel; +Cc: Julien Grall, Stefano Stabellini
Resolved, did not setup xen magic pages in proper mmu settings.
Regards,
Peng.
> -----Original Message-----
> From: Xen-devel [mailto:xen-devel-bounces@lists.xenproject.org] On Behalf
> Of Peng Fan
> Sent: 2018年11月14日 18:22
> To: xen-devel@lists.xenproject.org
> Cc: Julien Grall <julien.grall@arm.com>; Stefano Stabellini
> <sstabellini@kernel.org>
> Subject: [Xen-devel] domu console issue
>
> Hi,
>
> I am trying to enable pv console in domu uboot without interrupt, but not
> work well, When using xl console to attach domu, there are only a few chars
> output.
>
> I add some debug info in write_console, and see out_cons are not increased
> after notify_remote_by_evtchn. The write_console is taken from Linux
> driver/tty/hvc/hvc_xen.c
>
> Any suggestions?
>
> Thanks,
> Peng.
>
> struct xen_uart_priv {
> struct xencons_interface *intf;
> u32 evtchn;
> int vtermno;
> struct hvc_struct *hvc;
> grant_ref_t gntref;
> };
>
> static int xen_serial_probe(struct udevice *dev) {
> struct xen_uart_priv *priv = dev_get_priv(dev);
> uint64_t v = 0;
> unsigned long gfn;
> int r;
>
> r = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v);
> if (r < 0 || v == 0)
> return r;
>
> priv->evtchn= v;
>
> r = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v);
> if (r < 0 || v == 0)
> return -ENODEV;
>
> gfn = v;
>
> priv->intf = (struct xencons_interface *)(gfn << XEN_PAGE_SHIFT);
> if (priv->intf == NULL)
> return -EINVAL;
>
> return 0;
> }
>
> static int xen_serial_pending(struct udevice *dev, bool input) {
> struct xen_uart_priv *priv = dev_get_priv(dev);
> struct xencons_interface *intf = priv->intf;
>
> if (!input || intf->in_cons == intf->in_prod)
> return 0;
>
> return 1;
> }
>
> static int xen_serial_getc(struct udevice *dev) {
> struct xen_uart_priv *priv = dev_get_priv(dev);
> struct xencons_interface *intf = priv->intf;
> XENCONS_RING_IDX cons, prod;
> int recv = 0;
> char c;
> int num_of_bytes = 1;
>
> while (intf->in_cons == intf->in_prod) {
> /* wait */
> mb();
> }
>
> cons = intf->in_cons;
> prod = intf->in_prod;
> mb(); /* get pointers before reading ring */
>
> while (cons != prod && recv < num_of_bytes) {
> c = intf->in[MASK_XENCONS_IDX(cons++, intf->in)];
> recv++;
> }
>
> mb(); /* read ring before consuming */
> intf->in_cons = cons;
> mb(); /* read ring before consuming */
>
> if (recv)
> notify_remote_via_evtchn(priv->evtchn);
>
> return c;
> }
>
> static int __write_console(struct udevice *dev, const char *data, int len) {
> struct xen_uart_priv *priv = dev_get_priv(dev);
> struct xencons_interface *intf = priv->intf;
> XENCONS_RING_IDX cons, prod;
> int sent = 0;
>
> cons = intf->out_cons;
> prod = intf->out_prod;
> asm volatile("dsb sy\r\n" : : : "memory");
> xen_raw_printk("11 %u %u\n", intf->out_cons, intf->out_prod);
>
> BUG_ON((prod - cons) > sizeof(intf->out));
>
> while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
> intf->out[MASK_XENCONS_IDX(prod++, intf->out)] =
> data[sent++];
>
> asm volatile("dsb sy\r\n" : : : "memory");
> intf->out_prod = prod;
> xen_raw_printk("12 %u %u %d\n", intf->out_cons, intf->out_prod,
> sent);
>
> if (sent)
> notify_remote_via_evtchn(priv->evtchn);
>
> mdelay(1000);
> asm volatile("dsb sy\r\n" : : : "memory");
> xen_raw_printk("\n");
> xen_raw_printk("%u %u %s\n", intf->out_cons, intf->out_prod,
> &intf->out[MASK_XENCONS_IDX(intf->out_cons, intf->out)]);
>
> return sent;
> }
>
> static int write_console(struct udevice *dev, const char *data, int len) {
> struct xen_uart_priv *priv = dev_get_priv(dev);
> struct xencons_interface *intf = priv->intf;
> int ret = len;
>
> /*
> * Make sure the whole buffer is emitted, polling if
> * necessary. We don't ever want to rely on the hvc daemon
> * because the most interesting console output is when the
> * kernel is crippled.
> */
> while (len) {
> int sent = __write_console(dev, data, len);
>
> data += sent;
> len -= sent;
>
> if (unlikely(len))
> HYPERVISOR_sched_op(SCHEDOP_yield,
> NULL);
> HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
> }
>
> return ret;
> }
>
> static int xen_serial_puts(struct udevice *dev, const char *str) {
> struct xen_uart_priv *priv = dev_get_priv(dev);
> struct xencons_interface *intf = priv->intf;
> XENCONS_RING_IDX cons, prod;
>
> int sent = 0;
> int num_of_bytes = strlen(str);
>
> xen_raw_printk("%s", str);
>
> write_console(dev, str, strlen(str));
>
> return 0;
> }
>
> static int xen_serial_putc(struct udevice *dev, const char ch) {
> struct xen_uart_priv *priv = dev_get_priv(dev);
> struct xencons_interface *intf = priv->intf;
> XENCONS_RING_IDX cons, prod;
>
> int sent = 0;
> int num_of_bytes = 1;
>
> xen_raw_printk("%c", ch);
>
> write_console(dev, &ch, 1);
>
> return 0;
> }
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xenproject.org
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.
> xenproject.org%2Fmailman%2Flistinfo%2Fxen-devel&data=02%7C01%7
> Cpeng.fan%40nxp.com%7C58d7c4ebe8da4811056708d64a1b1181%7C686ea
> 1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C636777877462336257&
> sdata=bLm8uKrON4RbaGFLjN%2FE0TZeedTKFPHnQkNdfRTDBD0%3D&r
> eserved=0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-11-15 3:18 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-14 10:21 domu console issue Peng Fan
2018-11-15 3:18 ` Peng Fan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.