There are at least two types in the ADT related to USB,
but there's a decent chance that there are even more
required for other devices:
* A simple tunable that applies to a whole device node
and all its MMIO ranges specified in the "reg" property.
This one seems to just be mask32.
* A slightly more complex tunable that applies to a single
MMIO range specified in the "reg" property. So far I've
only seen 32 bit masks but the format looks like it should
also support 8,16 and 64 bit masks.
Signed-off-by: Sven Peter <sven@svenpeter.dev>
Turns out we had a bunch of silly dependencies on libc headers that are
not included with freestanding compilers. Fix all this and change the
CFLAGS to exclude libc headers and only include the built-in compiler
path.
Add our own versions of assert.h, errno.h, limits.h, and move malloc.h
and string.h together into a new path used as -isystem, so these headers
can be included using #include <>.
Remove a bunch of other dependencies in third-party code.
Add a strnlen function.
Disable building the libfdt overlay code for now, as it needs a strtoul
implementation. We can throw that in if/when we decide to use overlays.
Signed-off-by: Hector Martin <marcan@marcan.st>
This works by clearing HCR_EL2.TGE, and then doing essentially the same
thunk/return dance as for EL0 calls. However, since most EL1 exceptions
are not routed to EL2, we install hypercall vectors in EL1 to forward
them to EL2, and then short circuit the exception return to whatever
triggered the original exception.
Signed-off-by: Hector Martin <marcan@marcan.st>
Since we're in VHE mode, we can pretend to be in EL1 - but this will
allow us to really run in EL1 if we want to in the future.
Signed-off-by: Hector Martin <marcan@marcan.st>
This lets us test register access and other features from EL0.
No serious attempt at security is made, but at least EL0 runs off of a
separate stack and can return to EL2 at any time with `brk`; we can
easily implement a guard mode to break straight to EL2 on exception
later if needed.
Signed-off-by: Hector Martin <marcan@marcan.st>
Enable EL0 access to MMIO/etc, but not main RAM, because AArch64
architecturally enforces EL0w ^ EL2x.
Instead, create an alias of main RAM to grant EL0 full permissions,
at 0x80_0000_0000.
Grant EL0 full access to MMIO stuff, since EL2 will never execute
from there.
Signed-off-by: Hector Martin <marcan@marcan.st>
Previously all MMIO was mapped twice with different attributes
which may or may not lead to strange behaviour when the same
physical range is accessed from both mappings.
We now have a better idea which ranges require nGnRE and nGnRnE
and can just do it correctly instead.
Signed-off-by: Sven Peter <sven@svenpeter.dev>
These functions all perform a store direcly followed by a load.
This is useful to e.g. useful to find busy bits which might
already be cleared a few cycles after a write.
Signed-off-by: Sven Peter <sven@svenpeter.dev>
I can't remember why I used vmalls12e1is but this leads to
the following bug:
1. Load m1n1 with normal MMU setup
2. Disable all mappings, recompile and chainload to that m1n1
3. Everything will work fine for a while even though it should explode
when enabling the MMU.
This happens becuse there are still stale TLB entries in some cache.
Signed-off-by: Sven Peter <sven@svenpeter.dev>
This can be used when the input file size is unknown: the decompression
functions will keep track of it and return it to the caller instead.
Signed-off-by: Hector Martin <marcan@marcan.st>
Seems one of the registers is some kind of system-level CPU spinup flag,
without which the CPU runs but the rest of the system thinks it's still
dead.
Signed-off-by: Hector Martin <marcan@marcan.st>
This fixes the random SErrors after returning from a page fault. Turns
out the M1 was randomly deciding to speculate an instruction fetch from
address 0, triggering a fabric error.
Quoting the ARM ARM:
"Hardware does not prevent speculative instruction fetches from a memory
location with any of the Device memory attributes unless the memory
location is also marked as Execute-never for all Exception levels.
This means that to prevent speculative instruction fetches from memory
locations with Device memory attributes, any location that is assigned
any Device memory type must also be marked as execute-never for all
Exception levels. Failure to mark a memory location with any Device
memory attribute as execute-never for all Exception levels is a
programming error."
Signed-off-by: Hector Martin <marcan@marcan.st>
iBoot does this for us, but this is for the benefit of chainload.py and
other dump loaders that may not.
Signed-off-by: Hector Martin <marcan@marcan.st>
heapblock is a simple `sbrk` style implementation, also useful as an
"endless" decompression buffer. dlmalloc is used on top as a malloc
implementation.
This also changes how the Python side manages its heap. We still use a
python-side malloc implementation (since this is faster), and we put the
Python heap at the m1n1 heap + 128MB, without allocating it.
Hopefully this should never step on anything m1n1 neads, and avoids
having to manage freeing across Python script calls.
Signed-off-by: Hector Martin <marcan@marcan.st>
I saw at least one SError crash on Linux after doing this, but can't
repro; unclear if related to the MMU changes or not...
Signed-off-by: Hector Martin <marcan@marcan.st>
We mostly use read32/write32 and friends to poke hardware registers,
which might have side effects on RAM, so just make everything a memory
clobber to avoid potential issues.
Signed-off-by: Hector Martin <marcan@marcan.st>
this is required to fix the following error when compiling with clang:
CC build/string.o
src/string.c:3:10: error: 'string.h' file not found with <angled> include; use "quotes" instead
^~~~~~~~~~
"string.h"
Signed-off-by: Sven Peter <sven@svenpeter.dev>