üApp: picar-s: perform i2c-bcm2708 I/O accesses via uobjcoll

This task will refactor i2c-bcm2708 low-level I2C driver to perform I/O accesses via uobjcoll.
The following are the proposed sub-tasks:

  1. We will be working with forks and respective branches of the following repositories:

    • uberspark/uberxmhf.git on branch develop
    • uberspark/uberspark.git on branch develop
    • uberspark/uobjcoll-raspberrypi-linux-i2c-bcm2835.git on branch uobjcoll-4.4.y

    Ensure the aforementioned forks/branches are upto date with the upstream repositories. The following gives an example of how to sync your fork of uberspark/uberxmhf.git; the same can be applied to other repositories. Note these commands have to be applied on a local checkout of your fork.

    git remote add upstream https://github.com/uberspark/uberxmhf.git
    git fetch -a upstream
    git checkout develop 
    git pull upstream develop 
    git push origin develop
  2. Build and install micro-hypervisor and I2C drivers (i2c-dev and i2c-bcm2708) from the above forks/branches and ensure baseline line-following functionality works.

  3. within your fork of uberspark/uberxmhf.git make a feature branch off of develop.
    Let us call it feature-uapp-i2c-ioaccess.

  4. copy uxmhf-rpi3/uobjcoll/uobjs/main/include/uhcalltest.h to uxmhf-rpi3/uobjcoll/uobjs/main/include/i2c-ioaccess.h. Revise uxmhf-rpi3/uobjcoll/uobjs/main/include/i2c-ioaccess.h to change UHCALLTEST definitions to I2C_IOACCESS.

  5. copy uxmhf-rpi3/uobjcoll/uobjs/main/uapps/uapp-uhcalltest.c to uxmhf-rpi3/uobjcoll/uobjs/main/uapps/uapp-i2c-ioaccess.c. Revise uxmhf-rpi3/uobjcoll/uobjs/main/uapps/uapp-i2c-ioaccess.c to change uhcalltest/UHCALLTEST definitions to i2c_ioaccess/I2C_IOACCESS. Remove the snippet below within the handlehcall function:

    #if 1
       _XDPRINTFSMP_("dumping in[]...\n");
       for(i=0; i < 16; i++)
        _XDPRINTFSMP_("%c", uhctp->in[i]);
       _XDPRINTFSMP_("\ndumped uhctp->in[]\n");
    uberspark_uobjrtl_crt__memcpy(&uhctp->out, &uhctp->in, 16);
    #if 1
    _XDPRINTFSMP_("dumping out[]...\n");
    for(i=0; i < 16; i++)
        _XDPRINTFSMP_("%c", uhctp->out[i]);
    _XDPRINTFSMP_("\ndumped uhctp->out[]\n");
  6. Edit uxmhf-rpi3/uobjcoll/uobjs/main/uberspark.json and add "include/uapp-i2c-ioaccess.h" to "uberspark.uobj.headers"; add "uapps/uapp-i2c-ioaccess.c" to "uberspark.uobj.sources"

  7. Edit uxmhf-rpi3/uobjcoll/uberspark.json and add { "name": "enable_uapp_i2c_ioaccess", "value": "@@TRUE@@"} to "uberspark.uobjcoll.configdefs"

  8. Edit function guest_hypercall_handler within uxmhf-rpi3/uobjcoll/uobjs/main/core/ghcall.c and add the following snippet to hook in the i2c-ioaccess uapp hypercall handler:

    if( uapp_i2c_ioaccess_handlehcall(r->r0, r->r1, r->r2) )
  9. Switch to your fork of uberspark/uobjcoll-raspberrypi-linux-i2c-bcm2835.git on branch uobjcoll-4.4.y

  10. Revise i2c_bcm2708 module Makefile to provide access to micro-hypervisor header files and the khcall library (libkhcall) for linking. See: üApp: picar-s: uobjcoll for i2c-driver on how this was done for the i2c-dev kernel module and replicate.

  11. Add the following function definition to i2c_bcm2708.c:

      static void khcall_fast_hvc(uint32_t khcall_function, uint32_t param1, uint32_t param2) { 
        asm volatile
        ( " mov r0, %[in_0]\r\n"
          " mov r1, %[in_1]\r\n"
          " mov r2, %[in_2]\r\n"
          ".long 0xE1400070 \r\n"
            : [in_0] "r" (khcall_function), [in_1] "r" (param1), [in_2] "r" (param2)
            : "r0", "r1", "r2" ); }
  12. Add khcall_fast_hvc(0, 0, 0); to bcm2708_rd and bcm2708_wr functions.

  13. Rebuild kernel and/or kernel-module

  14. Rebuild the micro-hypervisor

  15. Test line-following functionality of picar-s; should work as before.

