|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [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@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |