Re: [Qemu-devel] [PATCH V4 3/7] CAN bus SJA1000 chip register level emulation for QEMU

2018-01-14 Thread Philippe Mathieu-Daudé
On 01/14/2018 05:14 PM, p...@cmp.felk.cvut.cz wrote:
> From: Pavel Pisa 
> 
> The core SJA1000 support is independent of following
> patches which map SJA1000 chip to PCI boards.
> 
> The work is based on Jin Yang GSoC 2013 work funded
> by Google and mentored in frame of RTEMS project GSoC
> slot donated to QEMU.
> 
> Rewritten for QEMU-2.0+ versions and architecture cleanup
> by Pavel Pisa (Czech Technical University in Prague).
> 
> Signed-off-by: Pavel Pisa 
> ---
>  default-configs/pci.mak |1 +
>  hw/can/Makefile.objs|1 +
>  hw/can/can_sja1000.c| 1013 
> +++
>  hw/can/can_sja1000.h|  167 
>  4 files changed, 1182 insertions(+)
>  create mode 100644 hw/can/can_sja1000.c
>  create mode 100644 hw/can/can_sja1000.h
> 
> diff --git a/default-configs/pci.mak b/default-configs/pci.mak
> index bbe11887a1..979b649fe5 100644
> --- a/default-configs/pci.mak
> +++ b/default-configs/pci.mak
> @@ -32,6 +32,7 @@ CONFIG_SERIAL=y
>  CONFIG_SERIAL_ISA=y
>  CONFIG_SERIAL_PCI=y
>  CONFIG_CAN_CORE=y
> +CONFIG_CAN_SJA1000=y
>  CONFIG_IPACK=y
>  CONFIG_WDT_IB6300ESB=y
>  CONFIG_PCI_TESTDEV=y
> diff --git a/hw/can/Makefile.objs b/hw/can/Makefile.objs
> index f999085f7a..3c4bf3bfc1 100644
> --- a/hw/can/Makefile.objs
> +++ b/hw/can/Makefile.objs
> @@ -7,4 +7,5 @@ common-obj-y += can_socketcan.o
>  else
>  common-obj-y += can_host_stub.o
>  endif
> +common-obj-$(CONFIG_CAN_SJA1000) += can_sja1000.o
>  endif
> diff --git a/hw/can/can_sja1000.c b/hw/can/can_sja1000.c
> new file mode 100644
> index 00..7f7a6ea244
> --- /dev/null
> +++ b/hw/can/can_sja1000.c
> @@ -0,0 +1,1013 @@
> +/*
> + * CAN device - SJA1000 chip emulation for QEMU
> + *
> + * Copyright (c) 2013-2014 Jin Yang
> + * Copyright (c) 2014-2018 Pavel Pisa
> + *
> + * Initial development supported by Google GSoC 2013 from RTEMS project slot
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a 
> copy
> + * of this software and associated documentation files (the "Software"), to 
> deal
> + * in the Software without restriction, including without limitation the 
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "chardev/char.h"
> +#include "hw/hw.h"
> +#include "can/can_emu.h"
> +
> +#include "can_sja1000.h"
> +
> +#ifndef DEBUG_FILTER
> +#define DEBUG_FILTER 0
> +#endif /*DEBUG_FILTER*/
> +
> +#ifndef DEBUG_CAN
> +#define DEBUG_CAN 0
> +#endif /*DEBUG_CAN*/
> +
> +#define DPRINTF(fmt, ...) \
> +do { \
> +if (DEBUG_CAN) { \
> +qemu_log("[cansja]: " fmt , ## __VA_ARGS__); \
> +} \
> +} while (0)
> +
> +static void can_sja_software_reset(CanSJA1000State *s)
> +{
> +s->mode&= ~0x31;
> +s->mode|= 0x01;
> +s->status_pel  &= ~0x37;
> +s->status_pel  |= 0x34;
> +
> +s->rxbuf_start = 0x00;
> +s->rxmsg_cnt   = 0x00;
> +s->rx_cnt  = 0x00;
> +}
> +
> +void can_sja_hardware_reset(CanSJA1000State *s)
> +{
> +/* Reset by hardware, p10 */
> +s->mode= 0x01;
> +s->status_pel  = 0x3c;
> +s->interrupt_pel = 0x00;
> +s->clock   = 0x00;
> +s->rxbuf_start = 0x00;
> +s->rxmsg_cnt   = 0x00;
> +s->rx_cnt  = 0x00;
> +
> +s->control = 0x01;
> +s->status_bas  = 0x0c;
> +s->interrupt_bas = 0x00;
> +
> +s->irq_lower(s->irq_opaque);
> +}
> +
> +static
> +void can_sja_single_filter(struct qemu_can_filter *filter,
> +const uint8_t *acr,  const uint8_t *amr, int extended)
> +{
> +if (extended) {
> +filter->can_id = (uint32_t)acr[0] << 21;
> +filter->can_id |= (uint32_t)acr[1] << 13;
> +filter->can_id |= (uint32_t)acr[2] << 5;
> +filter->can_id |= (uint32_t)acr[3] >> 3;
> +if (acr[3] & 4) {
> +filter->can_id |= QEMU_CAN_RTR_FLAG;
> +}

I hope we inline that later...

> +
> +filter->can_mask = (uint32_t)amr[0] << 21;
> +filter->can_mask |= (uint32_t)amr[1] << 13;
> +filter->can_mask |= (uint32_t)amr[2] << 5;
> +   

[Qemu-devel] [PATCH V4 3/7] CAN bus SJA1000 chip register level emulation for QEMU

2018-01-14 Thread pisa
From: Pavel Pisa 

The core SJA1000 support is independent of following
patches which map SJA1000 chip to PCI boards.

The work is based on Jin Yang GSoC 2013 work funded
by Google and mentored in frame of RTEMS project GSoC
slot donated to QEMU.

Rewritten for QEMU-2.0+ versions and architecture cleanup
by Pavel Pisa (Czech Technical University in Prague).

Signed-off-by: Pavel Pisa 
---
 default-configs/pci.mak |1 +
 hw/can/Makefile.objs|1 +
 hw/can/can_sja1000.c| 1013 +++
 hw/can/can_sja1000.h|  167 
 4 files changed, 1182 insertions(+)
 create mode 100644 hw/can/can_sja1000.c
 create mode 100644 hw/can/can_sja1000.h

diff --git a/default-configs/pci.mak b/default-configs/pci.mak
index bbe11887a1..979b649fe5 100644
--- a/default-configs/pci.mak
+++ b/default-configs/pci.mak
@@ -32,6 +32,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_ISA=y
 CONFIG_SERIAL_PCI=y
 CONFIG_CAN_CORE=y
+CONFIG_CAN_SJA1000=y
 CONFIG_IPACK=y
 CONFIG_WDT_IB6300ESB=y
 CONFIG_PCI_TESTDEV=y
diff --git a/hw/can/Makefile.objs b/hw/can/Makefile.objs
index f999085f7a..3c4bf3bfc1 100644
--- a/hw/can/Makefile.objs
+++ b/hw/can/Makefile.objs
@@ -7,4 +7,5 @@ common-obj-y += can_socketcan.o
 else
 common-obj-y += can_host_stub.o
 endif
+common-obj-$(CONFIG_CAN_SJA1000) += can_sja1000.o
 endif
diff --git a/hw/can/can_sja1000.c b/hw/can/can_sja1000.c
new file mode 100644
index 00..7f7a6ea244
--- /dev/null
+++ b/hw/can/can_sja1000.c
@@ -0,0 +1,1013 @@
+/*
+ * CAN device - SJA1000 chip emulation for QEMU
+ *
+ * Copyright (c) 2013-2014 Jin Yang
+ * Copyright (c) 2014-2018 Pavel Pisa
+ *
+ * Initial development supported by Google GSoC 2013 from RTEMS project slot
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "chardev/char.h"
+#include "hw/hw.h"
+#include "can/can_emu.h"
+
+#include "can_sja1000.h"
+
+#ifndef DEBUG_FILTER
+#define DEBUG_FILTER 0
+#endif /*DEBUG_FILTER*/
+
+#ifndef DEBUG_CAN
+#define DEBUG_CAN 0
+#endif /*DEBUG_CAN*/
+
+#define DPRINTF(fmt, ...) \
+do { \
+if (DEBUG_CAN) { \
+qemu_log("[cansja]: " fmt , ## __VA_ARGS__); \
+} \
+} while (0)
+
+static void can_sja_software_reset(CanSJA1000State *s)
+{
+s->mode&= ~0x31;
+s->mode|= 0x01;
+s->status_pel  &= ~0x37;
+s->status_pel  |= 0x34;
+
+s->rxbuf_start = 0x00;
+s->rxmsg_cnt   = 0x00;
+s->rx_cnt  = 0x00;
+}
+
+void can_sja_hardware_reset(CanSJA1000State *s)
+{
+/* Reset by hardware, p10 */
+s->mode= 0x01;
+s->status_pel  = 0x3c;
+s->interrupt_pel = 0x00;
+s->clock   = 0x00;
+s->rxbuf_start = 0x00;
+s->rxmsg_cnt   = 0x00;
+s->rx_cnt  = 0x00;
+
+s->control = 0x01;
+s->status_bas  = 0x0c;
+s->interrupt_bas = 0x00;
+
+s->irq_lower(s->irq_opaque);
+}
+
+static
+void can_sja_single_filter(struct qemu_can_filter *filter,
+const uint8_t *acr,  const uint8_t *amr, int extended)
+{
+if (extended) {
+filter->can_id = (uint32_t)acr[0] << 21;
+filter->can_id |= (uint32_t)acr[1] << 13;
+filter->can_id |= (uint32_t)acr[2] << 5;
+filter->can_id |= (uint32_t)acr[3] >> 3;
+if (acr[3] & 4) {
+filter->can_id |= QEMU_CAN_RTR_FLAG;
+}
+
+filter->can_mask = (uint32_t)amr[0] << 21;
+filter->can_mask |= (uint32_t)amr[1] << 13;
+filter->can_mask |= (uint32_t)amr[2] << 5;
+filter->can_mask |= (uint32_t)amr[3] >> 3;
+filter->can_mask = ~filter->can_mask & QEMU_CAN_EFF_MASK;
+if (!(amr[3] & 4)) {
+filter->can_mask |= QEMU_CAN_RTR_FLAG;
+}
+} else {
+filter->can_id = (uint32_t)acr[0] << 3;
+filter->can_id |= (uint32_t)acr[1] >> 5;
+if (acr[1] & 0x10) {
+filter->can_id |=