Of course, the aforementioned sub-tasks might need slight tweaking as we go through them.

Linked PRs:


I went up to step 10.
Aren’t we missing the actual logic of the hypercall.

The following code has to go in the hypervisor I am guessing:

/* Our implementation of readl() and writel() functions */
#define __u_raw_writel __u_raw_writel
static inline void __u_raw_writel(u32 val, volatile void __iomem addr)
asm volatile(“str %1, %0”
: : “Qo” (
(volatile u32 __force *)addr), “r” (val));

#define u_writel_relaxed(v,c) __u_raw_writel((__force u32) cpu_to_le32(v),c)
#define u_writel(v,c) ({ __iowmb(); u_writel_relaxed(v,c); })

#define __u_raw_readl __u_raw_readl
static inline u32 __u_raw_readl(const volatile void __iomem addr)
u32 val;
asm volatile(“ldr %0, %1”
: “=r” (val)
: “Qo” (
(volatile u32 __force *)addr));
return val;

#define u_readl_relaxed© ({ u32 __r = le32_to_cpu((__force __le32)
__u_raw_readl©); __r; })
#define u_readl© ({ u32 __v = u_readl_relaxed©; __iormb(); __v; })

It is intentional for the first try :). I would like to first get a baseline with the fast-khcall to see if we can handle the frequency of such NULL invocations for our mission…

ok, I was able to build it fine to step 13.

So do steps 14 and 15 work? Does the car still follow the line with the NULL hypercalls?

Yes, it worked with the changes. No issues at all.

Nice :slight_smile:

Can you share your branches so I can take a look and plot our next steps?


Pushed the changes for the hypervisor in branch feature-uapp-i2c-ioaccess of https://github.com/antonhristozov/uberxmhf.git

I have a problem submitting my changes to the Linux kernel repository branch i2c-io-protection:

(base) anton@anton-Precision-7720:~/uberwork/uobjcoll-raspberrypi-linux-i2c-bcm2835/drivers/i2c/busses$ git push
Username for ‘https://github.com’: antonhristozov
Password for ‘https://antonhristozov@github.com’:
remote: Permission to uberspark/uobjcoll-raspberrypi-linux-i2c-bcm2835.git denied to antonhristozov.
fatal: unable to access ‘https://github.com/uberspark/uobjcoll-raspberrypi-linux-i2c-bcm2835/’: The requested URL returned error: 403

Did something change there?
I was able to submit changes up until today.

Yes, you will have to fork that repository and move your branch to the fork. This is so that we can follow the same PR workflow on that repo.


But this worked so far. Was this changed to follow the same model ?

Yes, correct. This helps us have a unified model of introducing changes into all our source repositories. It also helps avoid unecessary management of remote branches (except for develop and uobjcoll) on the upstream repos.

ok, I am already building the fork and will put my changes soon.

1 Like

Pushed my changes in branch i2c-io-protection as part of my fork:

Can you please give me access to the respective branches on your forks of uberxmhf.git and uobjcoll-raspberrypi-linux-i2c-bcm2835.git ?

I would like to push a changeset for you to test and am currently getting permission denied.


Push to your fork of uberxmhf.git works, still getting denied error for the other one. Can you pease check when you get a chance? Thanks!

I did just gave you access.

It says awating response from you.

Ok it works now. I have pushed in my changes to the following:

  1. your fork of uberxmhf.git on branch feature-uapp-i2c-ioaccess
  2. your fork of uobjcoll-raspberrypi-linux-i2c-bcm2835.git on branch i2c-io-protection

Please pull the latest changes, rebuild the micro-hypervisor, libkhcall, and the drivers and give the line-following functionality a whirl.


Do I need to rebuild libkhcall.a and the uhcallkmod manually ?
They have their own build.sh scripts.
Or do I need just the hypervisor rebuilt?