Changes between Version 55 and Version 56 of Developer/Simulators/QEMU/CANEmulation


Ignore:
Timestamp:
Aug 16, 2013, 8:16:56 PM (6 years ago)
Author:
C Rempel
Comment:

/* qemu-char.c */

Legend:

Unmodified
Added
Removed
Modified
  • Developer/Simulators/QEMU/CANEmulation

    v55 v56  
    407407      { .name = "stdio",     .open = qemu_chr_open_stdio },
    408408
     409<!-- ==== hw/can-pci.c ====
     410
     411This adds the can-pci device
     412
     413Include the simulations for the bus (pci), device type (char), timer functions, and the address-spaces (for memory-mapped io?)
     414 @@ -0,0 +1,193 @@
     415 +#include "pci/pci.h"
     416 +#include "char/char.h"
     417 +#include "qemu/timer.h"
     418 +#include "exec/address-spaces.h"
     419
     420'''TODO:''' look up where these defines are from
     421 +#define PCI_MEM_SIZE                          16
     422 +#define PCI_DEVICE_ID_CANBUS          0xbeef
     423 +#define PCI_REVISION_ID_CANBUS                0x73
     424
     425
     426+typedef struct CanState {
     427+       /* Some registers ... */
     428+    qemu_irq irq;
     429+       void                    *mem_base;
     430+
     431+    CharDriverState *chr;
     432+    MemoryRegion       portio;
     433+    MemoryRegion       memio;
     434+} CanState;
     435+
     436+typedef struct PCICanState {
     437+    PCIDevice          dev;
     438+    CanState           state;
     439+} PCICanState;
     440+
     441+#define DEBUG_CAN
     442+#ifdef DEBUG_CAN
     443+#define DPRINTF(fmt, ...) \
     444+   do { fprintf(stderr, "[mycan]: " fmt , ## __VA_ARGS__); } while (0)
     445+#else
     446+#define DPRINTF(fmt, ...) \
     447+   do {} while (0)
     448+#endif
     449+
     450+
     451+const uint8_t whatever[] = "ttt";
     452+static void can_ioport_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
     453+{
     454+    CanState *s = opaque;
     455+    DPRINTF("write addr=0x%02x val=0x%02x\n", (unsigned int)addr, (unsigned int)val);
     456+       qemu_chr_fe_write(s->chr, whatever, 3); // write to the backends.
     457+}
     458+
     459+static uint64_t can_ioport_read(void *opaque, hwaddr addr, unsigned size)
     460+{
     461+       DPRINTF("%s-%s() called\n", __FILE__, __FUNCTION__);
     462+    return 0;
     463+}
     464+
     465+const MemoryRegionOps can_io_ops = {
     466+    .read              = can_ioport_read,
     467+    .write             = can_ioport_write,
     468+    .endianness = DEVICE_LITTLE_ENDIAN,
     469+    .impl              = {
     470+        .min_access_size = 1,
     471+        .max_access_size = 1,
     472+    },
     473+};
     474+
     475+static void can_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
     476+{
     477+    CanState                   *s = opaque;
     478+       void                            *pci_mem_addr;
     479+       int                             region_size;
     480+
     481+       pci_mem_addr = s->mem_base; 
     482+       pci_mem_addr = ((char *)pci_mem_addr) + addr; 
     483+       region_size  = (int)memory_region_size(&s->memio);
     484+       if(addr > region_size)
     485+               return ;
     486+
     487+       DPRINTF("write 0x%llx to %p\n", val, pci_mem_addr);
     488+       memcpy(pci_mem_addr, (void *)&val, size);       
     489+       DPRINTF("   pci_mem_addr 0x%llx\n", *(uint64_t *)pci_mem_addr);
     490+
     491+
     492+} 
     493+
     494+static uint64_t can_mem_read(void *opaque, hwaddr addr, unsigned size)
     495+{ 
     496+    CanState                   *s = opaque;
     497+       void                            *pci_mem_addr; 
     498+       int                             region_size;
     499+       unsigned int            temp;
     500+
     501+       pci_mem_addr = s->mem_base; 
     502+       pci_mem_addr = ((char *)pci_mem_addr) + addr; 
     503+       region_size  = memory_region_size(&s->memio);
     504+       if(addr > region_size) 
     505+               return 0;
     506+
     507+       memcpy(&temp, pci_mem_addr, size);
     508+       DPRINTF("read %d bytes of 0x%x from %p\n", size, temp, pci_mem_addr);
     509+
     510+       return temp;
     511+}
     512+
     513+static const MemoryRegionOps can_mem_ops = { 
     514+       .read           = can_mem_read, 
     515+       .write          = can_mem_write, 
     516+       .endianness = DEVICE_LITTLE_ENDIAN,
     517+    .impl              = {
     518+               // how many bytes can we read/write every time.
     519+        .min_access_size = 1,
     520+        .max_access_size = 16,
     521+    },
     522+};
     523+
     524+
     525+static int can_pci_init(PCIDevice *dev)
     526+{
     527+       // Get the address of PCICanState through PCIDevice.
     528+    PCICanState *pci = DO_UPCAST(PCICanState, dev, dev);
     529+    CanState *s = &pci->state;
     530+
     531+       DPRINTF("%s-%s() called\n", __FILE__, __FUNCTION__);
     532+       if (!s->chr) {
     533+        fprintf(stderr, "Can't create can device, empty char device\n");
     534+               exit(1);
     535+    }
     536+       
     537+       s->mem_base = g_malloc0(PCI_MEM_SIZE);
     538+
     539+    pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
     540+    s->irq = pci->dev.irq[0];
     541+
     542+
     543+       qemu_irq_lower(s->irq);
     544+       
     545+    memory_region_init_io(&s->portio, &can_io_ops, s, "can", 8);
     546+    memory_region_init_io(&s->memio, &can_mem_ops, s, "can", PCI_MEM_SIZE);
     547+    pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->portio);
     548+    pci_register_bar(&pci->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->memio);
     549+
     550+//    memory_region_add_subregion(system_io, base, &s->io);
     551+    return 0;
     552+}
     553+
     554+static void can_pci_exit(PCIDevice *dev)
     555+{
     556+    PCICanState *pci = DO_UPCAST(PCICanState, dev, dev);
     557+    CanState *s = &pci->state;
     558+
     559+    g_free(s->mem_base);
     560+    memory_region_destroy(&s->memio);
     561+    memory_region_destroy(&s->portio);
     562+}
     563+
     564+
     565+static const VMStateDescription vmstate_pci_can = {
     566+    .name = "pci-can",
     567+    .version_id = PCI_REVISION_ID_CANBUS,
     568+    .minimum_version_id = 1,
     569+    .fields      = (VMStateField[]) {
     570+        VMSTATE_PCI_DEVICE(dev, PCICanState),
     571+        VMSTATE_END_OF_LIST()
     572+    }
     573+};
     574+
     575+static Property can_pci_properties[] = {
     576+    DEFINE_PROP_CHR("chardev",  PCICanState, state.chr),
     577+    DEFINE_PROP_END_OF_LIST(),
     578+};
     579+
     580+static void can_pci_class_initfn(ObjectClass *klass, void *data)
     581+{
     582+    DeviceClass *dc = DEVICE_CLASS(klass);
     583+    PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
     584+       
     585+    pc->init = can_pci_init;
     586+    pc->exit = can_pci_exit;
     587+    pc->vendor_id = PCI_VENDOR_ID_REDHAT; // 0x1b36
     588+    pc->device_id = PCI_DEVICE_ID_CANBUS;
     589+    pc->revision = PCI_REVISION_ID_CANBUS;
     590+    pc->class_id = PCI_CLASS_OTHERS;
     591+
     592+    dc->desc = "PCI CAN SJA1000";
     593+    dc->vmsd = &vmstate_pci_can;
     594+    dc->props = can_pci_properties;
     595+}
     596+
     597+static const TypeInfo can_pci_info = {
     598+    .name          = "pci-can",
     599+    .parent        = TYPE_PCI_DEVICE,
     600+    .instance_size = sizeof(PCICanState),
     601+    .class_init    = can_pci_class_initfn,
     602+};
     603+
     604+static void can_pci_register_types(void)
     605+{
     606+    type_register_static(&can_pci_info);
     607+}
     608+
     609+type_init(can_pci_register_types)
     610-->
    409611The above is an OLD one. You can get some newer update at [http://jin-yang.github.io/2013/07/24/build-minimal-linux-environment.html JinYang's Blog].
    410612=  Running the Example  =