This sets CONFIG_KERNEL_VM_SIZE to define the size of virtual
memory region which can be used by the TLB driver. The size is
derived from the actual SOF code where they say the TLB register
space is of size 0x1000. There are 2048 TLB entries (for 2 bytes
per entry), which translates to 8MB of virtual memory space with
4KB pages.
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This configures soc and flash size definition
using DTSI information instead of hardcoded
values.
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
The newer sys_winstream utility is considerably simpler and much
faster for the reader. Use that instead.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
It's not uncommon to have Zephyr running in environments where it
shares a memory bus with a foreign/non-Zephyr system (both the older
Intel Quark and cAVS audio DSP systems share this property). In those
circumstances, it would be nice to have a utility that allows an
arbitrary-sized chunk of that memory to be used as a unidirectional
buffered byte stream without requiring complicated driver support.
sys_winstream is one such abstraction.
This code is lockless, it makes no synchronization demands of the OS
or hardware beyond memory ordering[1]. It implements a simple
file/socket-style read/write API. It produces small code and is high
performance (e.g. a read or write on Xtensa is about 60 cycles plus
one per byte copied). It's bidirectional, with no internal Zephyr
dependencies (allowing it to be easily ported to the foreign system).
And it's quite a bit simpler (especially for the reader) than the
older cAVS trace protocol it's designed to replace.
[1] Which means that right now it won't work reliably on arm64 until
we add a memory barrier framework to Zephyr! See notes in the code;
the locations for the barriers are present, but there's no utility to
call.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
There is no need to call soc_mp_init() if CONFIG_MP_NUM_CPUS
indicates only 1 CPU is being used. This also fixes an undefined
reference to soc_mp_init() since mp_cavs.c is not compiled
unless the build is targeting more than 1 CPU.
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This is trick (mapping RAM twice so you can use alternate Region
Protection Option addresses to control cacheability) is something any
Xtensa hardware designer might productively choose to do. And as it
works really well, we should encourage that by making this a generic
architecture feature for Zephyr.
Now everything works by setting two kconfig values at the soc level
defining the cached and uncached regions. As long as these are
correct, you can then use the new arch_xtensa_un/cached_ptr() APIs to
convert between them and a ARCH_XTENSA_SET_RPO_TLB() macro that
provides much smaller initialization code (in C!) than the HAL
assembly macros. The conversion routines have been generalized to
support conversion between any two regions.
Note that full KERNEL_COHERENCE still requires support from the
platform linker script, that can't be made generic given the way
Zephyr does linkage.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Continue the previous work, moving the cAVS hardware dependencies into
a separate file, leaving soc_mp.c with only OS-generic details to
track.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Clean up soc_mp.c a bit. Put all cAVS register use in functions
dedicated to hardware details (e.g. "soc_start_core()"), leave the
Zephyr OS tracking (e.g. the CPU start record, the active cores array,
etc...) in generic code.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
So far board name was used as IDF target. This worked, as the only board
in tree that is based on 'esp32' SoC is actually 'esp32'.
Use CONFIG_SOC instead of CONFIG_BOARD, so that new boards based on
'esp32' SoC can be successfully introduced both downstream or upstream.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
This got broken during the cpu_init unification pass. I appear to
have copied that zero out of code that initialized Zephyr on a
uniprocessor config somewhere. But what it means is that any use of
the S32C1I instruction to store to any memory type will trap an
exception! And even when CONFIG_MP_NUM_CPUS==1, we will emit code to
do that in the atomics layer when SMP=y.
That configuration ("SMP" with 1 cpu) is actually exercised by some
tests, including important ones like timer_api. These got broken.
Fix.
Really it's never correct to have anything but 1:1:1 ("external RCW
transaction") on these CPUs. All Intel cAVS processors have hardware
atomics support. We owe it to all the code we'll run to make sure it
works as documented and doesn't explode.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
When running under a simulator, it's difficult to extract output from
the window (it's difficult with hardware too!). Add "SIMCALL" output
to stderr (it's literally just 3 extra instructions) as an optional
feature so this subsystem itself can be debugged without herculean
effort.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Reword the symbols to make it clear what they mean ("INIT_LPSRAM"
instead of "RESET_MHE_AT_BOOT") and use them correctly instead of
SOC_SERIES_* kconfigs.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
We don't define a MemoryException handler, nor is one appropriate for
this hardware as it stands. And the empty section keeps causing
linker warnings we have to work around. Remove.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Single-core instantiations of this hardware and single-core builds of
firmware still exist, so we should support that without needless
bloat.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The MP startup code had a hardcoded INTLEVEL field of 5 in the initial
value of PS. That's needless, INTLEVEL is a full 4 bit field even if
the number of hardware interrupt levels is lower (and in fact 0xf is
the documented hardware reset state). Set that instead, so that this
code will work with any XEA2 hardware. This also matches the similar
code path in boot startup.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Most of soc.c is actually interrupt handling glue for the intc_cavs
driver. Give it its own file so that SOC initialization and bringup
can live separately.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
XCHAL_HAVE_ICACHE_DYN_ENABLE is not set for any Intel cAVS
hardware, so MEMCTL configuration is not done properly leaving
icache disabled. This can be seen as ~10X slowness when running
code on non-primary cores. Fix the issue by using XCHAL_USE_MEMCTL
to check for MEMCTL usage.
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Copy/paste/diverge struck again; I should have known better.
Fixes very recent and incomplete commit 9a1c5ec78e ("soc/intel_adsp:
cavs-link.ld: add *(.trace_ctx) sections"), see that commit for details.
Part of the fix for thesofproject/sof/issues/5032
This commit does not change `soc/xtensa/sample_controller/linker.ld`
Signed-off-by: Marc Herbert <marc.herbert@intel.com>
Select configuration when mcuboot is enabled.
At this moment, only UNSIGNED image is supported as per
Espressif's mcuboot porting.
This also updates esp32 runner to use proper bin_file name
and updates default bootloader check.
Move CMakeLists.txt content from board to soc directory
as this support is for esp32 architecture and not board
specific.
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
Booting ESP32 without 2nd stage bootloader is not supported.
Hence, ifdefs in startup code are removed
Signed-off-by: Shubham Kulkarni <shubham.kulkarni@espressif.com>
By enabling SMP option plus the APPCPU, also
completes the SMP port by adding the esp32
specific arch_sched_ipi() function
Signed-off-by: Felipe Neves <felipe.neves@espressif.com>
The CAVS linker scripts in Zephyr and "plain" (XTOS) SOF seem to share
the same origin and they mostly duplicate each other so they naturally
keep diverging from each other. This commit catches up with the SOF
commit ef43899c580f (thesofproject/sof/pull/2996) which added
the *(.trace_ctx) sections as part of the runtime log filtering
implementation (feature request thesofproject/sof/issues/2172)
Paraphrasing that commit, the goal is to create at link time a C-like
array by regrouping scattered trace contexts so they can be iterated on.
Together with some other changes in SOF, these 3 additional lines are
enough change in Zephyr to fix SOF bug thesofproject/sof/issues/5032
Signed-off-by: Marc Herbert <marc.herbert@intel.com>
The fix for xcc build failures yesterday forgot to preserve the
squashing of stderr from the objcopy steps. As mentioned in the
comments, there are deliberate empty sections in this link that
binutils warns about, but which are actually required, Cadence has
some vector sections in their standard exception table that don't get
populated and rimage has non-code sections that may be left empty for
non-audio-driver applications like tests.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Recent linker changes got ahead of the toolchain and started using
features not available in the binutils 2.23-based Xtensa toolchain.
Specifically:
+ The section arguments to objcopy don't accept wildcards.
+ It's not legal to have an ALLOC section emitted to a region outside
a declared MEMORY space. So various non-mapped sections populated
by C structs have to be put somewhere with an explicit address.
+ The older linker won't automatically create an empty section just
because you assigned to ".", so the Zephyr tests that lack a
.fw_metadata section get rejected by rimage. The fix here is a
little clumsy: copy the section out of zephyr.elf into a
(potentially-zero-length) temporary file, then add it back to
main.mod as a final step.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The module copy was clearing BSS sections from the module list, but we
already clear the full memory space immediately after SRAM power-up so
that's needless, just like the legacy reset vector bss clear that got
removed earlier. (Yes: that means that this code used to be writing
zeros to .bss three times!)
Similarly, put a symmetric clear on the LP-SRAM bank for safety (it's
not currently used by Zephyr but we do start it up). And move the
cache flush to the end of initialization immediately before OS
handoff.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Both soc.h and adsp/cache.h were very small headers, there's no good
reason to have a separate header just for two one-line inlines.
Merge.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This is some SOF code that got imported into Zephyr. But it's not a
Zephyr API and Zephyr doesn't use it. Unfortunately, the Zephyr
definition is now the one actually used at runtime in SOF, so we can't
remove it.
Put a guard around the definition so nothing else uses it until we get
it moved back home.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Dead code. Unused in Zephyr. Seems like SOF is picking this up from
its own headers via reading CONFIG_MP_NUM_CPUS correctly.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Syntax beautification and general simplification pass:
+ Remove some spurious padding around the _data_end symbol. That's a
Zephyr symbol and should reflect the actual end of the data section in
bytes.
+ Squash a warning that crept in where the linker doesn't like
changing cache mapping and padding at one time, clarify in docs.
+ Use the pre-existing-but-heretofore-unknown-to-me Zephyr
debug-sections.ld include file instead of putting all the DWARF
sections in by hand.
+ Move the .xt* sections to explicit zero addresses, since that's what
debug-sections.ld does for its output and if I don't they'll end up
with funny values.
+ Use Zephyr brace-on-same-line style consistently
+ Remove cargo-cult noop patterns like ALIGN(4) and ABSOLUTE(.) (none
of these sections get furthur relocated!)
+ Clean up the SEGSTART_* API so that it doesn't need to have
CONFIG_KERNEL_COHERENCE guards.
+ Remove a few unused/legacy symbol exports ("end", "__stack") so as
not to pollute the namespace.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This header is now included in only one place, and just contains a
handful of very-bootloader-specific platform tunables that will never
be exported elsewhere. Move that code into the C file. Longer term
we should configure the memory controllers with devicetree as much as
practical, but there's no reason to keep this header around.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Lots of changes to the linkage, none major:
+ Remove all the manually-defined ELF program headers. This was a big
pain to maintain, and I finally figured out why we were doing this:
it turns out to have been a workaround for the flags issue below.
+ Suppress the "empty loadable section" warnings at module generation.
This turns out to be an objcopy issue, when you drop all the
sections from an ELF program header.
+ Set section flags for NOLOAD sections manually. Rimage is very
strict about flags (even to the point of trying to suck in its own
metadata section as program text). This turns out to be really
fragile, as the linker automatically sets flags on the output
section based on the symbols placed in it. Rather than needing to
have one program header per section, or playing games in the
assembly for section definition to make this all match, just set the
flags expressly on the sections we know about on the objcopy command
line.
+ Similarly drop the special memory regions with explicit faked
"physical" addresses that were being used for non-loadable sections
(e.g. .fw_metadata, .static_log_entries). Just link them all after
the rest of the image like other platforms do.
+ Clean up multiple levels of macro indirection for the manifest base
address, which is ultimately coming from kconfig. Now the magic
numbers don't seem so magic.
+ Remove legacy symbol exports for "cacheattr" that we don't use
anymore.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
There was a ". = ALIGN(4096);" sitting at the end of the .text section
in the linker. This had the effect of needlessly padding the size of
the segment as packed into and copied out of the firmware DMA image.
There's no value to storing unused bytes in the image. It also makes
analysis easier for changes the modify code size. The following
.rodata section was already being 4k aligned anyway.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The bootloader had always been doing setup for window 0 (the firmware
status word reported to the loader). This then got needlessly
repeated in the main OS startup. Drop that, and move window 3 setup
(the trace/printk output buffer) there too for symmetry.
This means that the clear and cache flush of the buffer can be handled
in only one place too, for some runtime win (before it was being
cleared/flushed once at SRAM initialization time and then again at
window setup).
And as that was the only task remaining in the "adsp.c" file, we can
just remove it entirely.
One nice side effect is that this pushes up the point where we can get
a successful printk() out all the way back into the later stages of
the bootloader.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Now that we have access to IMR memory for non-bootloader tasks, let's
pick the low hanging fruit. SOC code that is only used at
initialization time (or things like core halt/restart which happen
only in non-realtime contexts) are now flagged __imr.
This is good for 808 bytes of code moved out of the main Zephyr image
on cavs_v25.
In the medium term, it would be good to define a system define for
this purpose (a-la Linux __init/__initdata) and start moving core
Zephyr init code too.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The Zephyr symbols are now part of the same link as the bootloader, so
no need to have an assembly entry stub or fixed address at all. Just
call z_cstart() as a normally-relocated function. Interestingly
Zephyr never put a declaration for it in public headers, because this
appears to be the first platform calling it from C.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Now that the IMR boot code is built as part of the main Zephyr
executable, remove the old stuff and its directory. The C file
becomes "boot.c" in the common directory and the two
bootloader-specific headers move into common/include.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The presence of a separate build for the bootloader code has always
been a wart with this platform. Sharing of code between the two has
required great care. We've had bugs with mismatched include paths,
macro definitions and compiler flags, etc... And of course it's not
possible for one to see the other; in theory we'd like the ability to
call back into IMR code after startup, to use the space for temporary
storage, etc...
So let's finally do it. This really isn't that complicated when you
see it in isolation:
+ Move the module manifest metadata into an "rimage_modules.c", and
put them in their own NOLOAD section where we can grab them later
with objcopy.
+ Make a new "imr" memory region in the main linker and just paste the
bootloader linkage (which is now using its own specific sections) in
there.
+ After zephyr.elf is built and cache-remapped, we can extract the imr
sections and the appropriate manifest for the bootloader rimage
module, and then do the converse by excluding them for the main
image module.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Define an __imr attribute macro that allows the bootloader to
expressly specify symbosls to go into IMR memory, use it pervasively
in the bootloader code, and remove the traditional section names from
boot_ldr.x.
This doesn't do anything by itself, but it is a necessary step for
getting the bootloader and Zephyr code to live together in the same
link.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Startup on these devices was sort of a mess, with multiple variants of
Xtensa and platform initialization code from multiple ancestries being
invoked at different places for different purposes. Just use one code
path for everyone.
Bootloader entry starts with a minimal assembly stub that simply sets
WINDOW{START,BASE}, PS and a stack pointer and then jumps to C code.
That then uses the cpu_early_init() implementation from cAVS 2.5's
secondary cores to finish Xtensa initialization, and then flows
directly into the pre-existing bootloader C code to initialize cache
and memory and copy the HP-SRAM image, then it invokes Zephyr via a
simple C function call to z_cstart().
Likewise, remove the "reset vector" from Zephyr. This was never a
reset vector, reset on these devices goes to a fixed address in a ROM.
CPU initialization is handled explicitly and completely in the
bootloader now, in a way that can be unified between the main and
secondary cores. Entry from the bootloader now goes directly into
z_cstart() via a C call (via a single jump instruction placed at the
entry point address -- that's going away soon too once we're using a
unified link).
Now that vector table initialization happens in a uniform way, there's
no need to copy the VECBASE value during arch_start_cpu().
Finally note that this also reverts the
CONFIG_RESET_VECTOR_IN_BOOTLOADER kconfig variable added for these
platforms, because it's no longer a tunable and true always.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Remove an unused strcmp() implementation. Flatten the call tree for
HP-SRAM initialization for clarity. Better isolate the platform
dependencies so e.g. hp_sram_pm_banks() becomes a clean noop on 1.5.
Also removes some dead/vestigial "error" handling, which wasn't being
propagated anywhere. Note that error detection and handling is a bad
idea, but this is VERY early code. We don't have even a theoretical
way of getting information back to the host until after SRAM is
initialized and window zero is set up. (And even then there's no
protocol available other than signaling "FW_ENTERED" or... not).
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Our "TLB"[1] initialization on secondary cores for cAVS 2.5 was
forgetting to initialize instruction caching, leading to a performance
regression. Clean this up and augment so that it matches the (larger,
non-C-callable) HAL implementation.
This will also allow us to use the same code on the main core in
upcoming changes.
[1] It's not a TLB, it just uses the TLB management instructions
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This seems to be a mistake in rimage: it wants the text and data
segments of the output module to be page-aligned, but it assumes
.rodata is part of "data" and not "text". So this reorders the
segments to make that happen.
Note that the page alignment is entirely artificial. Nothing is
interpreting the segment boundaries rimage is enforcing except for the
code in the bootloader itself, which doesn't care.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>