firmware merge requestshttps://git.flow3r.garden/card10/firmware/-/merge_requests2019-08-15T23:06:58Zhttps://git.flow3r.garden/card10/firmware/-/merge_requests/96Changes for the Cycle of Life [MANUAL MERGE]2019-08-15T23:06:58Zrahixcard10@rahix.deChanges for the Cycle of Life [MANUAL MERGE]Finally ... This is quite a big changeset, so I tried to make sure to separate
the changes into individual commits. **Please don't squash!!**
Please don't merge before everyone had the chance to take a look; these changes
go quite ...Finally ... This is quite a big changeset, so I tried to make sure to separate
the changes into individual commits. **Please don't squash!!**
Please don't merge before everyone had the chance to take a look; these changes
go quite deep into a lot of parts of the firmware and I fear I might have
accidentally broken some things ...
**WARNING**: These changes break the API (hopefully for the last time ...)
---
Here's what's included:
### 6e2d34915c8ebd1be7845a1b57442ddf41c6da14 fix(l0dables): Fix vector table alignment
The vector table's alignment requirements depend on the number of interrupts
([Cortex-M4 VTOR](https://developer.arm.com/docs/dui0553/a/cortex-m4-peripherals/system-control-block/vector-table-offset-register)).
In our case, we have `0x6E`(=110) interrupts and thus an alignment requirement
of `0x80`(=128).
To satisfy this requirement, this commit moves the IVT to the beginning of
`.text` and enforces a 128 byte alignment. Please note that the headers which
come before `.text` will push the IVT to `0x100` instead of having it directly
in the beginning at `0x00`.
@q3k, remember when I told you? :P
### 6510d8dd4ffdf27ac9f046deaff680706ef4438d feat(epicardium): Add switch for core 1 debugging
You can enable core 1 debugging by bootstrapping with
```bash
./bootstrap.sh -Ddebug_core1=true
```
### 904851ab748bedbbaa86854d3441de330317eb15 fix(api): Fix API overlapping core 1 stack
Core 1 has its stack base at `0x20080000` which would overlap with the first
byte of the API parameter space. This patch moves the API further back to
prevent any weird behaviours being caused by this.
### 6cd4fcc36d9aecbcec1e002328db508928e7c383 feat(api): Add initial argument passing
This allows Pycardium to learn which script it should start once it
boots. Arguments can only be read before any API calls are made.
Afterward they are lost.
To ensure they won't collide with anything during a core 1 restart,
they are offset by `0x20` from the start of the API buffer.
### 78a7e827d6ac0fb7a6a1cdb6a2a7eb9888219c88 fix(api): Change interrupt idle value to ``-1``
Previously `0` was used but as `0` is also the ID of the reset interrupt,
this could lead to weird behaviors.
### 1b8b490bc2311ea7dab609b06f704af163eeb5d3 fix(api): Make reset interrupt non-maskable
### 98be0bcee0dab5ba9b4c4189615e78c35fc39fd9 feat(epicardium): Implement basic core 1 lifecycle
This commit introduces a way to control core 1. This is archieved by a
predefined API-Interrupt: The reset interrupt. When triggered, it will
bring the core back into its default state and wait for a new vector
address from Epicardium. Once this vector address is transferred, it
will start the new payload.
This method only works as long as core 1 is responsive to the API
interrupts. Cases where this might not be the case:
- During times where core 1 has interrupts disabled
- When in a higher priority exception handler
- When core 1 has corrupted its IVT
### bb54b68b6ea5fdb1820ac87ef0ef386098bb444c chore(epicardium): Move dispatcher into own module
Also add a mutex around API calls in preparation for future changes.
### 37daca63a65be158a0e28cef08acca90bdbd6d7b feat(epicardium): Add module for hardware init
Hardware initialization routines should not clutter main and instead belong
into the new `epicardium/modules/hardware.c`. Haven't moved anything yet,
though.
Also splits the init into two steps, `hardware_early_init()` which runs before
absolutely everything and `hardware_init()` for less critical stuff.
### c7be004eda2cb192562fd3844bd6a6877f8fbe2f feat(epicardium): Add core 1 lifecycle
This commit introduces a lifecycle for core 1. Based on the new loading
system, a few APIs are made available to control the payload running on
core 1. These are:
1. From core 1 (Pycardium, L0dable):
- `epic_exec(name)` API Call: Request loading of a new payload by
name. If the file does not exist, the call will return with an
error code. Otherwise, control will go to the new payload.
- `epic_exit(retcode)` API Call: Return from payload
unconditionally. This call should be called whenever a payload is
done or when it has hit an unrecoverable error. On `epic_exit`,
Epicardium will reset the core back into the menu.
2. From inside Epicardium:
- `epic_exec(name)`: This is **not** the same as the API call, as it
needs a different implementation underneath. It will load a new
payload and wait until this load actually completed (synchroneous).
- `return_to_menu()`: Return core 1 to the menu script no matter
what it is currently doing. This call is asynchroneous and will
return immediately after scheduling the lifecycle task. This task
will then take care of actually performing the load.
### 632f3652bf0091869bd1adab6c762c70c58c5fdc feat(pycardium): Add a barebones "os" module
Provides `os.exit(ret)` and `os.exec("file.py")`.
### d5da536f0d8f4a6a187188b37471883b6cb8f7f8 feat(pycardium): Return on HardFault
When Pycardium encounters a HardFault, it will now return to the menu.
### b1371bb67b20049ac98a76464c5a74a991fa6288 feat(pmic): Implement proper reset behavior
Pressing the power button will now excert the following behavior:
- `<400 ms`: Return back to menu
- `<1 s`: Reset card10
- `>1 s`: Poweroff
cc @schneider, @q3k, @swym