summaryrefslogtreecommitdiff
path: root/docs/zephyr_shim.md
blob: 900bc1775dea5b832b8681abb779469d49abd795 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
[TOC]

# Objective

Allow a subset of the platform/ec code to be built as part of the Zephyr-based
EC without needing to land code into upstream zephyr, or our zephyr-chrome
repository.

# Background

Now that Google has joined [Zephyr OS](https://www.zephyrproject.org/), the EC
team is moving toward it instead of platform/ec code on embedded controllers for
future Chrome OS devices. See the
[originally proposed idea](https://goto.google.com/cros-ec-rtos) and a more
specific [Zephyr process doc](https://goto.google.com/zephyr-structure) of what
future development on Zephyr will look like.

Simply put, we want to move to Zephyr OS to use an open-source embedded OS that
has a vibrant community. The embedded OS scene for the industry is very
fragmented, with various parties using their own custom solution. We see the
strong open-source community at Zephyr as potentially helping to consolidate
efforts in the embedded controller space. It will also benefit our partners
(both chip vendors and OEMs) since they should only have to support one embedded
OS (i.e., Zephyr) for both their Chrome OS and Windows based devices.

Migrating to use Zephyr fully is going to take a few years. We do not want to
diverge from the active development happening on platform/ec code. We
potentially want to ship a product using Zephyr before the migration is
complete.

# Design ideas

In order to reuse `platform/ec` development , we shim "active" `platform/ec`
code as a
[Zephyr Module](https://docs.zephyrproject.org/latest/guides/modules.html). This
requires us to add some Zephyr specific code in a `zephyr` directory in the
`platform/ec` codebase. Once we release a Zephyr-based EC, then we can turn down
platform/ec for future development and work on migrating the platform/ec-module
code out of the module directory and into a first-class Zephyr code format -- in
the local
[Chrome Zephyr repo](https://chromium.googlesource.com/chromiumos/platform/zephyr-chrome/+/refs/heads/master)
and ultimately [upstream](https://github.com/zephyrproject-rtos/zephyr).

For platform/ec code that is stable and not under active development, the Zephyr
team may port that code to Zephyr, thus skipping the shimming process.

## Subsystems of interest

### With Shim

We shim the following subsystems (non-exhaustive).

*   USB-C: TCPC, PPC, MUX, TCPMv2
*   Charge Manager
*   SoC Power Sequencing
*   Sensors, if Intel’s HID-based solution is delayed in getting to Zephyr
    upstream

### Little-to-No Shim

We adopt upstream Zephyr or skip the shimming process (non-exhaustive).

*   CBI and dependent EEPROM code
    *   The format is stable. We pull in the list of CBI tags from platform/ec
        though
*   EFS2, Vboot, RO/RW split
    *   Adjusting flash layout would be difficult to shim, and the concept is
        very stable.
    *   We may shim some core EFS2 logic
*   Host command framework
*   Sensors, if Intel’s HID-based solution getts to Zephyr upstream and passes
    CTS
*   Keyboard and keycode scanning support
    *   We may shim the newer Vivaldi feature.
*   Console support
    *   We allow individual console commands via DECLARE\_CONSOLE\_COMMAND to be
        shimmed to Zephyr. These convert commands to work with Zephyr's shell
        subsystem.
*   I2C

## New content in platform/ec

Add the `src/platform/ec/zephyr` folder with:

*   [Module integration files](https://docs.zephyrproject.org/latest/guides/modules.html#build-system-integration),
    e.g., module.yml, CMakeLists.txt, and KConfig.
    *   **module.yml** is the required entry point (must be located at
        _zephyr/module.yml_ in the repository) for Zephyr modules, and declares
        the location of Kconfig and CMakeLists.txt files used by the Zephyr
        build system.
    *   **CMakeLists.txt** replicates build logic for the files being shimmed,
        outside of the platform/ec Makefile.
    *   **Kconfig** will declare any CONFIG\_\* options which are important to
        expose from platform/ec code to the Zephyr build.
*   Shim code to translate platform/ec code into Zephyr code
    *   For example, redefine platform/ec’s
        [`DECLARE_HOST_COMMAND`](https://source.chromium.org/chromiumos/chromiumos/codesearch/+/master:src/platform/ec/include/host_command.h;l=256;drc=514923bc59f5a3435dbb7cbf348735ed41889ffe)
        to map to Zephyr's upstream
        [`EC_HOST_CMD_HANDLER`](https://github.com/zephyrproject-rtos/zephyr/blob/d7468bf836b75c29980441f294a61eae6bf4bc75/include/ec_host_cmd.h#L73)
        macro. This allows us to compile select platform/ec files in the Zephyr
        build.

## Namespace Collisions

One significant issue of mixing Zephyr headers with our existing EC code is that
we currently have many names colliding with the Zephyr code. For example,
Zephyr's atomic functions also are named `atomic_add`, `atomic_or`, ...,
however, have a different API from our EC's atomic functions. This is critical,
since atomic operations are often used in `static inline` functions placed in
header files.

In some cases, we are able to hack around these collisions by creating macros
and functions which are compatible with both Zephyr and our EC's usages. For
example, we can create a modified `IS_ENABLED` which accepts both defined to
nothing usages (CrOS EC `config.h` style), and defined to `1` usages (Zephyr
Kconfig style).

However, long term, we may find this to be a continual cause of issues, and
creating hacks for every colliding macro or function may be unsustainable. We
propose _gradually_ introducing a namespace prefix to the `platform/ec`
codebase, for example `crec_`. We can begin at the critical areas of namespace
collision (e.g., atomics) and continue to improve the naming convention with
time.

## New CQ check

As long as code from platform/ec is part of the zephyr
[ebuild](http://cs/chromeos_public/src/third_party/chromiumos-overlay/chromeos-base/chromeos-zephyr-2_3/chromeos-zephyr-2_3-9999.ebuild),
then we need to run the Zephyr CQ checks on any platform/ec CLs in addition to
the normal platform/ec CQ checks. This ensures that platform/ec changes aren’t
breaking the Zephyr builds and requiring the Zephyr team to debug recent
changes.

For local builds, we can run `emerge-betty chromeos-zephyr-2_3` or `zmake`
utility to check that an EC CL has not broken anything on the Zephyr side.

We will work with the CI team to enable this.

# Alternatives Considered

## Translate code and mirror into the zephyr-chrome repository

We could potentially write a script which, via a series of find/replace
operations, translates a platform/ec module to use Zephyr functions, macros, and
paradigms. On a frequent basis, we would translate all modules of interest in
the platform/ec repository and land an "uprev" change in the zephyr-chrome
repository.

The main disadvantage of this technique is that we can't get any CQ coverage
when platform/ec CLs land that the modules will continue to work in Zephyr.
Additionally, the translator script would be delicate and probably require
frequent maintenance.

However, this technique does have some benefits. With modules directly
translated to code in the Zephyr paradigm, the process of upstreaming a shimmed
module to ZephyrOS would be significantly easier. Additionally, it would require
no shim code in platform/ec.

## Don't do any code sharing

One option is to avoid shimming in any platform/ec code and allow the Zephyr
team to re-implement features in upstream zephyr, or our local zephyr-chrome
repository.

Disregarding the infeasible amount of work required to complete this option, the
platform/ec repository has a far faster development pace as there are many more
contributors, and the Zephyr features would quickly lose parity during the time
frame that we are launching both Zephyr-based and platform/ec-based devices.