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>
There was some vestigial handling here for Sue Creek (which this code
has never supported, that's a different board in Zephyr) and some code
that apparently managed a bug workaround in the ancestral SOF code.
Neither was buildable. Remove.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Move the very-early core initialization hooks (which are a mix of
Xtensa architectural features and Intel-specific hardwareisms) into a
separate header so they can be shared between the bootloader, main
core, and MP cores.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Adds Xtensa as supported architecture for coredump. Fixes
a few typos in documentation, Kconfig and a C file. Dumps
minimal set of registers shown by 'info registers' in GDB
for the sample_controller and ESP32 SOCs. Updates tests.
Signed-off-by: Lauren Murphy <lauren.murphy@intel.com>
This reverts commit af79664da3.
The patch caused regression on TGL-H systems where only 2 DSP
cores are available. The Kconfig override used by existing SOF
application does not work with Zephyr. A quick fix using
Zephyr board revisions was considered, but review feedback
was that core count difference should be reflected in SoC-level
device tree. This will take more time to develop, so the revert
is needed to fix the immediate regression.
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
There is some legacy code that tries to mask IDC interrupts when
starting up cores. This is there because the IDC interrupt is both
the system IPI when Zephyr is running (and can thus be signaled
asynchronously to the code calling arch_start_cpu()) and the messaging
protocol to the boot ROM on the other CPU. So the idea is that we
mask interrupts after startup so nothing is confused.
But that's needless in the current architecture. We maintain a
synchronized cpus_active[] record that will show true/active for any
CPU between the end of its SMP startup sequence and the beginning of
the shutdown process in soc_halt_cpu(), and false at all other times.
An IPI will never be sent to a CPU that is running in the boot ROM,
because such a CPU will be flagged as inactive. Likewise a ROM
startup IDC will never be sent to a CPU running Zephyr code for the
converse reason. Remove all that code.
Unfortunately SOF itself still needs an interrupt unmask step at CPU
startup, because it's still doing its own masking (probably according
to the same algorithm that we imported). Leave that in place as a
minimal workaround until we get that fixed upstream.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Investigation by Kai Vehmanen has shown that there is a very short
delay needed before starting the secondary core on cAVS 1.5 hardware.
What we finally realized is happening is that on these devices,
secondary core power is managed by the host. The cavs-fw.py test
integration powers the second core on at system startup and lets
Zephyr start it later, but SOF will power it up and send an IPC to the
firmware immediately.
There is a period after power-up but before the ROM is available
(unclear whether this is a race vs. hardware, the ROM firmware, or the
kernel driver, or potentially some combination); interrupts latched
earlier than that seem to be cleared by CPU initialization.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
These registers were defined in the new interface, but still being
used with bare bits (and in one spot a legacy field access macro).
Clean things up and use macros pervasively. To be fair: in this
particular case the field names aren't particularly descriptive...
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The usage of this interface is correct, but the docs in the header
spoonerized the source and destination of masking in the INTCTL
registers. Oops.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Put the initial stack in (slow) IMR memory instead of HP-SRAM. Very
little happens on this stack anyway before Zephyr switches off to the
interrupt stack and/or main thread. And this will allow us to start
running stackful C code much earlier in the boot process.
This puts the stack into the region of memory immediately below the
IMR image (because that edge of the image is easier to detect in
code). On all current platforms, that's offset quite a bit into IMR
space and leaves plenty of room. But we should have some kind
architectural way to reserve this space...
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The memory layout for the boot loader was needlessly complicated, with
separate fixed regions defined at fixed addresses, all in a file that
needs to be contiguous and DMA'd from the host in a single block. The
end result was a lot of magic numbers and wasted space.
Clean things up so that it links in a single region expressed (for the
benefit of rimage, I think) as a single program header in the ELF
file.
This is in preparation for further changes to unify the bootloader
stage with the main Zephyr image in a single link.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This board, whose hardware is just a cAVS 1.8 device without an x86
host CPU, started life (as all the cAVS devices did) as a
cut-and-pasted copy of the same basic code.
Because of hardware and schedule limitations, it didn't get the same
unification treatment that all the other platforms did. But it turns
out that in SMP configurations (which... it's not clear if we actually
test on hardware?) it wants to use the cavs_timer driver, which now
uses the new SOC API and not the old one. Which s1000 doesn't expose.
So... I guess we have to continue to cut and paste until we can find
time to unify this. Add a copy of the new shim/IDC headers to this
SOC and expose them via devivcetree.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
data cache mode setup and enabling should be done only when
CONFIG_ESP_SPIRAM is enabled. Otherwise, memory layout will
conflict with defaults.
Signed-off-by: Glauber Maroto Ferreira <glauber.ferreira@espressif.com>
The default config for cavs25 should be a 4 core config. Variants that
have less cores, need to override the config option to a smaller value.
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
This adds the SoC specific bits to enable GDB stub,
mainly the description for the register file, and
memory regions.
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
The IDC driver was written for Tiger Lake era devices, but works fine
on the earlier hardware too. Make it selectable; if you don't
configure IPM_CAVS_IDC, then you get the new driver.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
There was an attempt in the old code to express this as a formal
protocol with a proper field definitions, etc... But in fact no such
protocol really exists. This scheme is only used in one place to send
one specific message to code fixed in ROM on legacy devices that only
knows how to recognize this specific value. And 2.5 and later
hardware are moving away from it anyway.
Just express it directly, and explain in comments.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The CAVS_IDC_IPM driver happens to be used only on non-2.5 hardware,
but it's best to be clear in the conditional compilation when we're
talking about hardware-dependencies and when we mean software
configuration. This was mixed up in a few spots.
Also fix a warning that creeps in on non-default drivers choices about
an undeclared ipm function.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
While the linker scripts for these platforms had diverged in form, the
behavior remained compatible. Link all cAVS devices with the same
linker script included from the common directory (it's a verbatim copy
of the cavs_v25 script).
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
While technically this file can change for any instantiation of Xtensa
hardware, in practice all these devices have identical interrupts
setups. These files were duplicates, so there's no value in keeping
them in per-sub-soc directories. (Really we should wire it up so that
the generator gets run automatically with the build, but that will
need to wait for a rework of interrupt entry).
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
All the in-use contents of these files have now been moved to the
intel_adsp core, and they are configured via devicetree and kconfig.
Remove the legacy headers.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
These two register blocks are defined in the platform layers, but
never change (except on 1.5 where they don't exist). I don't want to
write a full devicetree interface for them as I can't find good docs
currently. They are used only at system initialization, so move the
definitions to the single file where they're used. In the longer term
we will want to move at least the GPDMA setup into a driver anyway.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
These registers were hardwired in the platform layer. Move to
devicetree, via a struct interface that looks like the pre-existing
shim layer.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
These values (used to arrange the bootloader within IMR memory) are
mostly computed or fixed to values that don't chagne between
platforms. Only the manifest address and the location of the data
section change. Put those in kconfig, move the rest to the global
header.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The bootloader code on this SOC has its own cmake rules, which means
it doesn't get the Zephyr-specific magic from the toolchain layer and
the code needs to handle fixups manually. (Specifically: we have a
xcc_missing_defs.h header to provide gcc symbols that xcc doesn't
have, and assembly needs to be built with _ASMLANGUAGE so headers
don't include C syntax.)
Long term the right solution here is to build the bootloader as part
of the Zephyr binary.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The locations of the memory windows within the reserved SRAM region
was being construted via a bunch of magic numbers referencing
(potentially historical?) SOF usage of those areas. But Zephyr only
ever touches two of these windows, and only cares about the sizes and
offsets. The complexity was hurting and not helping (especially since
there was no attempt made to unify these values with the ones that are
actually live in the SOF tree).
Replace with kconfig variables that simply specify the offset. Only
one platform has a nonstandard layout anyway. That allows SOF to move
things around in a clean way if it wants. Ideally we should be
presenting a proper API for managing this region, though.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Same as for the HP-SRAM memory region. It's already exposed in
devicetree, so take the per-platform values out (including some dead
code on 2.5) and put them in a global header.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The platform layer (except cAVS 1.5, which computed it via alternate
means as an offset on other stuff) was specifying the entry point as
an explicit address needlessly. In fact the linker scripts already
are written to place the entry point at the first address of linkable
RAM, which is already available as the RAM_BASE symbol.
Unify.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
These registers are identical on all platforms, the only difference
being that cAVS 1.5 places them at a different address.
Create a devicetree node to track the register block, and replace the
platform header code with a global API defined once (it works like the
pre-existing shim struct).
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
There is a diverged definition for SRAM_REG_FW_END, which exists to
prevent the Zephyr window initialization from changing values that
were already set by the ROM or bootloader (though this is incomplete,
as we're not ensuring the memory is actually the same space except by
convention; we also don't have any Zephyr-side visibility as to the
content of this struct).
That was silly; the only thing worse than one magic number is four
magic numbers in different files. Write a formula that works for all
the platforms and put it in the C file where it's used.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
There was a divergent set of definitions for a "RAM" region for the
benefit of memory layout in the platform headers. In fact there was
only one platform dependence (cAVS 1.5 has 32k instead of 64k
reserved). Put that into kconfig in a single place, and add a warning
that this is a trap region with hidden dependencies in both Zephyr and
SOF. Good enough until we clean this up and make everything visible
to the linker.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
There are multiple "fake" (not part of image) sections needless linked
to explicit addresses right now. This should be cleaned up, but in
the meantime let's at least put their definitions all in one place so
they aren't cut/pasted into every platform.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>