{"id":19713352,"url":"https://github.com/corellium/coremodel","last_synced_at":"2025-02-27T15:54:38.568Z","repository":{"id":194299145,"uuid":"690573930","full_name":"corellium/coremodel","owner":"corellium","description":"The CoreModel API provides over-the-internet support to attach remote peripheral models to a Virtual Machine(VM) bus interfaces. There are multiple standard device interfaces supported including UART, I2C, SPI, CAN, GPIO, and USB Host.","archived":false,"fork":false,"pushed_at":"2023-10-05T02:05:44.000Z","size":43,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-10T14:50:23.698Z","etag":null,"topics":["api","coremodel"],"latest_commit_sha":null,"homepage":"https://www.corellium.com","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/corellium.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-12T13:06:22.000Z","updated_at":"2024-11-20T01:06:30.000Z","dependencies_parsed_at":"2023-09-12T19:46:11.527Z","dependency_job_id":"1bab9b6d-04b7-4001-a5ac-49d8862f6a93","html_url":"https://github.com/corellium/coremodel","commit_stats":null,"previous_names":["corellium/coremodel"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/corellium%2Fcoremodel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/corellium%2Fcoremodel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/corellium%2Fcoremodel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/corellium%2Fcoremodel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/corellium","download_url":"https://codeload.github.com/corellium/coremodel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241031922,"owners_count":19897382,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","coremodel"],"created_at":"2024-11-11T22:21:12.184Z","updated_at":"2025-02-27T15:54:38.546Z","avatar_url":"https://github.com/corellium.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CoreModel\n\nThe CoreModel API provides over-the-internet support to attach remote peripheral models to a virtual Machine(VM) bus interfaces.\nThere are multiple standard device interfaces supported including UART, I2C, SPI, CAN, GPIO, and USB Host.\n\n```\n  -------------     ------------     -------------------\n  | CoreModel | \u003c-\u003e | Internet | \u003c-\u003e | Virtual Machine |\n  -------------     ------------     -------------------\n```\n\n## Supported Devices\n\nNot all machine types support CoreModel API interface as they were built before CoreModel was implemented.\nThe following machines have been updated for CoreModel support.\n \n| Interface | I.MX93 | I.MX8 | RPI4B |\n| :-------: | :----: | :---: | :---: |\n| GPIO      | x      | x     | x     |\n| UART      | x      | x     | x     |\n| I2C       | x      | x     | x     |\n| SPI       | x      | x     | x     |\n| CAN       | x      | x     |       |\n| USBH      |        |       | x     |\n\nNew machine types will support CoreModel API interface.\n\n## General CoreModel Connection and Control\n\nThese API's and helper functions provide simple way to connect and interact with a VMs bus interfaces.\n\n\n### Connection\n\nThe coremodel_connect/disconnect functions provide a standard way to connect and disconnect over the network to the VM.\nThe `coremodel_connect` function takes a `\u003ctarget\u003e` string formatted as `\"ip:port\"` for example \"10.10.0.3:1900\" and returns 0 on success.\nThe IP to use with CoreModel is the services IP of the VM and the port is 1900. You can find the services IP in the Connect tab of the VM.\n\n```\n/* Connect to a VM. */\nint coremodel_connect(const char *target);\n\n/* Close connection to a VM. */\nvoid coremodel_disconnect(void);\n```\n\n### Main Loop\n\nThe `coremodel_mainloop` helper function provides a simple implementation of the device model main loop.\nPrimarily the main loop handles processing the connection send and receive between the device model and the VM interface.\n`coremodel_mainloop` takes the parameter `usec` setting how much time to spend in the loop. The value of `usec` is specified in microseconds and if set to -1 will run indefinitely.\nThe main loop will return an error flag of 0 on success. Helper function `coremodel_mainloop` wraps the usage of the file descriptor functions.\n\n```\nint coremodel_mainloop(long long usec);\n```\n\n### File Descriptor\n\nThe file descriptor functions set and process the read and write buffers of the attached device model.\n\n```\n/* Prepare fd_sets for select(2).\n *  nfds        current index of maximum fd in sets + 1\n *  readfds     readfds to update\n *  writefds    writefds to update\n * Returns new nfds.\n */\nint coremodel_preparefds(int nfds, fd_set *readfds, fd_set *writefds);\n\n/* Process fd_sets after select(2).\n *  readfds     readfds to process\n *  writefds    writefds to process\n * Returns error flag.\n */\nint coremodel_processfds(fd_set *readfds, fd_set *writefds);\n```\n\n### Detach Device\n\nDetach any device model by handle from the VM.\n\n```\n/*  handle      handle of UART/I2C/SPI/GPIO interface */\nvoid coremodel_detach(void *handle);\n```\n\n### Device List\n\nDevice list functions provide a way to enumerate available bus interfaces of the VM into an array and free that array.\nThe function `coremodel_list` returns an array of `coremodel_device_list_t` data structure and is terminated by the last element member `type` set to `COREMODEL_INVALID`.\n\n```\n/* Enumerates devices available in VM.\n * Returns invalid-terminated array of device structs. The array, as well as\n * names in it, is allocated by malloc(3). */\n#define COREMODEL_UART          0\n#define COREMODEL_I2C           1\n#define COREMODEL_SPI           2\n#define COREMODEL_GPIO          3\n#define COREMODEL_USBH          4\n#define COREMODEL_CAN           5\n#define COREMODEL_INVALID       (-1)\ntypedef struct {\n    int type; /* one of COREMODEL_* constants */\n    char *name; /* name used to attach to the device */\n    unsigned num; /* number of chip selects (SPI) or pins (GPIO) */\n} coremodel_device_list_t;\ncoremodel_device_list_t *coremodel_list(void);\n\n/* Frees a device list */\nvoid coremodel_free_list(coremodel_device_list_t *list);\n```\n\n\n### Attach Interface\n\nAll attach functions require a correct `\u003cname\u003e` be provided to generate a `handle` for the VMs interface. \nThe correct name can be retrieved from device list.\nA proper `\u003cfunc\u003e` data structure for the specific interface is required.\nAny attach function will return `NULL` on failure.\nIf the device model being attached to one of the interfaces does not need any independent state structure or specific value for operation then NULL can be provided to `\u003cpriv\u003e`.\n\n## UART\n\nThe CoreModel UART APIs provides the ability to attach a single device to any available virtual UART on the VM.\n\n### UART Data Structure\n\nThe following data structure represents required functions that need to be provided to `coremodel_attach_uart` for a device to interface with the VMs UART.\n\n```\ntypedef struct {\n    /* Called by CoreModel to transmit bytes. Return a \u003e0 number to accept as\n     * many bytes, or 0 to stall Tx interface (it will have to be un-stalled\n     * with coremodel_uart_txrdy). */\n    int (*tx)(void *priv, unsigned len, uint8_t *data);\n    /* Called by CoreModel to signal a BREAK condition on UART line. */\n    void (*brk)(void *priv);\n    /* Called by CoreModel to unstall Rx interface. */\n    void (*rxrdy)(void *priv);\n} coremodel_uart_func_t;\n```\n\nStub functions for `brk` and `rxrdy` can be provided if they are not required for the device model operation.\n\n### UART Attach\n\nAttach to a virtual UART and returns the handle.\n\n```\nvoid *coremodel_attach_uart(const char *name, const coremodel_uart_func_t *func, void *priv);\n```\n\n### UART RX\n\nAttempt to send data over the virtual UART.\n\n```\nint coremodel_uart_rx(void *uart, unsigned len, uint8_t *data);\n```\n\nProvide `\u003cuart\u003e` the attached handle of the UART interface.\nThe `\u003cdata\u003e` and `\u003clen\u003e` of the array to send to the interface.\nReturns a number \u003e0 of how many bytes were accepted if 0 then the interface is stalled. CoreModel will call `func-\u003erxrdy` to un-stall the device.\n\n\n### UART TX Ready\n\nUnstall a stalled Tx interface of the `\u003cuart\u003e` handle.\n\n```\nvoid coremodel_uart_txrdy(void *uart);\n```\n\n## I2C\n\nThe CoreModel I2C APIs provides the ability to attach multiple devices to any available virtual I2C bus on the VM. The virtual I2C bus supports a maximum of 128 devices.\n\n### I2C Data Structure\n\nThe data structure below is allocated and owned by the device model.\n\n```\ntypedef struct {\n    /* Called by CoreModel to notify of a START to a device; return -1 to NAK,\n     * 0 to stall, 1 to accept. A stalled interface will have to be un-stalled\n     * with coremodel_i2c_ready. */\n    int (*start)(void *priv);\n    /* Called by CoreModel to WRITE bytes. Return a \u003e0 number to accept as\n     * many bytes, -1 to NAK, or 0 to stall interface (it will have to be\n     * un-stalled with coremodel_i2c_ready). */\n    int (*write)(void *priv, unsigned len, uint8_t *data);\n    /* Called by CoreModel to READ bytes. Return a \u003e0 number to produce as\n     * many bytes, or 0 to stall interface (it will have to be un-stalled\n     * with coremodel_i2c_ready). */\n    int (*read)(void *priv, unsigned len, uint8_t *data);\n    /* Called by CoreModel to notify of a STOP to a device. */\n    void (*stop)(void *priv);\n} coremodel_i2c_func_t;\n```\n\n### I2C Attach\n\nThe virtual I2C bus only supports 7-bit addresses that are defined `\u003caddr\u003e` when the device is attached.\nDepending on the VM there could already be other devices on the bus and those addresses can not be used.\n`\u003cflags\u003e` can be set to notify the master of non standard behavior of the device. \n\n```\n#define COREMODEL_I2C_START_ACK 0x0001  /* device must ACK all starts */\n#define COREMODEL_I2C_WRITE_ACK 0x0002  /* device must ACK all writes */\n\nvoid *coremodel_attach_i2c(const char *name, uint8_t addr, const coremodel_i2c_func_t *func, void *priv, uint16_t flags);\n```\n\n### I2C Push Read\n\nProvide unsolicited data for lower access latency.\n\n```\nint coremodel_i2c_push_read(void *i2c, unsigned len, uint8_t *data);\n```\n\nPush unsolicited I2C READ `\u003cdata\u003e` of `\u003clen\u003e` in bytes to the `\u003ci2c\u003e` handle.\nReturns the number of accepted bytes by the host controller. \n\n### I2C Ready\n\nSignal CoreModel that the `\u003ci2c\u003e` handle of the interface is unstalled and can call `func-\u003estart/write/read` again. \n\n```\nvoid coremodel_i2c_ready(void *i2c);\n```\n\n\n## SPI\n\nThe CoreModel SPI APIs provides the ability to attach multiple devices to any available virtual SPI bus on the VM.\nThe maximum amount of devices the virtual SPI bus supports can be different between VMs or even instances of SPI masters.\nTo determine the maximum `\u003cnum\u003e` of supported devices for the bus use device list. [described above](#device-list)\n\n\n### SPI Data Structure\n\n```\ntypedef struct {\n    /* Called by CoreModel to notify of a CS pin change. */\n    void (*cs)(void *priv, unsigned csel);\n    /* Called by CoreModel to write and read bytes. Return a \u003e0 number to\n     * accept (and produce) as many bytes, or 0 to stall interface (it will\n     * have to be un-stalled with coremodel_spi_ready). */\n    int (*xfr)(void *priv, unsigned len, uint8_t *wrdata, uint8_t *rddata);\n} coremodel_spi_func_t;\n```\n\n### SPI Attach\n\nAttach a device to the VMs virtual SPI bus. Since multiple devices can be attached to the same SPI interface the chip select index `\u003ccsel\u003e` must be \u003e= 0 and \u003c `\u003cnum\u003e` max devices.\nVMs could have devices already on the SPI bus and their chip select index can not be used as they are hardwired inside the VM.\n`\u003cflags\u003e` can be set to notify the master of non standard behavior of the device. \n\n```\n#define COREMODEL_SPI_BLOCK     0x0001  /* device must handle \u003e1 byte transfers */\n\nvoid *coremodel_attach_spi(const char *name, unsigned csel, const coremodel_spi_func_t *func, void *priv, uint16_t flags);\n```\n\n### SPI Ready\n\nNotify CoreModel that the `\u003cspi\u003e` handle of the interface is unstalled and can call `func-\u003exfr` again. \n\n```\nvoid coremodel_spi_ready(void *spi);\n```\n\n## CAN Bus\n\nThe CoreModel CAN APIs provides the ability to interface multiple devices to any available virtual CAN bus on the VM.\n\n### CAN Data Structure\n\n```\n#define CAN_CTRL_ID_MASK        (0x7FFul \u003c\u003c 29)\n#define  CAN_CTRL_ID_SHIFT      29\n#define CAN_CTRL_RTR            (1ul \u003c\u003c 28)\n#define CAN_CTRL_IDE            (1ul \u003c\u003c 27)\n#define CAN_CTRL_EID_MASK       (0x3FFFFul \u003c\u003c 9)\n#define  CAN_CTRL_EID_SHIFT     9\n#define CAN_CTRL_ERTR           (1ul \u003c\u003c 8)\n#define CAN_CTRL_EDL            (1ul \u003c\u003c 7)\n#define CAN_CTRL_BRS            (1ul \u003c\u003c 5)\n#define CAN_CTRL_ESI            (1ul \u003c\u003c 4)\n#define CAN_CTRL_DLC_MASK       15ul\n#define  CAN_CTRL_DLC_SHIFT     0\n\n#define CAN_ACK                 0\n#define CAN_NAK                 1\n#define CAN_STALL               (-1)\ntypedef struct {\n    int (*tx)(void *priv, uint64_t ctrl, uint8_t *data); /* return one of CAN_ACK, CAN_NAK, CAN_STALL */\n    void (*rxcomplete)(void *priv, int nak);\n} coremodel_can_func_t;\n```\n\n### CAN Attach\n\nAttach a device to a virtual CAN bus.\n\n```\nvoid *coremodel_attach_can(const char *name, const coremodel_can_func_t *func, void *priv);\n```\n\n### CAN RX\n\nSend CAN packet over the virtual `\u003ccan\u003e` interface. The `\u003cdata\u003e` portion of the packet is optional if control word `\u003cctrl\u003e` DLC != 0.\n`coremodel_can_rx` returns 0 on success if the bus is not available 1 will be returned.\n\n```\nint coremodel_can_rx(void *can, uint64_t ctrl, uint8_t *data);\n```\n\n### CAN Ready\n\nUnstall the stalled virtual interface `\u003ccan\u003e` signaling CoreModel that `func-\u003etx` can be called once again.\n\n```\nvoid coremodel_can_ready(void *can);\n```\n\n## GPIO\n\nThe CoreModel GPIO APIs provides the ability to interact with the VMs GPIO pins logical or voltage values.\nCaution should be taken when manipulating GPIO pins that are already being used internally by the VM as this could cause undefined behavior.\nThe count of GPIO pins can be determined using device list. [described above](#device-list) \n\n### GPIO Notify Structure\n\n```\ntypedef struct {\n    /* Called by CoreModel to update voltage on a GPIO pin. */\n    void (*notify)(void *priv, int mvolt);\n} coremodel_gpio_func_t;\n```\n\n### GPIO Attach\n\nAttach to a specified `\u003cpin\u003e` index in the bank of GPIO pins.\n\n```\nvoid *coremodel_attach_gpio(const char *name, unsigned pin, const coremodel_gpio_func_t *func, void *priv);\n```\n\n### GPIO Set\n\nSet a tri-state driver on a GPIO `\u003cpin\u003e` interface, enabling or disabling the `\u003cdrven\u003e` `\u003cmvolt\u003e` value in millivolts.\n\n```\nvoid coremodel_gpio_set(void *pin, unsigned drven, int mvolt);\n```\n\n## USB Host\n\nThe CoreModel USBH APIs provides the ability to interface multiple devices to any available virtual USB Bus.\n\n### USBH Data Structure\n\n```\n/* USB Host (connect a local USB Device to a Host inside VM) */\n\n#define USB_TKN_OUT             0\n#define USB_TKN_IN              1\n#define USB_TKN_SETUP           2\n#define USB_XFR_NAK             (-1)\n#define USB_XFR_STALL           (-2)\ntypedef struct {\n    /* Called by CoreModel on USB bus reset. */\n    void (*rst)(void *priv);\n    /* Called by CoreModel to perform a USB transfer. Return a \u003e0 number to\n     * accept / produce as many bytes, or USB_XFR_NAK to pause interface, or\n     * USB_XFR_STALL to stall interface (create error condition). A paused\n     * interface will have to be un-paused with coremodel_usbh_ready. */\n    int (*xfr)(void *priv, uint8_t dev, uint8_t ep, uint8_t tkn, uint8_t *buf, unsigned size, uint8_t end);\n} coremodel_usbh_func_t;\n```\n\n### USBH Attach\n\nAttach to a virtual USB host `\u003cport\u003e` index at a requested connection `\u003cspeed\u003e`.\nVMs could have devices already on the USB bus and the port index those device are attached to should not be used as they are hardwired inside the VM.\n\n```\n#define USB_SPEED_LOW           0\n#define USB_SPEED_FULL          1\n#define USB_SPEED_HIGH          2\n#define USB_SPEED_SUPER         3\nvoid *coremodel_attach_usbh(const char *name, unsigned port, const coremodel_usbh_func_t *func, void *priv, unsigned speed);\n```\n\n### USBH Ready\n\nUnstall a stalled virtual USB interface end point `\u003cep\u003e` with the token `\u003ctkn\u003e`  notifying CoreModel can call `func-\u003exfr` once again.\n\n```\nvoid coremodel_usbh_ready(void *usb, uint8_t ep, uint8_t tkn);\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcorellium%2Fcoremodel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcorellium%2Fcoremodel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcorellium%2Fcoremodel/lists"}